Spring总是试图用默认的语言区域将日期输入绑定 到java.util.Date。假如想让Spring使用不同的日期样 式,就需要用一个Converter(转换器)或者 Formatter(格式化)来协助Spring完成。

一. Converter

  利用Converter进行日期的格式化

  Spring的Converter是一个可以将一种类型转换成另 一种类型的对象。例如,用户输入的日期可能有许多种 形式,如“December 25,2014”“12/25/2014”“2014-12- 25” ,这些都表示同一个日期。默认情况下,Spring会 期待用户输入的日期样式与当前语言区域的日期样式相 同。例如,对于美国的用户而言,就是月/日/年格式。 如果希望Spring在将输入的日期字符串绑定到Date时, 使用不同的日期样式,则需要编写一个Converter,才能 将字符串转换成日期。

1. 日期格式化需要的类:org.springframework.core.convert.converter.Converter

需要实现org.springframework.core.convert.converter.Converter的接口

  1. public interface Converter<S, T

例如

  1. package converter;
  2.  
  3. import java.text.ParseException;
  4. import java.text.SimpleDateFormat;
  5. import java.util.Date;
  6. import org.springframework.core.convert.converter.Converter;
  7. //必须实现 Converter
  8. public class StringToDateConverter implements Converter<String, Date> {
  9. private String datePattern;
  10.  
  11. public StringToDateConverter(String datePattern) {
  12. this.datePattern = datePattern;
  13. System.out.println("instantiating .... converter with pattern:*" + datePattern);
  14. }
  15. // 转换日期格式
    @Override
  16. public Date convert(String s) {
  17. try {
  18. SimpleDateFormat dateFormat = new SimpleDateFormat(datePattern);
  19. dateFormat.setLenient(false);
  20. return dateFormat.parse(s);
  21. } catch (ParseException e) {
  22. // the error message will be displayed when using
  23. // <form:errors>
  24. throw new IllegalArgumentException("invalid date format. Please use this pattern\"" + datePattern + "\"");
  25. }
  26. }
  27. }

2. springmvc-cofing.xml配置

  1. <mvc:annotation-driven conversion-service="conversionService"/>
  2. <bean id="conversionService"
  3. class="org.springframework.context.support.ConversionServiceFactoryBean">
  4. <property name="converters">
  5. <list>
  6. <bean class="converter.StringToDateConverter">
  7. <constructor-arg type="java.lang.String"
  8. value="MM-dd-yyyy" />
  9. </bean>
  10. </list>
  11. </property>
  12. </bean>

3.controller类

  1. package controller;
  2.  
  3. import org.apache.commons.logging.Log;
  4. import org.apache.commons.logging.LogFactory;
  5. import org.springframework.ui.Model;
  6. import org.springframework.validation.BindingResult;
  7. import org.springframework.validation.FieldError;
  8. import org.springframework.web.bind.annotation.ModelAttribute;
  9. import org.springframework.web.bind.annotation.RequestMapping;
  10. import domain.Employee;
  11.  
  12. @org.springframework.stereotype.Controller
  13. public class EmployeeController {
  14. private static final Log logger = LogFactory.getLog(EmployeeController.class);
  15.  
  16. @RequestMapping(value="employee_input")
  17. public String inputEmployee(Model model) {
  18. model.addAttribute(new Employee());
  19. return "EmployeeForm";
  20. }
  21.  
  22. @RequestMapping(value="employee_save")
  23. public String saveEmployee(@ModelAttribute Employee employee,BindingResult bindingResult,Model model) {
  24. if(bindingResult.hasErrors()) {
  25. FieldError fieldError = bindingResult.getFieldError();
  26. logger.info("Code:" + fieldError.getCode()
  27. + ", field:" + fieldError.getField());
  28. }
  29. // save employee here
  30. model.addAttribute("employee",employee);
  31.  
  32. return "EmployeeDetails";
  33. }
  34. }

