在SpringMVC中,根据请求方法签名不同,将请求消息中的消息以一定的方式转换并绑定到请求方法的参数中,在请求信息到达真正调用处理方法的这一段时间内,SpringMVC还会完成很多其他的工作,包括了请求信息转换,数据转换,数据格式化以及数据效验;
      下面的内容分为三部分,数据转换,数据格式化和数据校验;
        数据转换:我们知道,有时候数据之间不同的情况是有出现的,像是date数据类型和String数据类型的转换;这个时候就需要我们来自定义编写一个转换器来进行转换数据类型了,其中,又有三种数据类型转换器,分别是ConversionService装配的自定义转换器;@InitBinder装配的自定义编辑器;通过WebBindingInitializer接口装配的全局自定义编辑器;下面一一进行介绍;
        ConversionService装配的自定义转换器;这种转换器主要是通过实现Converter接口来实现的,并在XML中进行配置,便可以在任何控制器的处理方法中使用这个转换器了,我给它的定义是默认的转换器;
        下面是代码块;

<h3>注册页面</h3>
<form action = "register" method = "post">
<table>
<tr>
<td><label>登录名</label></td>
<td><input type = "text" id = "loginname" name = "loginname"></td>
</tr>
<tr>
<td><label>生日:</label></td>
<td><input type = "text" id = "birthday" name = "birthday"></td>
</tr>
<tr>
<td><input id = "submit" type = "submit" value = "登录"></td>
</tr>
</table>
</form>

  registerForm.jsp是一个简单的注册页面,其传递一个登录名和一个用户的生日信息;

