`
qqchinaok
  • 浏览: 214145 次
  • 性别: Icon_minigender_1
  • 来自: 武汉
社区版块
存档分类
最新评论

Spring MVC 数据绑定的扩展

阅读更多


Spring MVC 数据绑定的扩展

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;&#64;Target(ElementType.PARAMETER)&#64;Retention(RetentionPolicy.RUNTIME)&#64;Documentedpublic &#64;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(...);        };使用方式如下:    &#64;RequestMapping(value="/getContractList")    &#64;ResponseBodyExt(isCheck=true, resultType="sql", sqlColumns="ID,TUREID")     public Page<Contract> getContractList(&#64;RequestParamExt(value = "ds_search", type = "ds") Contract cp) throws Exception { Page<Contract> page = method1(); return page; }QQ:24889356

0
2
分享到:
评论

相关推荐

    spring mvc 3.2 参考文档

    Spring的数据绑定是高度灵活的: 例如,它把类型不匹配当做验证错误,这样就可以算作应用程序错误,而不是系统错误。因此你不需要简单的重复拷贝您的业务对象的属性,表单对象中的非类型化的字符串只是处理无效的...

    spring杂谈 作者zhang KaiTao

    1. spring杂谈[原创] 1.1 Spring事务处理时自我调用的解决方案及一些实现方式的风险 ...1.32 Spring3 Web MVC下的数据类型转换(第一篇)——《跟我学Spring3 Web MVC》抢先看 1.33 Spring 注入集合类型

    Spring MVC 员工管理系统

    和众多其它Web框架一样,它基于MVC设计理念,此外,由于它采用了松散耦合可插拔组件结构,具有比其它MVC框架更多的扩展性和灵活性。 Spring MVC框架围绕DispatcherServlet这个核心展开,DispatcherServlet的作用是...

    (第十一天)初识SpringMVC SSM框架的学习与应用-Java EE企业级应用开发学习记录

    请求处理流程: 我们将详细解释Spring MVC中的请求处理流程,包括请求映射、参数绑定、数据验证和响应生成。这有助于您理解整个请求生命周期。 配置与注解: 我们将演示如何配置Spring MVC,包括XML配置和注解驱动...

    Web框架编程-SpringMVC框架编程

    Spring MVC(Model-View-Controller)是一个基于Java的MVC...7. 数据绑定(Data Binding) 8. 校验器(Validator) 这些资源描述了Spring MVC框架中不同组件的职责和作用,协同工作以构建可靠和可扩展的Web应用程序。

    sample-springmvc-portlet:像附加组件一样打包的 Spring MVC Portlet 示例

    本示例中使用了以下功能: Spring MVC Portlet 动作和渲染映射依赖注入(使用@Inject) 表单绑定表单验证(Hibernate Validator)入门第 1 步:安装先决条件:安装(EXO_TOMCAT_ROOT_FOLDER 将用于指定 eXo Tomcat ...

    Spring.3.x企业应用开发实战(完整版).part2

    2.5.1 配置Spring MVC框架 2.5.2 处理登录请求 2.5.3 JSP视图页面 2.6 运行Web应用 2.7 小结 第2篇 IoC和AOP 第3章 IoC容器概述 3.1 IoC概述 3.1.1 通过实例理解IoC的概念 3.1.2 IoC的类型 3.1.3 通过容器完成依赖...

    Spring-Reference_zh_CN(Spring中文参考手册)

    2.5.1. Spring MVC的表单标签库 2.5.2. Spring MVC合理的默认值 2.5.3. Portlet 框架 2.6. 其他特性 2.6.1. 动态语言支持 2.6.2. JMX 2.6 .3. 任务规划 2.6.4. 对Java 5(Tiger)的支持 2.7. 移植到Spring 2.0 ...

    Spring 2.0 开发参考手册

    2.5.1. Spring MVC的表单标签库 2.5.2. Spring MVC合理的默认值 2.5.3. Portlet 框架 2.6. 其他特性 2.6.1. 动态语言支持 2.6.2. JMX 2.6.3. 任务规划 2.6.4. 对Java 5(Tiger)的支持 2.7. 移植到Spring ...

    Spring3.x企业应用开发实战(完整版) part1

    2.5.1 配置Spring MVC框架 2.5.2 处理登录请求 2.5.3 JSP视图页面 2.6 运行Web应用 2.7 小结 第2篇 IoC和AOP 第3章 IoC容器概述 3.1 IoC概述 3.1.1 通过实例理解IoC的概念 3.1.2 IoC的类型 3.1.3 通过容器完成依赖...

    spring security 参考手册中文版

    第七部分 Spring数据集成 273 38. Spring Data&Spring安全配置 273 39. @Query中的安全表达式 273 第八部分 附录 274 40.安全数据库模式 274 40.1用户模式 274 40.1.1集团当局 274 40.2持久登录(记得我)架构 275 ...

    Spring中文帮助文档

    2.5.1. Spring MVC合理的默认值 2.5.2. Portlet 框架 2.5.3. 基于Annotation的控制器 2.5.4. Spring MVC的表单标签库 2.5.5. 对Tiles 2 支持 2.5.6. 对JSF 1.2支持 2.5.7. JAX-WS支持 2.6. 其他 2.6.1. 动态...

    Spring API

    2.5.1. Spring MVC合理的默认值 2.5.2. Portlet 框架 2.5.3. 基于Annotation的控制器 2.5.4. Spring MVC的表单标签库 2.5.5. 对Tiles 2 支持 2.5.6. 对JSF 1.2支持 2.5.7. JAX-WS支持 2.6. 其他 2.6.1. 动态...

    spring chm文档

    5. 校验,数据绑定,BeanWrapper,与属性编辑器 5.1. 简介 5.2. 使用Spring的Validator接口进行校验 5.3. 从错误代码到错误信息 5.4. Bean处理和BeanWrapper 5.4.1. 设置和获取属性值以及嵌套属性 5.4.2. 内建...

    spring web flow demo

    最新的 Spring Web Flow 2.0 则明确声明是基于 Spring Web MVC 的一个扩展。 • 提供了处理 Ajax 事件的能力 Ajax 事件的处理与 Web Flow 事件的处理相一致,在处理完成后, flow 即可刷新客户端相关 界面代码。 • ...

    JavaSpring的商城项目前台+后台+api

    Spring框架的核心特性可以用于任何Java应用程序,但存在扩展,它们提供了对构建Web应用程序上下文的全面支持。Spring框架的主要目标是简化Java EE开发并促进良好编程实践,如依赖注入(Dependency Injection, DI)和...

    spring源代码解析

    Spring为web应用提供了上下文的扩展接口 WebApplicationContext: 如转载请注明,转载自:关注Java[http://www.gbsou.com] 本文链接: http://www.gbsou.com/2009/08/11/214.html - - Java代码 public ...

    springboot参考指南

    关闭Spring MVC DispatcherServlet vii. 65.7. 关闭默认的MVC配置 Spring Boot参考指南 7 viii. 65.8. 自定义ViewResolvers v. 66. 日志 i. 66.1. 配置Logback ii. 66.2. 配置Log4j i. 66.2.1. 使用YAML或JSON配置...

    基于SSM和VUE的公共资源模块的设计与开发(免费提供全套java开源项目源码+论文)

    本项目基于SSM(Spring、Spring MVC、MyBatis)和VUE技术栈,旨在构建一个高性能、易扩展的公共资源管理系统,满足多样化的业务需求。 项目目的 资源共享:建立统一的公共资源管理平台,实现资源的高效共享和利用。...

    基于SSM的王道考研购物网站.zip

    SpringMVC:一个基于Spring框架的Web MVC框架,用于构建RESTful Web服务。它提供了模型-视图-控制器(MVC)架构,支持RESTful风格的API设计。MyBatis:一个优秀的持久层框架,用于简化数据库操作。它将SQL映射到Java对象...

Global site tag (gtag.js) - Google Analytics