⽬录
拦截器获取request的值之后,Controller拿不到值
原因
解决⽅法
使⽤拦截器获取Controller⽅法名和注解信息⽅法⼀:通过request获得⽤户的URL⽅法⼆:通过⽤户要访问的⽅法来判断是否有权限⽅法三:⾃定义注解拦截器获取request的值之后,Controller拿不到值
原因
在Spring中request的值只能被获取⼀次,拦截器获取之后就会导致Controller拿不到值
解决⽅法
将request的值进⾏备份,请求到达Controller的时候就会拿到这个值
创建⼀个⾃⼰的HttpServletRequestWrapper并继承servlet的HttpServletRequestWrapper,为了备份request中的值。
public class MyHttpServletRequestWrapper extends HttpServletRequestWrapper { private final byte[] buff;
public MyHttpServletRequestWrapper(HttpServletRequest request) throws IOException { super(request);
InputStream is = request.getInputStream();
ByteArrayOutputStream baos = new ByteArrayOutputStream(); byte[] b = new byte[1024]; int len;
while ((len = is.read(b)) != -1) { baos.write(b, 0, len); }
buff = baos.toByteArray(); }
@Override
public ServletInputStream getInputStream() throws IOException {
final ByteArrayInputStream bais = new ByteArrayInputStream(buff); return new ServletInputStream() { @Override
public int read() throws IOException { return bais.read(); } }; }
@Override
public BufferedReader getReader() throws IOException {
return new BufferedReader(new InputStreamReader(getInputStream())); }}
创建⼀个Filter,将该过滤器配置在项⽬中,为了调⽤备份的HttpServletRequestWrapper
public class MyRequestBodyFilter implements Filter { @Override
public void init(FilterConfig filterConfig) throws ServletException { }
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest; servletRequest = new MyHttpServletRequestWrapper(httpServletRequest); filterChain.doFilter(servletRequest, servletResponse); }
@Override
public void destroy() { }}
创建⼀个⼯具类,在拦截器中获取request的值
public class RequestUtils {
public static String getRequestValue(HttpServletRequest request) throws IOException { StringBuffer sb = new StringBuffer();
MyHttpServletRequestWrapper myHttpServletRequestWrapper = new MyHttpServletRequestWrapper(request); InputStream is = myHttpServletRequestWrapper.getInputStream(); BufferedReader br = new BufferedReader(new InputStreamReader(is)); String str;
while ((str = br.readLine()) != null) { sb.append(str); }
return sb.toString(); } }
使⽤拦截器获取Controller⽅法名和注解信息
在使⽤SpringMVC进⾏项⽬的时候⽤到了权限验证。表分为:
⽤户表⾓⾊表资源表
⽤户-⾓⾊-资源都是多对多的关系,验证⽆⾮就是收到请求后,在拦截器循环判断⽤户是否有权限执⾏操作。
⽅法⼀:通过request获得⽤户的URL
再逐⼀循环判断是否可以操作只是这种⽅法很让⼈难受。
⽅法⼆:通过⽤户要访问的⽅法来判断是否有权限
preHandle⽅法中handler实际为HandlerMethod,(看⽹上说的有时候不是HandlerMethod),加个instanceof验证吧
可以得到⽅法名:h.getMethod().getName()
可以得到RequestMapping注解中的值:h.getMethodAnnotation(RequestMapping.class)这种⽅法还是不太⽅便
⽅法三:⾃定义注解
⾃定义注解代码:
@Retention(RUNTIME)@Target(METHOD)
public @interface MyOperation {
String value() default \"\";//默认为空,因为名字是value,实际操作中可以不写\"value=\"}
Controller代码:
@Controller(\"testController\")public class TestController {
@MyOperation(\"⽤户修改\")//主要看这⾥ @RequestMapping(\"test\") @ResponseBody
public String test(String id) { return \"Hello,2018!\"+id; }}
拦截器的代码:
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println(\"进⼊拦截器\");
if(handler instanceof HandlerMethod) {
HandlerMethod h = (HandlerMethod)handler;
System.out.println(\"⽤户想执⾏的操作是:\"+h.getMethodAnnotation(MyOperation.class).value()); //判断后执⾏操作... }
return HandlerInterceptor.super.preHandle(request, response, handler);}
补充
在每个⽅法上⾯加注解太⿇烦啦,可以在类上加注解
@Retention(RUNTIME)@Target(TYPE)
public @interface MyOperation { String value() default \"\";}
//拦截器中这样获得
h.getMethod().getDeclaringClass().getAnnotation(MyOperation.class);
我可以获取requestMapping,不⽤创建⾃定义注解啊,值得注意的是,不要使⽤GetMapping等,要使⽤requestMapping。以上为个⼈经验,希望能给⼤家⼀个参考,也希望⼤家多多⽀持。
因篇幅问题不能全部显示,请点此查看更多更全内容