SpringMVC拦截器和自定义注解
一、拦截器
1、拦截所有URL
<mvc:interceptors>
<bean class="myInterceptor.MyInterceptor" />
</mvc:interceptors>
2、拦截匹配的URL
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/**" />
<mvc:exclude-mapping path="/main/login*" />
<bean class="myInterceptor.MyInterceptor" />
</mvc:interceptor>
</mvc:interceptors>
3、HandlerMapping上的拦截器
<bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping"> <property name="interceptors"> <list> <bean class="myInterceptor.MyInterceptor"/>
</list>
</property>
</bean>
注意:如果使用了<mvc:annotation-driven />, 它会自动注册DefaultAnnotationHandlerMapping 与AnnotationMethodHandlerAdapter 这两个bean,所以就没有机会再给它注入interceptors属性,就无法指定拦截器。当然我们可以通过人工配置上面的两个Bean,不使用 <mvc:annotation-driven />,就可以给interceptors属性注入拦截器了。
4、自定义拦截器
继承HandlerInterceptorAdapter类并重写其三个方法(preHandle,postHandle,afterCompletion),分别实现预处理、后处理(调用了Service并返回ModelAndView,但未进行页面渲染)、返回处理(已经渲染了页面)
在preHandle中,可以进行编码、安全控制等处理; 在postHandle中,有机会修改ModelAndView; 在afterCompletion中,可以根据Exception是否为null判断是否发生了异常,进行日志记录,参数中的Object handler是下一个拦截器。
最主要的方法是preHandle方法:
如果方法返回false,从当前拦截器往回执行所有拦截器的afterCompletion方法,再退回拦截器链
如果返回true 执行下一个拦截器,直到所有拦截器都执行完毕,再运行被拦截的Controller,然后进入拦截器链从最后一个拦截器往回运行所有拦截器的postHandle方法,接着依旧是从最后一个拦截器往回执行所有拦截器的afterCompletion方法
二、自定义注解
1、概念
2、获取类注解的实例
@Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) public @interface MyAnnotation { /** * 前台登陆value */ public static final String WEB = "WEB"; /** * 后台登陆value */ public static final String ADMIN = "ADMIN"; String value() default WEB; }
@Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { Boolean flag = false; request.getSession().setAttribute("user", "user"); Class<?> clazz = MyController.class; MyAnnotation myAnnotation = clazz.getAnnotation(MyAnnotation.class); if (myAnnotation != null) { String value = myAnnotation.value(); // 判断前台登陆 if (value.equals(MyAnnotation.WEB)) { Object object = request.getSession().getAttribute("user"); if (object == null) {// 没有登录 String basePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + request.getServletPath() + "/"; response.sendRedirect(basePath + "admin/login");// 跳转到登录页面 } else { flag = true;// 已经登录,设置为true不再拦截 } } } else { return false; } return flag; }
3、获取方法上的注解
@Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface MethodAnnotation { String username() default "admin"; String uservalue() default "user"; }
@Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { HandlerMethod handlerMethod = (HandlerMethod) handler; MethodAnnotation methodAnnotation = handlerMethod.getMethodAnnotation(MethodAnnotation.class); if (methodAnnotation!=null) { String name = methodAnnotation.username(); String value = methodAnnotation.uservalue(); if(name.equals("admin")&&value.equals("user")){ return true; } System.out.println("名字不对"); } return false; }