1.Spring使用Converter转换器进行源类型对象到目标类型对象的转换(完成任意Object与Object之间的类型转换),而Formatter完成任意Object与Stinrg之间的类型转换,即格式化和解析。Formatter更实用于Web层的数据转换,而Converter可以用在任意层中。
2.使用ConversionService转换数据:
(1)向项目的WEB-INF/lib文件夹下导入Spring的jar包
(2)配置web.xml文件:配置SpringMVC的前端控制器
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0"> <display-name>SpringMVC_2</display-name> <welcome-file-list> <welcome-file>index.html</welcome-file> <welcome-file>index.htm</welcome-file> <welcome-file>index.jsp</welcome-file> <welcome-file>default.html</welcome-file> <welcome-file>default.htm</welcome-file> <welcome-file>default.jsp</welcome-file> </welcome-file-list> <servlet> <servlet-name>springmvc</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:springmvc.xml</param-value> </init-param> <!-- 让servlet随服务启动 --> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>springmvc</servlet-name> <url-pattern>*.action</url-pattern> </servlet-mapping> </web-app>
(3)编写实体类:Users.java
package com.entity; import java.util.Date; public class Users { private Date date; public Date getDate() { return date; } public void setDate(Date date) { this.date = date; } public Users() { // TODO Auto-generated constructor stub } public Users(Date date) { this.date = date; } }
(4)编写视图界面:index.jsp
(5)编写处理器handler:MyController.java<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Insert title here</title> </head> <body> <form action="show.action" method="post"> 日期:<input name="date"> <input type="submit" value="提交"> <span>${requestScope.user.date }</span> </form> </body> </html>
package com.controller; import java.util.Date; import javax.servlet.http.HttpServletRequest; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.ModelAttribute; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import com.entity.Users; @Controller public class MyController { @RequestMapping("/home") public String home(){ return "index"; } @RequestMapping("/show") public String show(@RequestParam Date date,HttpServletRequest request,@ModelAttribute Users user){ System.out.println(date); request.setAttribute("user", user); return "index"; } }
上面@RequestParam获取到从jsp传过来的name属性为date的值为String类型的,而这里定义为了Date类型,所以这里必须配置数据转换才能运行成功,否则运行失败,报出错误。
(6)编写自定义转换器,将传递的字符串转换为Date类型:StringToDateConverter.java
package com.converter; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; import org.springframework.core.convert.converter.Converter; public class StringToDateConverter implements Converter<String, Date>{ @Override public Date convert(String date) { SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd"); try { return format.parse(date); } catch (ParseException e) { // TODO Auto-generated catch block e.printStackTrace(); return null; } } }
(7)配置SpringMVC配置文件:springmvc.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:c="http://www.springframework.org/schema/c" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.1.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd"> <!-- 实际开发中使用<mvc:annotation-driven/>代替注解适配器和映射器 --> <!-- <mvc:annotation-driven/> --> <!-- 加载静态文件 --> <mvc:default-servlet-handler/> <!-- 配置视图解析器 --> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <!-- 后缀 --> <property name="suffix"> <value>.jsp</value> </property> </bean> <!-- 装配转换器 --> <mvc:annotation-driven conversion-service="conversionService"/> <!-- 配置转换器 --> <bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean"> <property name="converters"> <list> <bean class="com.converter.StringToDateConverter"/> </list> </property> </bean> </beans>
3.使用@initBinder添加自定义编辑器转换数据:
(1)编写自定义属性编辑器:DateEditor.java
package com.converter; import java.beans.PropertyEditorSupport; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; //自定义属性编辑器 public class DateEditor extends PropertyEditorSupport{ //将传入的字符串数据转换成Date类型 @Override public void setAsText(String text) throws IllegalArgumentException { SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");//设定页面输入时时间格式 try { Date date = format.parse(text); setValue(date); } catch (ParseException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
(2)在控制器初始化时注册属性编辑器,在处理器中添加注册自定义编辑器的方法,处理器MyController.java如下:
package com.controller; import java.util.Date; import javax.servlet.http.HttpServletRequest; import org.springframework.stereotype.Controller; import org.springframework.web.bind.WebDataBinder; import org.springframework.web.bind.annotation.InitBinder; import org.springframework.web.bind.annotation.ModelAttribute; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import com.converter.DateEditor; import com.entity.Users; @Controller public class MyController { @RequestMapping("/home") public String home(){ return "index"; } @RequestMapping("/show") public String show(@RequestParam Date date,HttpServletRequest request,@ModelAttribute Users user){ System.out.println(date); request.setAttribute("user", user); return "index"; } //在控制器初始化时注册属性编辑器 @InitBinder public void initBinder(WebDataBinder binder){ //注册自定义编辑器 binder.registerCustomEditor(Date.class, new DateEditor()); } }
(3)SpringMVC的配置文件就可如下配置(可以减少对于转换器的配置):springmvc.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:c="http://www.springframework.org/schema/c" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.1.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd"> <!-- 将注解的类,扫描加载 --> <context:component-scan base-package="com.controller"/> <!-- 注解的映射器和适配器,对类中使用了@RequestMapping标志的方法进行映射和适配 <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"/> <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"/>--> <!-- 实际开发中使用<mvc:annotation-driven/>代替注解适配器和映射器 --> <!-- <mvc:annotation-driven/> --> <!-- 加载静态文件 --> <mvc:default-servlet-handler/> <!-- 配置视图解析器 --> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <!-- 前缀 <property name="prefix"> <value>/WEB-INF/</value> </property>--> <!-- 后缀 --> <property name="suffix"> <value>.jsp</value> </property> </bean> <mvc:annotation-driven /> </beans>
4.使用WebBindingInitializer注册全局自定义编辑器转换数据:
数据绑定转换器:DateBindingInitializer.java
package com.binding2; import java.util.Date; import org.springframework.web.bind.WebDataBinder; import org.springframework.web.bind.support.WebBindingInitializer; import org.springframework.web.context.request.WebRequest; import com.converter2.DateEditor; //全局数据绑定转换器,实现WebBindingInitializer接口 public class DateBindingInitializer implements WebBindingInitializer{ @Override public void initBinder(WebDataBinder binder, WebRequest request) { //注册自定义编辑器 binder.registerCustomEditor(Date.class, new DateEditor());//DateEditor类与上面一样 } }
SpringMVC配置文件:springmvc.xml:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:c="http://www.springframework.org/schema/c" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.1.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd"> <context:component-scan base-package="com.controller"/> <!-- 配置视图解析器 --> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <!-- 前缀 <property name="prefix"> <value>/WEB-INF/</value> </property>--> <!-- 后缀 --> <property name="suffix"> <value>.jsp</value> </property> </bean> <!-- 通过 AnnotationMethodHandlerAdapter装配自定义编辑器--> <bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter"> <property name="webBindingInitializer"> <bean class="com.binding2.DateBindingInitializer"/> </property> </bean> </beans>
注意:使用AnnotationMethodHandlerAdapter时不能与mvc的标签同时使用,会出现冲突。Spring3.1之后,DefaultAnnotationHandlerMapping被RequestMappingHandlerMapping替代,AnnotationMethodHandlerAdapter被RequestMappingHandlerAdapter替代。
5.使用Formatter格式化数据:
格式化转换类:DateFormatter.java:
package com.converter2; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; import java.util.Locale; import org.springframework.format.Formatter; import org.springframework.format.FormatterRegistrar; import org.springframework.format.FormatterRegistry; public class DateFormatter implements Formatter<Date>{ //日期格式化对象 private SimpleDateFormat format; //日期类型模板:如yyyy-MM-dd private String pattern; public DateFormatter(String pattern) { this.pattern = pattern; this.format = new SimpleDateFormat(pattern); } //显示Formatter<T>的T类型对象 @Override public String print(Date date, Locale arg1) { return format.format(date); } //解析文本字符串,返回一个Formatter<T>的T类型对象 @Override public Date parse(String source, Locale arg1) throws ParseException{ return format.parse(source); } }
配置springMVC的配置文件:springmvc.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:c="http://www.springframework.org/schema/c" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.1.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd"> <!-- 扫描加载固定包下面的注解类 --> <context:component-scan base-package="com.controller"/> <!-- 加载适配器和映射器等 --> <mvc:annotation-driven conversion-service="conversionService"/> <!-- 加载静态文件 --> <!-- <mvc:default-servlet-handler/> --> <!-- 配置视图解析器 --> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <!-- 前缀 <property name="prefix"> <value>/WEB-INF/</value> </property>--> <!-- 后缀 --> <property name="suffix"> <value>.jsp</value> </property> </bean> <!-- 格式化 转换器--> <bean id="conversionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean"> <property name="formatters"> <list> <bean class="com.converter.DateFormatter" c:_0="yyyy/MM/dd"/> </list> </property> </bean> </beans>
c:_0:表示DateFormatter.java这个类的构造函数的第一个参数,这里指向的是pattern。
注意:
Spring的p命名空间和c命名空间(Spring4以后):
p命名空间对应setter注入属性方式:需要在命名空间引入
xmlns:c="http://www.springframework.org/schema/p"
c命名空间对应constructor构造函数注入方式:需要在命名空间引入
xmlns:c="http://www.springframework.org/schema/c"
另外:可以使用spring框架中自带的处理字符串到日期对象的转换的类:只需要在springMVC的配置文件springmvc.xml中修改配置就可以了,如下:
<!-- 使用spring框架内置的String转日期对象的格式化器 --> <mvc:annotation-driven conversion-service="conversionService"/> <bean id="conversionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean"> <property name="formatters"> <list> <bean class="org.springframework.format.datetime.DateFormatter" p:pattern="yyyy-MM-dd"/> </list> </property> </bean>
6.使用FormatterRegistrar注册Formatter,实现数据格式化:
编写格式化转换器:DateFormatterRegistrar.java
package com.converter2; import org.springframework.format.FormatterRegistrar; import org.springframework.format.FormatterRegistry; import org.springframework.format.datetime.DateFormatter; /** * * @author ${HLoach} * 2017年4月5日 */ public class DateFormatterRegistrar implements FormatterRegistrar{ private DateFormatter dateFormatter; public void setDateFormatter(DateFormatter dateFormatter) { this.dateFormatter = dateFormatter; } @Override public void registerFormatters(FormatterRegistry registry) { registry.addFormatter(dateFormatter); } }
配置springMVC的配置文件:springmvc.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:c="http://www.springframework.org/schema/c" xmlns:p="http://www.springframework.org/schema/p" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.1.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd"> <!-- 扫描加载固定包下面的注解类 --> <context:component-scan base-package="com.controller"/> <!-- 加载适配器和映射器等 --> <!-- <mvc:annotation-driven/> --> <!-- 加载静态文件 --> <!-- <mvc:default-servlet-handler/> --> <!-- 配置视图解析器 --> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <!-- 前缀 <property name="prefix"> <value>/WEB-INF/</value> </property>--> <!-- 后缀 --> <property name="suffix"> <value>.jsp</value> </property> </bean> <!-- 装配自定义格式化 --> <mvc:annotation-driven conversion-service="conversionService"/> <bean id="dateFormatter" class="com.converter2.DateFormatterRegister" c:_0="yyyy-MM-dd"/> <!-- 使用FormatterRegistrar注册Formatter--> <bean id="conversionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean"> <property name="formatterRegistrars"> <list> <bean class="com.converter2.DateFormatterRegistrar" p:dateFormatter-ref="dateFormatter"/> </list> </property> </bean> </beans>
7.使用AnnotationFormatterFactory<A extendsAnnotation>格式化数据(注解方式):
只需按如下方式在实体类中的属性之上添加注解就可以实现数据的格式化:Number.java
package com.beans2; import java.io.Serializable; import java.util.Date; import org.springframework.format.annotation.DateTimeFormat; import org.springframework.format.annotation.NumberFormat; import org.springframework.format.annotation.NumberFormat.Style; /** * 使用注解方式实现数据格式化 * @author ${HLoach} * 2017年4月5日 */ public class Number implements Serializable{ //日期类型 @DateTimeFormat(pattern="yyyy-MM-dd") private Date birthday; //正常数字类型 @NumberFormat(style=Style.NUMBER,pattern="#,###") private int total; //百分数类型 @NumberFormat(style=Style.PERCENT) private double discount; //货币类型 @NumberFormat(style=Style.CURRENCY) private double money; public Date getBirthday() { return birthday; } public void setBirthday(Date birthday) { this.birthday = birthday; } public int getTotal() { return total; } public void setTotal(int total) { this.total = total; } public double getDiscount() { return discount; } public void setDiscount(double discount) { this.discount = discount; } public double getMoney() { return money; } public void setMoney(double money) { this.money = money; } }