public clas User implements Serializable{
private String loginname;
private Date birthday;
public User(){
super();
}
public String getLoginname(){
return loginname;
}
public void setLoginname(){
this.loginname = loginname;
}
public Date getBirthday(){
return birthday;
}
public void setBirthday(Date birthday){
this.birthday = birthday;
}

  下面是控制器

@Controller
public class UserController{
private static final Log logger = LogFactory.getLog(UserController.class);
@RequestMapping(value = "/{formName}")
public String loginForm(@PathVariable String formName){
return formName;
}
@RequestMapping(value = "/register",method = RequestMethod.POST)
public String register(@ModelAttribute User use, Model model){
logger.info(user);
model.addAttribute("user",user);
return "success";
}
}

  接下来,开发自定义的转换器,将传递的字符串转换成Date类型;

public class StringToDateConverter implements Converter<String,Date>{
private String datePattern;
public void setDatePattern(String datePattern){
this.datePattern = datePattern;
}
@Override
public Date convert(String date){
try{
SimpleDateFormat dateFormat = new SimpleDateFormat(this.datePattern);
return dateFormat.parse(date);
}catch(Exception e){
e.printStackTrace();
System.out.println("日期转换失败");
return null;
}
}
}

  在springmvc-config.xml中加入自定义字符转换器;

<mvc:annotation-driven conversion-service = "conversionService"/>
<bean id = "conversionService"
class = "org.springframework.context.support.ConversionServiceFactoryBean">
<property name= "converters">
<list>
<bean class = "org.fkit.converter.StringToDateConverter"
p:datePattern = "yyyy-MM-dd"/></bean>
</list>
</property>
</bean>

  在success.jsp界面中的代码:

<body>
登录名:${requestScope.user.loginname}<br>
生日:<fmt:formaDate value = "${requestScope.user.birthday}"
pattern = "yyyy年MM月dd日"/><br>
</body>

  接下来是@InitBinder自定义编辑转换器;这个编辑器是通过在Controller中注册自定义编辑器来实现的;先让我们来编写一个编辑转换器,然后用@InitBinder来注入到Controller中;

public class DateEditor extends PropertyEditorSupport{
@Override
public void setAsText(String text) throws IllegalArgumentException{
SimpleDateFormat dateFormat = new SimpleDateFormaat("yyyy-MM-dd");
try{
Date date = dateFormat.parse(text);
setValue(date);
}catch(ParseException e){
e.printStackTrace();
}
}
}

  下面是注入转换器的控制器;

@InitBinder
public void initBinder(WebDataBinder binder){
binder.registerCustomEditor(Date.class,new DateEditor());
}

  接下来是全局自定义编辑转换器;通过实现WebBindingInitiallizer接口来实现;

public class DateBindingInitializer implements WebBindingInitializer{
@Override
public void initBinder(WebDataBinder binder,WebRequest request){
binder.registerCustomEditor(Date.class,new DateEditor());
}
}

  在springmvc-config.xml文件中配置全局的自定义编辑器;

<bean
class = "org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
<property name = "webBindingInitializer">
<bean class = "org.fkjava.binding.DateBindingInitializer"/>
</property>
</bean>

  

在这三种转换器中,优先顺序分别为
    1,查询通过@InitBinder装配的自定义编辑器;
    2,查询通过ConversionService装配的自定义转换器;
    3,查询通过WebBindingInitializer接口装配的全局自定义编辑器;
数据格式化;
我们前面提到的Converter转换器进行源类型对象到目标类型对象的转换,Spring的转换器并不承担输入以及输出信息格式化的工作;所以也就是说,我们接下来要的讲的格式化,是指不仅进行了信息的转换,同时也进行了信息的格式化工作,通过Formatter来实现,同时还有一种注解的方式;
先做一个Formatter格式器;

public class DateFormatter implements Formatter<Date>{
private String datePattern;
private SimpleDateFormat dateFormat;
public DateFOrmatter(String datePattern){
this.datePattern = datePattern;
this.dateFormat = new SimpleDateFormat(datePattern);
}
@Override
public String print(Date date,Locale locale){
return dateFormat.format(date);
}
@Override
public Date parse(String source,Locale locale) throws ParseException{
try{
return dateFormat.parse(source);
}catch(Exception e){
throw new IllegalArgumentException();
}
}
}

  接下来再springmvc-config.xml中装配自定义格式化转换器;

<mvc:annotation-driven conversion-service = "coversionService"/>
<bean id = "conversionService"
class = "org.springframework.format.support.FormattingConversionServiceFactoryBean">
<property name = "formatters">
<list>
<bean class = "org.fkit.formatter.DateFormatter" c:_0 = "yyyy-MM-dd"/>
</list>
</property>
</bean>

  接下来,如果要使用org.springframework.format.datetime包中提供的DateFormatter实现类完成字符串到对象的转换,则只需要在配置文件中配置就可以了。

<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>

  使用FormatterRegistrar注册Formatter;这个是将FormatterRegistrar作为接口来实现,所以在配置是不需要再注册任何Formatter了,而是注册Registrar;

<mvc:annotation-driven conversion-service = "conversionService"/>
<bean id = "dateFormatter" class = "org.fkit.formatter.DateFormatter" c:_0 = "yyyy-MM-dd"/>
<bean id = "conversionService"
class = "org.spirngframework.format.support.FormattingConversionServiceFactoryBean">
<set>
<bean class = "org.fkit.formatter.MyFormatterRegistrar"
p:dateFormatter-ref = "dateFormatter"/>
</set>
</property>
</bean>

  也可以通过注解来实现数据的格式化;

<h3>测试表单数据格式化</h3>
<form action = "test" method = "post">
<table>
<tr>
<td><label>日期类型:</label></td>
<td><input type = "text" id = "birthday" name = "brithday"></td>
</tr>
<tr>
<td><label>整数类型:</label></td>
<td><input type = "text" id = "total" name = "total"></td>
</tr>
<tr>
<td><label>百分数类型:</label></td>
<td><input type = "text" id = "discount" name = "discount"></td>
</tr>
<tr>
<td><label>货币类型:</label></td>
<td><input type = "text" id = "money" name = "money"></td>
</tr>
<tr>
<td><input id = "submit" type = "submit" value = "提交"></td>
</tr>
</table>
</form>

  这里的注解是用在模型数据中的;

public class User 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;
//省略set/get方法
}

  下面是控制器;

@Controller
public class FormatterController{
private static final Log logger = LogFactory.getLog(FormatterController.class);
@RequestMapping(value = "/{formName}")
public String loginForm(@PathVariable String formName){
return formName;
}
@RequestMapping(value = "/test",method = RequestMethod.POST)
public String test(
@ModelAttribute User user;
Model model){
logger.info(user);
model.addAttribute("user",user);
return "success";
}
}

  success.jsp代码

<@ taglib prefix = "form" uri = "http://www.springframework.org/tags/form" %>
<h3>测试表单数据格式化</h3>
<form:form modelAttribute = "user" method = "post" action = "">
<table>
<tr>
<td>日期类型:</td>
<td><form:input path = "birthday"/></td>
</tr>
<tr>
<td>整数类型:</td>
<td><form:input path = "total"/></td>
</tr>
<tr>
<td>百分数类型:</td>
<td><form:input path = "discount"/></td>
</tr>
<tr>
<td>货币类型:</td>
<td><form:input path = "money"/></td>
</tr>
</table>
</form:form>

  而这种自动装配是不需要特别配置的,只要默认的就行;

