Atea - Hero's Grave

          面向對象,開源,框架,敏捷,云計算,NoSQL,商業智能,編程思想。

            BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理 ::
            40 隨筆 :: 0 文章 :: 28 評論 :: 0 Trackbacks
          Spring-MVC如何使用攔截器,官方文檔只給出了非注解風格的例子。那么基于注解風格如何使用攔截器呢?

          基于注解基本上有2個可使用的定義類,分別是DefaultAnnotationHandlerMapping和AnnotationMethodHandlerAdapter:
          <bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping"/>
          <bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter"/>

          1、DefaultAnnotationHandlerMapping
          DefaultAnnotationHandlerMapping本身支持自定義攔截器,只需按如下進行配置:
          1 <bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping">
          2     <property name="interceptors">
          3         <list>
          4                <bean class="packageName.XXXInterceptor" />
          5         </list>
          6     </property>
          7 </bean>

          Interceptor的定義為:
           1 public class XXXInterceptor extends HandlerInterceptorAdapter {
           2     @Override
           3     public boolean preHandle(HttpServletRequest req, HttpServletResponse resp, Object handler) {
           4  
           5         String className = handler.getClass().getName();// packageName.ClassName
           6         if (Error) {
           7             return false;
           8         }
           9         return true;
          10     }
          11 }

          2、AnnotationMethodHandlerAdapter
          目前,筆者沒找到如何給AnnotationMethodHandlerAdapter配置自定義Interceptor的方法,但是有個customArgumentResolver可以利用一下,來充當Interceptor。
          1 <bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
          2     <property name="customArgumentResolver">
          3         <bean class="packageName.XXXResolver"/>
          4     </property>
          5 </bean>

          Resolver的定義為:
           1 public class XXXResolver implements WebArgumentResolver {
           2  
           3     @Override
           4     public Object resolveArgument(MethodParameter methodParameter, NativeWebRequest webRequest) throws Exception {
           5  
           6         String className = methodParameter.getMethod().getDeclaringClass().getName();// packageName.ClassName
           7 
           8         // 如何取得Response和Request
           9         HttpServletResponse resp = (HttpServletResponse) webRequest.getNativeResponse();
          10        HttpServletRequest req = (HttpServletRequest) webRequest.getNativeRequest();
          11  
          12        if (Error) {
          13            if (!resp.isCommitted()) resp.sendError(ERROR_STATUS);
          14        }
          15        return UNRESOLVED;    
          16     }
          17 }
          18 

          仔細的人會看出,第二種方法其實根本不是攔截。其實第二種只是在映射Controller,調用方法的時候,給每一個方法的參數增加了一個切點。
          上例在出錯的時候往HttpServletResponse寫錯誤狀態,來通知web容器進行錯誤重定向,達到了攔截器的作用。
          這么做有一個缺點,就是每個參數都有自己的切點,比如方法有3個參數就會調3次resolveArgument。為了避免出錯,需要判斷一下resp.isCommitted

          customArgumentResolver的初衷不是用來做Interceptor的,但有些環境卻不得不使用它,比如部署在GAE上。
          GAE是不支持DefaultAnnotationHandlerMapping的,因為此類用到了org.springframework.beans.BeanUtils.findEditorByConvention,這個方法會調用java.lang.ClassLoader.getSystemClassLoader,而這正是GAE所不允許的。

          PS:
          文中提到軟件的版本:
          spring - 2.5.X
          google app engine - 1.2.5

          參考資料
          http://www.scottmurphy.info/spring_framework_annotation_based_controller_interceptors
          http://groups.google.com/group/google-appengine-java/browse_thread/thread/54aadf8164be7bf0
          posted on 2009-09-20 20:23 Atea 閱讀(7274) 評論(0)  編輯  收藏 所屬分類: SpringGAE
          主站蜘蛛池模板: 竹溪县| 石柱| 武宣县| 广德县| 巴彦县| 若羌县| 仁化县| 民丰县| 大余县| 泸定县| 阿拉尔市| 金华市| 池州市| 厦门市| 双鸭山市| 成武县| 龙江县| 临安市| 房产| 望都县| 通榆县| 易门县| 肥城市| 扶余县| 汉阴县| 开江县| 漠河县| 玛多县| 舒城县| 石林| 淮滨县| 龙胜| 原阳县| 泸水县| 巨鹿县| 新安县| 云安县| 米脂县| 灵台县| 西安市| 宁蒗|