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 閱讀(7271) 評論(0)  編輯  收藏 所屬分類: SpringGAE
          主站蜘蛛池模板: 佛学| 大同县| 碌曲县| 无为县| 廊坊市| 万安县| 望城县| 新兴县| 邵阳市| 托里县| 武山县| 灵丘县| 太白县| 华安县| 阿拉善右旗| 开江县| 双鸭山市| 虞城县| 龙江县| 新营市| 开阳县| 尚志市| 贵定县| 苍南县| 赤峰市| 玉田县| 星座| 丘北县| 霍山县| 合水县| 望都县| 巩义市| 合山市| 郁南县| 泾川县| 赞皇县| 射阳县| 商水县| 留坝县| 和平区| 志丹县|