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; }
SpringMVC攔截器和自定義註解