4.view视图

  1. <%@ taglib prefix="form" uri="http://www.springframework.org/ta
  2. gs/form" %>
  3. <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %
  4. >
  5. <!DOCTYPE html>
  6. <html>
  7. <head>
  8. <title>Add Employee Form</title>
  9. <style type="text/css">@import url("<c:url
  10. value="/css/main.css"/>");</style>
  11. </head>
  12. <body>
  13. <div id="global">
  14. <form:form commandName="employee" action="employee_save" method
  15. ="post">
  16. <fieldset>
  17. <legend>Add an employee</legend>
  18. <p>
  19. <label for="firstName">First Name: </label>
  20. <form:input path="firstName" tabindex="1"/>
  21. </p>
  22. <p>
  23. <label for="lastName">First Name: </label>
  24. <form:input path="lastName" tabindex="2"/>
  25. </p>
  26. <p>
    <!-- 打印错误 -->
  27. <form:errors path="birthDate" cssClass="error"/>
  28. </p>
  29. <p>
  30. <label for="birthDate">Date Of Birth: </label>
  31. <form:input path="birthDate" tabindex="3" />
  32. </p>
  33. <p id="buttons">
  34. <input id="reset" type="reset" tabindex="4">
  35. <input id="submit" type="submit" tabindex="5"
  36. value="Add Employee">
  37. </p>
  38. </fieldset>
  39. </form:form>
  40. </div>
  41. </body>
  42. </html>

二. Formatter

  Formatter就像Converter一样,也是将一种类型转换 成另一种类型。但是,Formatter的源类型必须是一个 String,而Converter则适用于任意的源类型。Formatter 更适合Web层,而Converter则可以用在任意层中。为了 转换Spring MVC应用程序表单中的用户输入,始终应 该选择Formatter,而不是Converter。

1. 为了创建Formatter,要编写一个实现 org.springframework.format.Formatter接口的Java类。下 面是这个接口的声明:

  1. public interface Formatter<T >

  这里的T表示输入字符串要转换的目标类型。该接 口有parse和print两个方法,所有实现都必须覆盖:

  1. T parse(String text, java.util.Locale locale)
  2. String print(T object, java.util.Locale locale)

  parse方法利用指定的Locale将一个String解析成目 标类型。print方法与之相反,它是返回目标对象的字符 串表示法。

  例如,app20a应用程序中用一个DateFormatter将 String转换成Date

DateFormatter类

  1. package fomatter;
  2.  
  3. import java.text.ParseException;
  4. import java.text.SimpleDateFormat;
  5. import java.util.Date;
  6. import java.util.Locale;
  7.  
  8. import org.springframework.format.Formatter;
  9.  
  10. public class DateFormatter implements Formatter<Date>{
  11. private String datePattern;
  12. private SimpleDateFormat dateFormat;
  13. /* 这里的datepattern 从springmvc-config.xml传入 */
  14. public DateFormatter(String datePattern) {
  15. this.datePattern = datePattern;
  16. dateFormat = new SimpleDateFormat(datePattern);
  17. dateFormat.setLenient(false);
  18. }
  19.  
  20. @Override
  21. public String print(Date date, Locale locale) {
  22. return dateFormat.format(date);
  23. }
  24.  
  25. @Override
  26. public Date parse(String s, Locale locale) throws ParseException {
  27.  
  28. try {
  29. return dateFormat.parse(s);
  30. }catch(ParseException e) {
  31. // the error message will be displayed when using
  32. // <form:errors>
  33. throw new IllegalArgumentException(
  34. "invalid date format. Please use this pattern\""
  35. + datePattern + "\"");
  36. }
  37. }
  38. }

app20b的Spring配置文件

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xmlns:mvc="http://www.springframework.org/schema/mvc"
  5. xmlns:context="http://www.springframework.org/schema/context"
  6. xsi:schemaLocation="http://www.springframework.org/schema/beans
  7. http://www.springframework.org/schema/beans/spring-beans.xsd
  8. http://www.springframework.org/schema/mvc
  9. http://www.springframework.org/schema/mvc/spring-mvc.xsd
  10. http://www.springframework.org/schema/context
  11. http://www.springframework.org/schema/context/spring-context.xsd">
  12.  
  13. <!-- 配置自定义扫描的包 -->
  14. <context:component-scan
  15. base-package="controller">
  16. </context:component-scan>
  17. <context:component-scan base-package="formatter"/>
  18. <bean
  19. class="org.springframework.web.servlet.view.InternalResourceViewResolver">
  20. <!-- 前缀 和 后缀 -->
  21. <property name="prefix" value="/WEB-INF/jsp/" />
  22. <property name="suffix" value=".jsp" />
  23. </bean>
  24.  
  25. <!-- 转换器 -->
  26. <mvc:annotation-driven conversion-service="conversionService" />
  27.  
  28. <bean id="conversionService"
  29. class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
  30. <property name="formatters">
  31. <set>
  32. <bean class="fomatter.DateFormatter">
  33. <constructor-arg type="java.lang.String"
  34. value="MM-dd-yyyy" />
  35. </bean>
  36. </set>
  37. </property>
  38. </bean>
  39. </beans>

EmployeeController类

  1. package controller;
  2.  
  3. import org.apache.commons.logging.Log;
  4. import org.apache.commons.logging.LogFactory;
  5. import org.springframework.ui.Model;
  6. import org.springframework.validation.BindingResult;
  7. import org.springframework.validation.FieldError;
  8. import org.springframework.web.bind.annotation.ModelAttribute;
  9. import org.springframework.web.bind.annotation.RequestMapping;
  10. import domain.Employee;
  11.  
  12. @org.springframework.stereotype.Controller
  13. public class EmployeeController {
  14. private static final Log logger = LogFactory.getLog(EmployeeController.class);
  15.  
  16. @RequestMapping(value="employee_input")
  17. public String inputEmployee(Model model) {
  18. model.addAttribute(new Employee());
  19. return "EmployeeForm";
  20. }
  21.  
  22. @RequestMapping(value="employee_save")
  23. public String saveEmployee(@ModelAttribute Employee employee,BindingResult bindingResult,Model model) {
  24. if(bindingResult.hasErrors()) {
  25. FieldError fieldError = bindingResult.getFieldError();
  26. logger.info("Code:" + fieldError.getCode()
  27. + ", field:" + fieldError.getField());
  28. }
  29. // save employee here
  30. model.addAttribute("employee",employee);
  31.  
  32. return "EmployeeDetails";
  33. }
  34. }

EmployeeForm.jsp页面

  1. <%@ page language="java" contentType="text/html; charset=UTF-8"
  2. pageEncoding="UTF-8"%>
  3. <%@ taglib prefix="form"
  4. uri="http://www.springframework.org/tags/form"%>
  5. <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
  6. <!DOCTYPE html>
  7. <html>
  8. <head>
  9. <title>Add Employee Form</title>
  10. <style type="text/css">
  11. @import url("<c:url value= "/css/main.css"/>");
  12. </style>
  13. </head>
  14. <body>
  15. <div id="global">
  16. <form:form modelAttribute="employee" action="employee_save" method="post">
  17. <fieldset>
  18. <legend>Add an employee</legend>
  19. <p>
  20. <label for="firstName">First Name: </label>
  21. <form:input path="firstName" tabindex="1" />
  22. </p>
  23. <p>
  24. <label for="lastName">First Name: </label>
  25. <form:input path="lastName" tabindex="2" />
  26. </p>
  27. <p>
  28. <form:errors path="birthDate" cssClass="error" />
  29. </p>
  30. <p>
  31. <label for="birthDate">Date Of Birth: </label>
  32. <form:input path="birthDate" tabindex="3" />
  33. </p>
  34. <p id="buttons">
  35. <input id="reset" type="reset" tabindex="4"> <input
  36. id="submit" type="submit" tabindex="5" value="Add Employee">
  37. </p>
  38. </fieldset>
  39. </form:form>
  40. </div>
  41. </body>
  42. </html>

三. 用Registrar注册Formatter

  注册Formatter的另一种方法是使用Registrar。例 如,以下app20b就是注册DateFormatter的一个例子

MyFormatterRegistrar类

  1. package formatter;
  2.  
  3. import org.springframework.format.FormatterRegistrar;
  4. import org.springframework.format.FormatterRegistry;
  5.  
  6. public class MyFormatterRegistrar implements FormatterRegistrar {
  7. private String datePattern;
  8.  
  9. public MyFormatterRegistrar(String datePattern) {
  10. this.datePattern = datePattern;
  11. }
  12.  
  13. @Override
  14. public void registerFormatters(FormatterRegistry registry) {
  15. registry.addFormatter(new DateFormatter(datePattern));
  16. // register more formatters here
  17. }
  18. }

  有了Registrar,就不需要在Spring MVC配置文件中 注册任何Formatter了,只在Spring配置文件中注册 Registrar

springmvc-config配置

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xmlns:mvc="http://www.springframework.org/schema/mvc"
  5. xmlns:context="http://www.springframework.org/schema/context"
  6. xsi:schemaLocation="http://www.springframework.org/schema/beans
  7. http://www.springframework.org/schema/beans/spring-beans.xsd
  8. http://www.springframework.org/schema/mvc
  9. http://www.springframework.org/schema/mvc/spring-mvc.xsd
  10. http://www.springframework.org/schema/context
  11. http://www.springframework.org/schema/context/spring-context.xsd">
  12.  
  13. <!-- 配置自定义扫描的包 -->
  14. <context:component-scan
  15. base-package="controller">
  16. </context:component-scan>
  17. <context:component-scan base-package="formatter" />
  18. <bean
  19. class="org.springframework.web.servlet.view.InternalResourceViewResolver">
  20. <!-- 前缀 和 后缀 -->
  21. <property name="prefix" value="/WEB-INF/jsp/" />
  22. <property name="suffix" value=".jsp" />
  23. </bean>
  24.  
  25. <!-- 转换器 -->
  26. <mvc:annotation-driven
  27. conversion-service="conversionService" />
  28.  
  29. <bean id="conversionService"
  30. class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
  31. <property name="formatterRegistrars">
  32. <set>
  33. <bean class="formatter.MyFormatterRegistrar">
  34. <constructor-arg type="java.lang.String"
  35. value="MM-dd-yyyy" />
  36. </bean>
  37. </set>
  38. </property>
  39. </bean>
  40.  
  41. </beans>

四. 选择Converter,还是 Formatter

  Converter是一般工具,可以将一种类型转换成另一 种类型。例如,将String转换成Date,或者将Long转换 成Date。Converter既可以用在Web层,也可以用在其他 层中

  将String转换成Date,但它不能将Long转换成 Date。因此,Formatter适用于Web层。为此,在Spring MVC应用程序中,选择Formatter比选择Converter更合 适。

  

  

spring 转换器和格式化的更多相关文章

  1. Spring官网阅读(十五)Spring中的格式化(Formatter)

    文章目录 Formatter 接口定义 继承树 注解驱动的格式化 AnnotationFormatterFactory FormatterRegistry 接口定义 UML类图 FormattingC ...

  2. SpringMVC:学习笔记(6)——转换器和格式化

    转换器和格式化 说明 SpringMVC的数据绑定并非没有限制,有案例表明,在SpringMVC如何正确绑定数据方面是杂乱无章的,比如在处理日期映射到Date对象上. 为了能够让SpringMVC进行 ...

  3. Spring MVC -- 转换器和格式化

    在Spring MVC -- 数据绑定和表单标签库中我们已经见证了数据绑定的威力,并学习了如何使用表单标签库中的标签.但是,Spring的数据绑定并非没有任何限制.有案例表明,Spring在如何正确绑 ...

  4. Spring mvc数据转换 格式化 校验(转载)

    原文地址:http://www.cnblogs.com/linyueshan/p/5908490.html 数据绑定流程 1. Spring MVC 主框架将 ServletRequest 对象及目标 ...

  5. spring mvc 数据格式化

    web.xml <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www. ...

  6. Spring Security OAuth 格式化 token 输出

    个性化token 背景 上一篇文章<Spring Security OAuth 个性化token(一)>有提到,oauth2.0 接口默认返回的报文格式如下: {     "ac ...

  7. 【Spring学习笔记-MVC-9】SpringMVC数据格式化之日期转换@DateTimeFormat

    作者:ssslinppp       1. 摘要 本文主要讲解Spring mvc数据格式化的具体步骤: 并讲解前台日期格式如何转换为java对象: 在之前的文章<[Spring学习笔记-MVC ...

  8. 8. 格式化器大一统 -- Spring的Formatter抽象

    目录 ✍前言 本文提纲 版本约定 ✍正文 Printer&Parser Formatter 时间日期格式化 Date类型 代码示例 JSR 310类型 整合DateTimeFormatter ...

  9. Spring MVC深入学习

    一.MVC思想 MVC思想简介:        MVC并不是java所特有的设计思想,也不是Web应用所特有的思想,它是所有面向对象程序设计语言都应该遵守的规范:MVC思想将一个应用部分分成三个基本部 ...

随机推荐

  1. python convert csv to xlsx

    搬运:http://stackoverflow.com/questions/17684610/python-convert-csv-to-xlsx import os import glob impo ...

  2. (原)centos 防火墙开放端口命令

    centos 防火墙默认是关闭非系统端口的,所以用到非系统端口首先开放,命令如下 firewall-cmd --zone=public --add-port=1935/tcp --permanent ...

  3. oracle exp不生成dumpfile,预估出实际导出文件的大小。

    目的:在不创建dumpfile前预估出需要的导出文件大小.  适用于export     实验步骤如下:OS:  Linux test20 2.6.18-238.el5 #1 SMP Sun Dec ...

  4. jQuery HTML- 添加元素

    添加内容 html <!DOCTYPE html> <html> <head> <meta charset="utf-8" /> & ...

  5. 属性.native用于解决第三方el组件库@click事件无效

    描述 有时发现用一些第三方的组件库时,例如一个封装好的button按钮<el-butten>,绑定点击事件却没有任何作用,这时便需要加 .native 原因: v-on 是对 Vue 的事 ...

  6. STM点滴一

    就就是你用BSRR和BRR去改变管脚状态的时候,没有被中断打断的风险.也就不需要关闭中断. This way, there is no risk that an IRQ occurs between ...

  7. Linux系统之-常用命令及技巧

    一. 通用命令:1.date :print or set the system date and time2. stty -a: 可以查看或者打印控制字符(Ctrl-C, Ctrl-D, Ctrl-Z ...

  8. 分布式系统理论基础8:zookeeper分布式协调服务

    本文转自 https://www.cnblogs.com/bangerlee/p/5268485.html 本系列文章将整理到我在GitHub上的<Java面试指南>仓库,更多精彩内容请到 ...

  9. 《ArcGIS Runtime SDK for .NET开发笔记》--三维功能

    介绍 在ArcGIS Runtim SDK for .NET 10.2.6中,新添加了三维地图功能.在ArcGIS中,我们将三维地图称为Scene(场景),所以在Runtime SDK SDK for ...

  10. 在pycharm中切换python版本的方法

    转载自:https://blog.csdn.net/sgfmby1994/article/details/77876873 目前,python2和python3都有很重要的意义,所以,我们经常会在电脑 ...