<mvc:annotation-driven/>
  接下来是数据校验的;
  数据校验有两种方法,一个是Validation校验,一个是JSR3.0;测试Spring的Validation校验;

<@ taglib prefix = "form" uri = "http://www.springframework.org/tags/form" %>
<html>
<head>
</head>
<body>
<form:form modelAttribute = "user" method = "post" action = "login">
<table>
<tr>
<td>登录名:</td>
<td><form:input path = "loginname"></td>
<td><form:errors path = "loginname" cssStyle = "color:red"/></td>
</tr>
<tr>
<td>密码:</td>
<td><form:input path = "password"></td>
<td><form:errors path = "password" cssStyle = "color:red"/></td>
</tr>
<tr>
<td><input type = "submit" value = "提交"/></td>
</tr>
</table>
</form:form>
</body>
</html>

  再写一个Validator类来进行校验,称为校验器;

@Repository("userValidator")
public class UserValidator implements Validator{
@Override
public boolean supports(Class<?> clazz){
return user.class.isAssignableFrom(clazz);
}
@Override
public void validate(Object target,Errors errors){
ValidationUtils.rejectIfEmpty(errors, "loginname", null, "登录名不能为空");
ValidationUtils.rejectIfEmpty(errors, "password", null, "密码不能为空");
User user = (User)target;
if(user.getLoginname().length() > 10){
errors.rejectValue("loginname",null,"用户名不能超过10个字符");
}
if(user.getPassword() != null
&& !user.getPassword().equals("")
&& user.getPassword().length() < 6){
errors.rejectValue("password",null,"密码不能小于6位");
}
}
}

  通过实现Validator接口来实现校验器;然后只需要在控制器中注入校验器即可,采用对象的方式来实现;

@Autowired
@Qualifier("UserValidator")
private UserValidator userValidator;
@RequestMapping(value = "/login",method = RequestMethod.POST)
public String login(
@ModelAttribute User user,
Model model,
Errors errors){
logger.info(user);
model.addAttribute("user",user);
userValidator.validate(user,errors);
if(errors.hasErrors()){
return "loginForm";
}
return "success";
}

  JSR3.0的话就是各种封装好的注解;同样是用在模型数据类中;

public class User implements Serializable{
@Notblank(message = "登录名不能为空")
private String loginname;
@NotBlank(message = "密码不能为空")
@Length(min = 6,max = 8,message = "密码长度必须在6到8之间")
private String password;
@NotBlank(message = "用户名不能为空")
private String username;
@Range(min = 15,max = 60,message = "年龄必须在15岁到60岁之间")
private int age;
@Email(message = "必须是合法的邮箱地址")
private String email;
@DateTimeFormate(pattern = "yyyy-MM-dd")
@Past(message = "生日必须是一个过去的日期")
private Date birthDate;
}

  在控制器中只需要在引入模型数据之前做一下@Valid就可以了

@RequestMapping(value = "/login",method = RequestMethod.POST)
public String login(
@Valid @ModelAttribute User user,
Errors errors,
Model model){
logger.info(user);
if(errors.hasErrors())
return "regsiterForm";
model.addAttribute("user",user);
return "success";
}

  

