1、请求数据在到达处理方法前这段时间。
spring MVC还会做请求信息转换、数据转换、数据格式化、数据校验。
2、数据转换
1》ConversionService:
Spring类型转换体系的核心接口,在其中定义了一下4个方法:
可以在spring上下文中注册一个ConversionServiceFactoryBean,用以定义一个ConversionService。spring上下文将识别出这个ConversionService,并在spring mvc处理方法的参数绑定中使用它进行数据转换。
在ConversionServiceFactoryBean中可以内置很多的类型转换器,使用它们可以完成大多数Java类型的转换工作。其除了包括将spring对象转换为各种基础类型的对象外,还包括String、Number、Array、Collection、Map、Properties及Object之间的转换器。可以通过ConversionServiceFactoryBean的converters属性注册自定义的类型转换器。
<bean id="conversionService"class="org.springframework.context.support.ConversionServiceFactoryBean"> <property name="converters"> <list> <bean class="com.lfy.converter.StringToDateConverter"/> </list> </property> </bean>
2》spring支持的转换器
spring在org.springframework.core.convert.concerter包中定义了3种类型的转换器接口,我们可以实现其中任意一种转换器接口,并将它作为自定义转换器注册到ConversionServiceFactoryBean当中。3种转换器接口:
举个例子:
假设某User类型的组成如下,User还作为处理方法的参数。前端页面传递的都是字符串类型。
public class User implementsSerializable{ private static final long serialVersionUID = 1L; privateString loginname; privateDate birthday; ... }
这时候接收Date类型的数据绑定到User中就要经过处理了,开发自己的转换器StringToDateConverter.java。
importjava.text.SimpleDateFormat; importjava.util.Date; importorg.springframework.core.convert.converter.Converter; //实现Converter<S,T>接口 public class StringToDateConverter implements Converter<String, Date>{ //日期类型模板:如yyyy-MM-dd privateString datePattern; public voidsetDatePattern(String datePattern) { this.datePattern =datePattern; } //Converter<S,T>接口的类型转换方法 @Override publicDate convert(String date) { try{ SimpleDateFormat dateFormat = new SimpleDateFormat(this.datePattern); //将日期字符串转换成Date类型返回 returndateFormat.parse(date); } catch(Exception e) { e.printStackTrace(); System.out.println("日期转换失败!"); return null; } } }
在springmvc-config.xml中加入自定义的字符转换器。
<!--装配自定义的类型转换器,
默认annotation-dricen会注册一个ConversionService,即FormattingConversionServiceFactoryBean
,以满足大多数类型转换的需求。现在要注册一个自定义的转换类,因此需要显式地使用一个ConversionService覆盖
默认的实现类,通过制定conversion-service指定。这样在任意处理器中都可以使用该转换器了。 --> <mvc:annotation-driven conversion-service="conversionService"/> <!--自定义的类型转换器 --> <bean id="conversionService"class="org.springframework.context.support.ConversionServiceFactoryBean"> <property name="converters"> <list> <bean class="com.lfy.converter.StringToDateConverter"p:datePattern="yyyy-MM-dd"/> </list> </property> </bean>
UserController.java
packagecom.lfy.controller; importcom.lfy.bean.User; importorg.springframework.stereotype.Controller; importorg.springframework.ui.Model; importorg.springframework.web.bind.annotation.ModelAttribute; importorg.springframework.web.bind.annotation.RequestMapping; @Controller public classUserController{ ...@RequestMapping(value="/register") publicString register( @ModelAttribute User user, Model model) { System.out.println(user); model.addAttribute("user", user); return "success"; } }
运行结果:
3》使用@InitBinder添加自定义的编辑器转换数据
spring MVC在支持新的转换器框架的同时,也支持Java Bean的PropertyEditor。可以在控制器中使用@InitBinder添加自定义的编辑器。
在上面一个例子中将springmvc-config.xml中自定义的转换器删除。然后添加DateEditor.java
packagecom.lfy.converter; importjava.beans.PropertyEditorSupport; importjava.text.ParseException; importjava.text.SimpleDateFormat; importjava.util.Date; public class DateEditor extendsPropertyEditorSupport { @Override public void setAsText(String text) throwsIllegalArgumentException { SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd"); try{ Date date =dateFormat.parse(text); setValue(date); } catch(ParseException e) { e.printStackTrace(); } } }
修改UserController.java
packagecom.lfy.controller; importcom.lfy.bean.User; importcom.lfy.converter.DateEditor; importjava.util.Date; importorg.springframework.stereotype.Controller; importorg.springframework.ui.Model; importorg.springframework.web.bind.WebDataBinder; importorg.springframework.web.bind.annotation.InitBinder; importorg.springframework.web.bind.annotation.ModelAttribute; importorg.springframework.web.bind.annotation.RequestMapping; @Controller public classUserController{ @RequestMapping(value="/registerForm") publicString registerForm(){ return "registerForm"; } //在控制器初始化时注册属性编辑器 @InitBinder public voidinitBinder(WebDataBinder binder){ //注册自定义编辑器 binder.registerCustomEditor(Date.class, newDateEditor()); } @RequestMapping(value="/register") publicString register( @ModelAttribute User user, Model model) { System.out.println(user); model.addAttribute("user", user); return "success"; } }
运行,结果和上面的例子一致。
4》使用WebBindingInitializer注册全局自定义编辑器转换数据
如果希望在全局范围内使用自定义的编辑器,则可以通过实现WebBindingInitializer接口并在该实现类中注册自定义编辑器完成。
增加DateBindingInitializer.java
packagecom.lfy.binding; importjava.util.Date; importcom.lfy.converter.DateEditor; importorg.springframework.web.bind.WebDataBinder; importorg.springframework.web.bind.support.WebBindingInitializer; importorg.springframework.web.context.request.WebRequest; public class DateBindingInitializer implementsWebBindingInitializer { @Override public voidinitBinder(WebDataBinder binder, WebRequest webRequest) { binder.registerCustomEditor(Date.class, newDateEditor()); } }
去除UserController.java中的@InitBinder注解,UserController.java
packagecom.lfy.controller; importcom.lfy.bean.User; importcom.lfy.converter.DateEditor; importjava.util.Date; importorg.springframework.stereotype.Controller; importorg.springframework.ui.Model; importorg.springframework.web.bind.WebDataBinder; importorg.springframework.web.bind.annotation.InitBinder; importorg.springframework.web.bind.annotation.ModelAttribute; importorg.springframework.web.bind.annotation.RequestMapping; @Controller public classUserController{ @RequestMapping(value="/registerForm") publicString registerForm(){ return "registerForm"; } @RequestMapping(value="/register") publicString register( @ModelAttribute User user, Model model) { System.out.println(user); model.addAttribute("user", user); return "success"; } }
修改springmvc-config.xml,配置全局的自定义编辑器
<?xml version="1.0" encoding="utf-8"?> <beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns="http://www.springframework.org/schema/beans"xmlns:p="http://www.springframework.org/schema/p"xmlns:mvc="http://www.springframework.org/schema/mvc"xmlns:context="http://www.springframework.org/schema/context"xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd"> <mvc:default-servlet-handler/> <!--扫描controller --> <context:component-scan base-package="com.lfy.controller"/>
<!-- 通过RequestMappingHandlerAdapter装配自定义编辑器 -->
<beanclass="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
<propertyname="webBindingInitializer">
<beanclass="com.lfy.binding.DateBindingInitializer" />
</property>
</bean>
<!--视图解析器 --> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"p:prefix="/WEB-INF/content/"p:suffix=".jsp" /> </beans>
运行,结果与上一示例一致。
3、多种转换器的优先级(多种方式可以同时并存),优先查找顺序为:
4、数据格式化
5、数据校验