千家信息网

如何进行Spring MVC数据绑定的扩展

发表于:2025-02-23 作者:千家信息网编辑
千家信息网最后更新 2025年02月23日,这篇文章给大家介绍如何进行Spring MVC数据绑定的扩展,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。Spring MVC经过三个版本,功能已经改进和完善了很多。尤其是2.5
千家信息网最后更新 2025年02月23日如何进行Spring MVC数据绑定的扩展

这篇文章给大家介绍如何进行Spring MVC数据绑定的扩展,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。

Spring MVC经过三个版本,功能已经改进和完善了很多。尤其是2.5以来采用的Annotation的参数绑定,极大的方便了开发,3.0对其进行更进一步的完善。对于一些特殊的前台框架,传到后台的不是普通的request中的参数,而是request流中的xml格式,这时就不能采用SpringMVC自带的参数绑定方法。这时候考虑是否能扩展一下。

SpringMVC默认使用的是AnnotationMethodHandlerAdapter.java,可以修改这个类来实现扩展。关键位置在如下方法中:

otected 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配置:

     

到此就实现了自定义格式的数据绑定。

对于特定格式的输出,如果需要自定义的话,同样需要修改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 getContractList(@RequestParamExt(value = "ds_search", type = "ds") Contract cp) throws Exception { Page page = method1(); return page; }

关于如何进行Spring MVC数据绑定的扩展就分享到这里了,希望以上内容可以对大家有一定的帮助,可以学到更多知识。如果觉得文章不错,可以把它分享出去让更多的人看到。

方法 关键 位置 数据 参数 格式 内容 更多 帮助 不错 普通 特殊 更进一步 三个 两个 关键点 兴趣 前台 功能 同时 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 郑州民蕴网络技术有限公司 网络安全信息系统台账 国庆70周年网络安全保护 起源引擎游戏服务器管理平台 住建局网络安全年度工作计划 网络安全销售话术 什么用来比喻大数据库 105016数据库技术题库 护苗网络安全合集 阿里云服务器共享型和突发性能型 宜兴定制软件开发市场价格 云服务器可以放收款码吗 福州软件开发毕业生工资 陕西计算机网络技术的大专 网络安全都有哪些岗位 伊春市网络安全事件应急预案 网络技术平台是商标多少类 断掉某个数据库用户的连接 杨浦区专业软件开发不二之选 计算机专业网络安全方向 德化网络安全检查 怎么看到网站服务器端的代码 视频监控的硬件和软件开发 临沂公安局网络安全项目 沭阳多功能网络技术供应商家 中国数据库技术方向 退出pg数据库快捷方式 方舟服务器找不到了 数据库中如何设外键 黑龙江七色互联网络科技有限公司
0