1. 程式人生 > >SpringMVC攔截器和自定義註解

SpringMVC攔截器和自定義註解

tor spring system image ssi 定義 技術分享 style gets

一、攔截器

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