Spring MVC
数据绑定之日期转换
在Spring MVC中 具备强大的数据绑定,常用的数据类型都是可以直接在后台转换的
常见的数据绑定注解有:
1.@RequestParam,绑定单个请求数据,可以是URL中的数据,表单提交的数据或上传的文件;
2.@PathVariable,绑定URL模板变量值;
3.@CookieValue,绑定Cookie数据;
4.@RequestHeader,绑定请求头数据;
5.@ModelAttribute,绑定数据到Model;
6.@SessionAttributes,绑定数据到Session;
7.@RequestBody,用来处理Content-Type不是application/x-www-form-urlencoded编码的内容,例如application/json, application/xml等;
8.@RequestPart,绑定“multipart/data”数据,并可以根据数据类型进项对象转换;
这些都可以实现前台和后台的数据绑定,可以根据实际场景来使用具体的数据绑定注解。
但是今天要讲的是一些数据类型不能实现绑定,如:日期。
所以今天主要讲解的是 数据绑定之日期转换。
常用的日期转换有三种方式:
- POJO类属性添加@DateTimeFormat(pattern = “yyyy-MM-dd”)注解,可以实现string转换成Date类型。
- web层的开发添加@InitBinder注解,实现方法public void initBinder(WebDataBinder binder)。
- 在系统中加入一个全局类型转换器。
一个简单的例子
1、POJO类属性添加注解方式
1.1、web.xml配置
<!-- 前端控制器 DispatcherServlet -->
<servlet>
<servlet-name>SpringMVC</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!-- spring mvc 配置文件路径 如果不配置,默认是 /WEB-INF/[servlet-name]-servlet.xml -->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:SpringMVC.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>SpringMVC</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
1.2、SpringMVC配置
<!-- 定义控制器扫描包位置 -->
<context:component-scan base-package="com.wm.spring.MVC.controller" />
<!-- 视图解析器 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!-- prefix 前缀 suffix 后缀 -->
<property name="viewClass" value="org.springframework.web.servlet.view.JstlView" />
<property name="prefix" value="/WEB-INF/page/" />
<property name="suffix" value=".jsp" />
<property name="order" value="10" />
</bean>
1.3、POJO类
package com.wm.spring.MVC.POJO;
import java.util.Date;
import org.springframework.format.annotation.DateTimeFormat;
public class Employee {
private int empNum; // 员工号
private String empName; // 员工名
// 1、POJO类 中通过@DateTimeFormat来实现数据转换
@DateTimeFormat(pattern="yyyy-MM-dd")
private Date hiredDate; // 入职日期
public int getEmpNum() {
return empNum;
}
public void setEmpNum(int empNum) {
this.empNum = empNum;
}
public String getEmpName() {
return empName;
}
public void setEmpName(String empName) {
this.empName = empName;
}
public Date getHiredDate() {
return hiredDate;
}
public void setHiredDate(Date hiredDate) {
this.hiredDate = hiredDate;
}
public String toString() {
return "Employee [empNum=" + empNum + ", empName=" + empName
+ ", hiredDate=" + hiredDate + "]";
}
}
如果查询类使我们自己写,那么在属性前面加上@DateTimeFormat(pattern = “yyyy-MM-dd”) ,即可将String转换为Date类型。
1.4、controller
package com.wm.spring.MVC.controller;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView;
import com.wm.spring.MVC.POJO.Employee;
@Controller // 容器中注册控制器BEAN
public class FormHandleController {
@RequestMapping(value="login.do",method=RequestMethod.GET)
public ModelAndView getFormPage(HttpServletRequest request,HttpServletResponse response){
return new ModelAndView("login");
}
// Employee 类型 可以从表单中数据绑定,表单的名字是类的属性,才能一一绑定
@RequestMapping(value="doLogin.do",method=RequestMethod.POST)
public ModelAndView doLogin(HttpServletRequest request,HttpServletResponse response, Employee employee){
String empNum = request.getParameter("empNum");
String hiredDate = request.getParameter("hiredDate");
System.out.println(hiredDate);
System.out.println(empNum);
System.out.println(employee);
return new ModelAndView("showFirst", "emp" , employee);
}
}
1.5、页面
页面:login.jsp
<body>
<div class="div0">
<form action="doLogin.do" method="post">
<div class="row">
<label>员工编号:</label>
<input type="text" name="empNum" />
</div>
<div class="row">
<label>员工姓名:</label>
<input type="text" name="empName" />
</div>
<div class="row">
<label>入职时间:</label>
<input type="date" name="hiredDate" />
</div>
<div class="row">
<input type="submit" />
<input type="reset" />
</div>
</form>
</div>
</body>
页面:showFirst.jsp – 用来展示结果
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE HTML>
<html>
<head>
<title>ShowFirst</title>
</head>
<body>
<h1>show first</h1>
<h2>your IP : ${ip }</h2>
<h2>empNum: ${emp.empNum }</h2>
<h2>empName: ${emp.empName }</h2>
<h2>hiredDate: ${emp.hiredDate }</h2>
</body>
</html>
1.6、测试结果
地址:http://localhost:8080/MySpring/login.do
提交
测试结果表明:使用注解@DateTimeFormat(pattern=”yyyy-MM-dd”),可以很好的绑定页面数据。
2、web层开发使用@InitBinder注解
web层控制器中
FormHandleController控制器中添加注解:@InitBinder
并且实现方法:public void initBinder(WebDataBinder binder)
在其中实现注册日期编辑器
// 2、web层 controller中 进行数据绑定
@InitBinder
public void initBinder(WebDataBinder binder){
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
// 严格限制日期转换
sdf.setLenient(false);
//true:允许输入空值,false:不能为空值
binder.registerCustomEditor(Date.class, new CustomDateEditor(sdf, true));
}
测试结果如上: 1.6测试结果
在系统中加入一个全局类型转换器
全局类型转换器类
首先定义一个全局类型转换器类DateConverter:
package com.wm.spring.MVC.service;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.springframework.core.convert.converter.Converter;
// 3、定义系统全局类型转换器
public class DateConverter implements Converter<String, Date>{
@Override
public Date convert(String source) {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
sdf.setLenient(false);
try {
return sdf.parse(source);
} catch (Exception e) {
System.out.println(e);
}
return null;
}
}
注册到配置文件SpringMVC.xml中
<!-- 配置 全局日期类型转换器 -->
<bean id="conversionService"
class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
<property name="converters" >
<list>
<bean class="com.wm.spring.MVC.service.DateConverter" />
</list>
</property>
</bean>
并且还要把全局日期转换器注册到驱动里面,不然不会生效
<!-- 配置全局日期类型转换器 -->
<mvc:annotation-driven conversion-service="conversionService" />
测试结果如上: 1.6测试结果
总结
第一种方式是最简单的,但是也要根据实际情况去实现,如果你只有开发web层代码的权限,这第二、三种方式比较适合。
第二种方式比较冗余,因为你要为每一个controller控制器都注册一个日期转换器,所以比较麻烦,也是最不常用的。
第三种方式,定义一个系统全局日期转换器,配置简单,实现也是比较简单的。