<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    菜園子

    BlogJava 首頁 新隨筆 聯系 聚合 管理
      7 Posts :: 1 Stories :: 31 Comments :: 0 Trackbacks


    Spring MVC經過三個版本,功能已經改進和完善了很多。尤其是2.5以來采用的Annotation的參數綁定,極大的方便了開發,3.0對其進行更進一步的完善。對于一些特殊的前臺框架,傳到后臺的不是普通的request中的參數,而是request流中的xml格式,這時就不能采用SpringMVC自帶的參數綁定方法。這時候考慮是否能擴展一下。

    SpringMVC默認使用的是AnnotationMethodHandlerAdapter.java,可以修改這個類來實現擴展。關鍵位置在如下方法中:

    protected ModelAndView invokeHandlerMethod(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

         ServletHandlerMethodResolver methodResolver= getMethodResolver(handler);

         Method handlerMethod = methodResolver.resolveHandlerMethod(request);

         ServletHandlerMethodInvoker methodInvoker=new ServletHandlerMethodInvoker(methodResolver);

         ServletWebRequest webRequest = new ServletWebRequest(request, response);

         ExtendedModelMap implicitModel = new BindingAwareModelMap();

         Object result=methodInvoker.invokeHandlerMethod(handlerMethod,handler,webRequest, implicitModel);

         ModelAndView mav=methodInvoker.getModelAndView(handlerMethod,handler.getClass(),result, implicitModel, webRequest);    methodInvoker.updateModelAttributes(handler,(mav!=null?mav.getModel():null),implicitModel,webRequest);

         return mav;

        }

    藍色位置是關鍵點,ServletHandlerMethodInvoker.java是內部類,繼承自HandlerMethodInvoker.java,invokeHandlerMethod方法需要擴展,繼續跟蹤這個方法,發現是HandlerMethodInvoker.java這個類的方法,這個方法中的關鍵方法是resolveHandlerArguments(),關鍵部分如下

    if (RequestParam.class.isInstance(paramAnn)) {

    RequestParam requestParam = (RequestParam) paramAnn;

    paramName = requestParam.value();

    required = requestParam.required();

    defaultValue = parseDefaultValueAttribute(requestParam.defaultValue());

    annotationsFound++;

    }

    else if (RequestHeader.class.isInstance(paramAnn)) {

    RequestHeader requestHeader = (RequestHeader) paramAnn;

    headerName = requestHeader.value();

    required = requestHeader.required();

    defaultValue = parseDefaultValueAttribute(requestHeader.defaultValue());

    annotationsFound++;

    }

    到此擴展的話需要添加自己的類型,如RequestParamExt,添加在后面,模仿如下:

    else if (RequestParamExt.class.isInstance(paramAnn)) {

    RequestParamExtrequestParam = (RequestParamExt) paramAnn;

    paramName = requestParam.value();

    defaultValue = parseDefaultValueAttribute(requestParam.defaultValue());

    miType = requestParam.type();

    annotationsFound++;

    }

    else if (paramName != null) {

    args[i] = resolveRequestParam(paramName, required, defaultValue, methodParam, webRequest, handler);

    }

    這個方法上面添加擴展邏輯:

    if(!RequestParamExt.TYPE_NONE.equals(miType)){

    if(null == platformRequest){

    HttpServletRequest request = webRequest.getNativeRequest(HttpServletRequest.class);

    platformRequest = new PlatformRequest((HttpServletRequest)request, "utf-8");

    platformRequest.receiveData();

    }

    if(RequestParamExt.TYPE_PLATFORMREQUEST.equals(miType)){

        args[i] = platformRequest;

    }

    else if(RequestParamExt.TYPE_STR.equals(miType)){

    args[i] = resolveRequestStrParamExt(platformRequest, methodParam);

    }else{

    args[i] = resolveRequestParamExt(miType,platformRequest,paramName, defaultValue, methodParam, webRequest, handler);

    }

    }

    兩個resolveRequest*Ext方法如下:

    protected Object resolveRequestStrParamExt(PlatformRequest platformRequest, MethodParameter methodParam){

    VariableList inVl = platformRequest.getVariableList();

    String paraName = methodParam.getParameterName();

    return inVl.getValueAsObject(paraName);

    }

    protected Object resolveRequestParamExt(String miType,PlatformRequest platformRequest, String paramName, 

    String defaultValue,MethodParameter methodParam,NativeWebRequest webRequest, Object handler)throws Exception{

    if(StringUtils.isBlank(paramName)){

    paramName = defaultValue;

    }

    Class<?> paramType = methodParam.getParameterType();

    DatasetList inDl = platformRequest.getDatasetList();

    VariableList inVl = platformRequest.getVariableList();

    if(RequestParamExt.TYPE_DS.equals(miType)){//綁定的關鍵過程

    Dataset ds = inDl.getDataset(paramName);

    Object vo = paramType.newInstance();

    MiPDataBinder dataBinder = new MiPDataBinder(vo, false);

        dataBinder.bind(inVl);

        return dataBinder.getTarget();

    }

    }

    同時還需要一個annotation的定義:示例如下:

    package com.company.springext.web.bind.annotation;

    import java.lang.annotation.Documented;

    import java.lang.annotation.ElementType;

    import java.lang.annotation.Retention;

    import java.lang.annotation.RetentionPolicy;

    import java.lang.annotation.Target;

    @Target(ElementType.PARAMETER)

    @Retention(RetentionPolicy.RUNTIME)

    @Documented

    public @interface RequestParamExt {

        public static final String TYPE_NONE            = "none";

        public static final String TYPE_DS              = "ds";

        public static final String TYPE_VL              = "vl";

        public static final String TYPE_STR             = "string";   

    String type() default TYPE_NONE

    String value() default "";    

    String defaultValue() default "ds";

    }

    最后是修改Spring配置:

    <bean class="com.company.springext.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapterExt">    

    </bean>  

    到此就實現了自定義格式的數據綁定。

    對于特定格式的輸出,如果需要自定義的話,同樣需要修改AnnotationMethodHandlerAdapterExt.java這個類,關鍵位置在getModelAndView()方法。在如下位置:

    } else if (AnnotationUtils.findAnnotation(handlerMethod, ResponseBody.class) != null) {

                handleResponseBody(returnValue, webRequest);

                return null;

            }

    添加自己的擴展方法:

    else if (AnnotationUtils.findAnnotation(handlerMethod, ResponseBodyExt.class) != null) {

                    ResponseBodyExt bodyMi = AnnotationUtils.findAnnotation(handlerMethod, ResponseBodyExt.class);

                    handleResponseBodyExt(returnValue, webRequest, bodyMi);

                    return null;

                }

    定義handleResponseBodyExt方法:

     private void handleResponseBodyExt(Object returnValue, ServletWebRequest webRequest, ResponseBodyMI bodyMi) throws Exception {

                HttpServletResponse servletResponse = (HttpServletResponse) webRequest.getNativeResponse();

                writeWithExtConverters(returnValue, servletResponse, bodyMi);

            }

    writeWithExtConverters()方法如下:

     private void writeWithExtConverters(Object returnValue, HttpServletResponse response, ResponseBodyMI bodyMi) throws Exception {            

         convertToXML(...);    

        };

    使用方式如下:

        @RequestMapping(value="/getContractList")

        @ResponseBodyExt(isCheck=true, resultType="sql", sqlColumns="ID,TUREID")

         public Page<Contract> getContractList(@RequestParamExt(value = "ds_search", type = "ds") Contract cp) throws Exception {

    Page<Contract> page = method1();

    return page;

    }



    QQ:24889356
    posted on 2011-09-12 19:12 GhostZhang 閱讀(4286) 評論(6)  編輯  收藏

    Feedback

    # re: Spring MVC 數據綁定的擴展 2011-09-12 20:45 @joe
    有什么用?  回復  更多評論
      

    # re: Spring MVC 數據綁定的擴展 2011-09-13 09:05 tb
    恩 不錯 挺有用的   回復  更多評論
      

    # re: Spring MVC 數據綁定的擴展[未登錄] 2011-09-13 11:13 junxy
    不知道樓主的使用場景是什么?能否介紹下,另外對于一般的格式轉換,他的轉換器就可以滿足需求了..呵呵  回復  更多評論
      

    # re: Spring MVC 數據綁定的擴展 2011-09-13 12:45 GhostZhang
    我們用的是一個特殊的前臺框架,參數是xml格式的,所有的參數都在一個xml中,同時xml是存在request.getInputStream()中,所以不用用原來的轉換器。
      回復  更多評論
      

    # re: Spring MVC 數據綁定的擴展[未登錄] 2011-09-13 20:00 junxy
    @GhostZhang
    為啥參數要用xml格式的呢?我也就是用webservice時遇到過 呵呵   回復  更多評論
      

    # re: Spring MVC 數據綁定的擴展 2011-09-13 21:35 GhostZhang
    因為前臺框架的限制。沒辦法。  回復  更多評論
      


    只有注冊用戶登錄后才能發表評論。


    網站導航:
     
    主站蜘蛛池模板: 亚洲成人免费网站| 永久免费A∨片在线观看| 亚洲免费中文字幕| 亚洲色偷偷av男人的天堂| 久久久久久AV无码免费网站下载| 亚洲中文字幕无码一久久区| 国产精品免费久久久久久久久| 亚洲AV无码乱码精品国产| 色哟哟国产精品免费观看| mm1313亚洲精品无码又大又粗| 人成免费在线视频| 色噜噜AV亚洲色一区二区| 嫩草在线视频www免费观看| 亚洲AV无码第一区二区三区| 蜜桃成人无码区免费视频网站| 亚洲欧洲第一a在线观看| 67194熟妇在线永久免费观看| 国产亚洲中文日本不卡二区| 女人18毛片a级毛片免费| 美女裸免费观看网站| 国产亚洲精品无码拍拍拍色欲 | 亚洲av午夜国产精品无码中文字 | 色窝窝免费一区二区三区| 亚洲久悠悠色悠在线播放| 日本无吗免费一二区| 中文字幕乱理片免费完整的| 亚洲v高清理论电影| 久久精品女人天堂AV免费观看| 国产成人亚洲综合无| 亚洲av无码一区二区三区不卡| 免费A级毛片无码无遮挡内射| 国产区图片区小说区亚洲区| 亚洲国产精品无码av| 毛片a级毛片免费播放下载| 黄色网址大全免费| 久久亚洲私人国产精品vA| 日韩免费一区二区三区| a毛片全部免费播放| 亚洲日韩看片无码电影| 亚洲乱码中文字幕久久孕妇黑人| 日韩免费精品视频|