SpringMVC的数据转换,格式化和数据校验的更多相关文章

  1. SpringMVC——类型转换和格式化、数据校验、客户端显示错误消息

    在介绍类型转换和格式化之前,我首先来介绍 <mvc:annotation-driven />. 需要导入的 schema: xmlns:mvc="http://www.sprin ...

  2. SpringMVC框架下数据的增删改查,数据类型转换,数据格式化,数据校验,错误输入的消息回显

    在eclipse中javaEE环境下: 这儿并没有连接数据库,而是将数据存放在map集合中: 将各种架包导入lib下... web.xml文件配置为 <?xml version="1. ...

  3. SpringMVC框架07——服务器端JSR303数据校验

    1.数据校验概述 数据校验分为客户端校验和服务器端校验,客户端主要是通过过滤正常用户的误操作,是第一道防线,一般使用JavaScript代码实现.但是只有客户端校验是不够的,攻击者可以绕过客户端验证直 ...

  4. SpringMVC中的 JSR 303 数据校验框架说明

    JSR 303 是java为Bean数据合法性校验提供的标准框架,它已经包含在JavaEE 6.0中. JSR 303 通过在Bean属性上标注类似于@NotNull.@Max等标准的注解指定校验规则 ...

  5. SpringMVC的拦截器和数据校验

    SpringMVC拦截器 什么是拦截器:Spring MVC中的拦截器(Interceptor)类似于Servlet中的过滤器(Filter),它主要用于拦截用户请求并作相应的处理.例如通过拦截器可以 ...

  6. 第6章 Spring MVC的数据转换、格式化和数据校验

    使用ConversionService转换数据 <%@ page language="java" contentType="text/html; charset=U ...

  7. SpringMVC 数据转换 & 数据格式化 & 数据校验

    数据绑定流程 1. Spring MVC 主框架将 ServletRequest 对象及目标方法的入参实例传递给 WebDataBinderFactory 实例,以创建 DataBinder 实例对象 ...

  8. SpringMVC——数据转换 & 数据格式化 & 数据校验

    一.数据绑定流程 1. Spring MVC 主框架将 ServletRequest 对象及目标方 法的入参实例传递给 WebDataBinderFactory 实例,以创 建 DataBinder ...

  9. SpringMVC的数据转换&&数据格式化&&数据校验

    1 SpringMVC的数据绑定流程 SpringMVC将ServletRequest对象及目标方法的入参实例传递给WebDataBinderFactory实例,以创建DataBinder实例对象. ...

随机推荐

  1. php加入环境变量

    一.配置变量 右击计算机-属性-高级系统设置-环境变量-系统变量-双击path,编辑,将php的文件夹路径添加到后面,我是:D:\wamp64\bin\php\php5.6.25 二.测试 当没有加入 ...

  2. spring使用redis做缓存

    缓存 什么是缓存? 在高并发下,为了提高访问的性能,需要将数据库中 一些经常展现和不会频繁变更的数据,存放在存取速率更快的内存中.这样可以 降低数据的获取时间,带来更好的体验 减轻数据库的压力 缓存适 ...

  3. #pragma once 与 #ifndef 解析

    转自:http://www.cnblogs.com/hokyhu/archive/2009/03/30/1425604.html 为了避免同一个文件被include多次,C/C++中有两种方式,一种是 ...

  4. SpringMVC环境搭建---xml版及注解版

    一.建立 JavaWeb 项目(基于Intellij 14.0.3搭建) 1.建立一个 Java 项目,在项目下新建一个文件夹 webapp ,然后在该文件夹下新建一个 WEB-INF 文件夹: 2. ...

  5. Apache中的gzip压缩作用及配置

    gzip会对文本资源进行压缩,一般能节省40%的大小,二进制内容不需要开启Gzip压缩,因为这些文件是已经压缩过的,如果再进行gzip压缩可能反而会增加其大小,并且空耗cpu资源啊. 静态资源一般都会 ...

  6. ABP官方文档翻译 3.2 值对象

    值对象 介绍 值对象基类 最佳实践 介绍 "展现领域描述性层面且没有概念性身份的对象称之为值对象."(Eric Evans). 和实体相反,实体有身份标示(Id),值对象没有身份标 ...

  7. 前端-Useful Js Plugins

    Validform.min.js:提供对表单的验证.提交等功能,具体可查阅相关文档,@Validform 示例: $("#id").Validform() ; WdatePicke ...

  8. 深入理解Java内存模型之系列篇[转]

    原文链接:http://blog.csdn.net/ccit0519/article/details/11241403 深入理解Java内存模型(一)——基础 并发编程模型的分类 在并发编程中,我们需 ...

  9. BZOJ 3697: 采药人的路径 [点分治] [我想上化学课]

    传送门 题意: 路径有$-1,1$两种权值,求有多少路径满足权值和为$0$且有一个点将路径分成权值和为$0$的两段 第四节课本来想去上化学,然后快上课了这道题还没调出来.....可恶我想上化学 昨天两 ...

  10. HDU 4333 Revolving Digits [扩展KMP]【学习笔记】

    题意:给一个数字,每一次把它的最后一位拿到最前面,一直那样下去,分别求形成的数字小于,等于和大于原来数的个数. SAM乱搞失败 当然要先变SS了 然后考虑每个后缀前长为n个字符,把它跟S比较就行了 如 ...