spring 转换器和格式化
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的接口
public interface Converter<S, T
例如
package converter; import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.springframework.core.convert.converter.Converter;
//必须实现 Converter
public class StringToDateConverter implements Converter<String, Date> {
private String datePattern; public StringToDateConverter(String datePattern) {
this.datePattern = datePattern;
System.out.println("instantiating .... converter with pattern:*" + datePattern);
}
// 转换日期格式
@Override
public Date convert(String s) {
try {
SimpleDateFormat dateFormat = new SimpleDateFormat(datePattern);
dateFormat.setLenient(false);
return dateFormat.parse(s);
} catch (ParseException e) {
// the error message will be displayed when using
// <form:errors>
throw new IllegalArgumentException("invalid date format. Please use this pattern\"" + datePattern + "\"");
}
}
}
2. springmvc-cofing.xml配置
<mvc:annotation-driven conversion-service="conversionService"/>
<bean id="conversionService"
class="org.springframework.context.support.ConversionServiceFactoryBean">
<property name="converters">
<list>
<bean class="converter.StringToDateConverter">
<constructor-arg type="java.lang.String"
value="MM-dd-yyyy" />
</bean>
</list>
</property>
</bean>
3.controller类
package controller; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import domain.Employee; @org.springframework.stereotype.Controller
public class EmployeeController {
private static final Log logger = LogFactory.getLog(EmployeeController.class); @RequestMapping(value="employee_input")
public String inputEmployee(Model model) {
model.addAttribute(new Employee());
return "EmployeeForm";
} @RequestMapping(value="employee_save")
public String saveEmployee(@ModelAttribute Employee employee,BindingResult bindingResult,Model model) {
if(bindingResult.hasErrors()) {
FieldError fieldError = bindingResult.getFieldError();
logger.info("Code:" + fieldError.getCode()
+ ", field:" + fieldError.getField());
}
// save employee here
model.addAttribute("employee",employee); return "EmployeeDetails";
}
}
4.view视图
<%@ taglib prefix="form" uri="http://www.springframework.org/ta
gs/form" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %
>
<!DOCTYPE html>
<html>
<head>
<title>Add Employee Form</title>
<style type="text/css">@import url("<c:url
value="/css/main.css"/>");</style>
</head>
<body>
<div id="global">
<form:form commandName="employee" action="employee_save" method
="post">
<fieldset>
<legend>Add an employee</legend>
<p>
<label for="firstName">First Name: </label>
<form:input path="firstName" tabindex="1"/>
</p>
<p>
<label for="lastName">First Name: </label>
<form:input path="lastName" tabindex="2"/>
</p>
<p>
<!-- 打印错误 -->
<form:errors path="birthDate" cssClass="error"/>
</p>
<p>
<label for="birthDate">Date Of Birth: </label>
<form:input path="birthDate" tabindex="3" />
</p>
<p id="buttons">
<input id="reset" type="reset" tabindex="4">
<input id="submit" type="submit" tabindex="5"
value="Add Employee">
</p>
</fieldset>
</form:form>
</div>
</body>
</html>
二. Formatter
Formatter就像Converter一样,也是将一种类型转换 成另一种类型。但是,Formatter的源类型必须是一个 String,而Converter则适用于任意的源类型。Formatter 更适合Web层,而Converter则可以用在任意层中。为了 转换Spring MVC应用程序表单中的用户输入,始终应 该选择Formatter,而不是Converter。
1. 为了创建Formatter,要编写一个实现 org.springframework.format.Formatter接口的Java类。下 面是这个接口的声明:
public interface Formatter<T >
这里的T表示输入字符串要转换的目标类型。该接 口有parse和print两个方法,所有实现都必须覆盖:
T parse(String text, java.util.Locale locale)
String print(T object, java.util.Locale locale)
parse方法利用指定的Locale将一个String解析成目 标类型。print方法与之相反,它是返回目标对象的字符 串表示法。
例如,app20a应用程序中用一个DateFormatter将 String转换成Date
DateFormatter类
package fomatter; import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale; import org.springframework.format.Formatter; public class DateFormatter implements Formatter<Date>{
private String datePattern;
private SimpleDateFormat dateFormat;
/* 这里的datepattern 从springmvc-config.xml传入 */
public DateFormatter(String datePattern) {
this.datePattern = datePattern;
dateFormat = new SimpleDateFormat(datePattern);
dateFormat.setLenient(false);
} @Override
public String print(Date date, Locale locale) {
return dateFormat.format(date);
} @Override
public Date parse(String s, Locale locale) throws ParseException { try {
return dateFormat.parse(s);
}catch(ParseException e) {
// the error message will be displayed when using
// <form:errors>
throw new IllegalArgumentException(
"invalid date format. Please use this pattern\""
+ datePattern + "\"");
}
}
}
app20b的Spring配置文件
<?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: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.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd"> <!-- 配置自定义扫描的包 -->
<context:component-scan
base-package="controller">
</context:component-scan>
<context:component-scan base-package="formatter"/>
<bean
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!-- 前缀 和 后缀 -->
<property name="prefix" value="/WEB-INF/jsp/" />
<property name="suffix" value=".jsp" />
</bean> <!-- 转换器 -->
<mvc:annotation-driven conversion-service="conversionService" /> <bean id="conversionService"
class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
<property name="formatters">
<set>
<bean class="fomatter.DateFormatter">
<constructor-arg type="java.lang.String"
value="MM-dd-yyyy" />
</bean>
</set>
</property>
</bean>
</beans>
EmployeeController类
package controller; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import domain.Employee; @org.springframework.stereotype.Controller
public class EmployeeController {
private static final Log logger = LogFactory.getLog(EmployeeController.class); @RequestMapping(value="employee_input")
public String inputEmployee(Model model) {
model.addAttribute(new Employee());
return "EmployeeForm";
} @RequestMapping(value="employee_save")
public String saveEmployee(@ModelAttribute Employee employee,BindingResult bindingResult,Model model) {
if(bindingResult.hasErrors()) {
FieldError fieldError = bindingResult.getFieldError();
logger.info("Code:" + fieldError.getCode()
+ ", field:" + fieldError.getField());
}
// save employee here
model.addAttribute("employee",employee); return "EmployeeDetails";
}
}
EmployeeForm.jsp页面
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="form"
uri="http://www.springframework.org/tags/form"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<!DOCTYPE html>
<html>
<head>
<title>Add Employee Form</title>
<style type="text/css">
@import url("<c:url value= "/css/main.css"/>");
</style>
</head>
<body>
<div id="global">
<form:form modelAttribute="employee" action="employee_save" method="post">
<fieldset>
<legend>Add an employee</legend>
<p>
<label for="firstName">First Name: </label>
<form:input path="firstName" tabindex="1" />
</p>
<p>
<label for="lastName">First Name: </label>
<form:input path="lastName" tabindex="2" />
</p>
<p>
<form:errors path="birthDate" cssClass="error" />
</p>
<p>
<label for="birthDate">Date Of Birth: </label>
<form:input path="birthDate" tabindex="3" />
</p>
<p id="buttons">
<input id="reset" type="reset" tabindex="4"> <input
id="submit" type="submit" tabindex="5" value="Add Employee">
</p>
</fieldset>
</form:form>
</div>
</body>
</html>
三. 用Registrar注册Formatter
注册Formatter的另一种方法是使用Registrar。例 如,以下app20b就是注册DateFormatter的一个例子
MyFormatterRegistrar类
package formatter; import org.springframework.format.FormatterRegistrar;
import org.springframework.format.FormatterRegistry; public class MyFormatterRegistrar implements FormatterRegistrar {
private String datePattern; public MyFormatterRegistrar(String datePattern) {
this.datePattern = datePattern;
} @Override
public void registerFormatters(FormatterRegistry registry) {
registry.addFormatter(new DateFormatter(datePattern));
// register more formatters here
}
}
有了Registrar,就不需要在Spring MVC配置文件中 注册任何Formatter了,只在Spring配置文件中注册 Registrar
springmvc-config配置
<?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: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.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd"> <!-- 配置自定义扫描的包 -->
<context:component-scan
base-package="controller">
</context:component-scan>
<context:component-scan base-package="formatter" />
<bean
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!-- 前缀 和 后缀 -->
<property name="prefix" value="/WEB-INF/jsp/" />
<property name="suffix" value=".jsp" />
</bean> <!-- 转换器 -->
<mvc:annotation-driven
conversion-service="conversionService" /> <bean id="conversionService"
class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
<property name="formatterRegistrars">
<set>
<bean class="formatter.MyFormatterRegistrar">
<constructor-arg type="java.lang.String"
value="MM-dd-yyyy" />
</bean>
</set>
</property>
</bean> </beans>
四. 选择Converter,还是 Formatter
Converter是一般工具,可以将一种类型转换成另一 种类型。例如,将String转换成Date,或者将Long转换 成Date。Converter既可以用在Web层,也可以用在其他 层中
将String转换成Date,但它不能将Long转换成 Date。因此,Formatter适用于Web层。为此,在Spring MVC应用程序中,选择Formatter比选择Converter更合 适。
spring 转换器和格式化的更多相关文章
- Spring官网阅读(十五)Spring中的格式化(Formatter)
文章目录 Formatter 接口定义 继承树 注解驱动的格式化 AnnotationFormatterFactory FormatterRegistry 接口定义 UML类图 FormattingC ...
- SpringMVC:学习笔记(6)——转换器和格式化
转换器和格式化 说明 SpringMVC的数据绑定并非没有限制,有案例表明,在SpringMVC如何正确绑定数据方面是杂乱无章的,比如在处理日期映射到Date对象上. 为了能够让SpringMVC进行 ...
- Spring MVC -- 转换器和格式化
在Spring MVC -- 数据绑定和表单标签库中我们已经见证了数据绑定的威力,并学习了如何使用表单标签库中的标签.但是,Spring的数据绑定并非没有任何限制.有案例表明,Spring在如何正确绑 ...
- Spring mvc数据转换 格式化 校验(转载)
原文地址:http://www.cnblogs.com/linyueshan/p/5908490.html 数据绑定流程 1. Spring MVC 主框架将 ServletRequest 对象及目标 ...
- spring mvc 数据格式化
web.xml <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www. ...
- Spring Security OAuth 格式化 token 输出
个性化token 背景 上一篇文章<Spring Security OAuth 个性化token(一)>有提到,oauth2.0 接口默认返回的报文格式如下: { "ac ...
- 【Spring学习笔记-MVC-9】SpringMVC数据格式化之日期转换@DateTimeFormat
作者:ssslinppp 1. 摘要 本文主要讲解Spring mvc数据格式化的具体步骤: 并讲解前台日期格式如何转换为java对象: 在之前的文章<[Spring学习笔记-MVC ...
- 8. 格式化器大一统 -- Spring的Formatter抽象
目录 ✍前言 本文提纲 版本约定 ✍正文 Printer&Parser Formatter 时间日期格式化 Date类型 代码示例 JSR 310类型 整合DateTimeFormatter ...
- Spring MVC深入学习
一.MVC思想 MVC思想简介: MVC并不是java所特有的设计思想,也不是Web应用所特有的思想,它是所有面向对象程序设计语言都应该遵守的规范:MVC思想将一个应用部分分成三个基本部 ...
随机推荐
- JQuery-跑马灯(文字无缝向上翻动-封装)
转载自他人:https://blog.csdn.net/z69183787/article/details/12857587 (function($){ $.fn.extend({ &qu ...
- 【leetcode】987. Vertical Order Traversal of a Binary Tree
题目如下: Given a binary tree, return the vertical order traversal of its nodes values. For each node at ...
- POJ 2387 Til the Cows Come Home (dijkstra模板题)
Description Bessie is out in the field and wants to get back to the barn to get as much sleep as pos ...
- 【Flutter学习】可滚动组件之ScrollView
一,概述 ScrollView 是一个带有滚动的视图组件. 二,组成部分 ScrollView 由三部分组成: Scrollable - 它监听各种用户手势并实现滚动的交互设计.可滚动Widget都直 ...
- 【软工项目Beta阶段】第11周Scrum会议博客
第十一周会议记录 小组GitHub项目地址https://github.com/ouc-softwareclass/OUC-Market 小组Issue地址https://github.com/ouc ...
- JavaScript实现注册时检查邮箱,名称,密码等是否符合规则
大概实现了,用户名是否存在,邮箱是否已注册,密码是否符合复杂度. //对用户名校验是否存在function checkname(){ //alert("checkname"); v ...
- oracle 中和mysql的group_concat有同样作用的写法
所有版本的oracle都可以使用select wm_concat(name) as name from user;但如果是oracle11g,使用select listagg(name, ',') w ...
- 查询事件状态,mysql查看事件是否开启,设置启动时自动开启方法
1.查看事件是否开启 SHOW VARIABLES LIKE 'event_scheduler' 2.设置当前事件开启 SET GLOBAL event_scheduler = 1; 或 SET GL ...
- numpy的函数使用
目录 注 help ,帮助 numpy.genfromtxt,导入文件 array,创建数组(1,2维数组) array,创建行列向量 numpy.shape,看numpy数据的行列信息 numpy. ...
- 响应式web开发的一些文章
CSS Device Adaptation:关注 W3C 建议的 CSS 设备适配标准. “在 CSS 中使用 LESS 实现更多的功能”(作者:Uche Ogbuji,developerWorks, ...