在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. android adapter 中添加OnClickListener事件

    public class SearchAutoAdapter extends BaseAdapter { private OnClickListener mOnClickListener; publi ...

  2. func_get_args  获取一个函数的所有参数

    func_get_args  获取一个函数的所有参数 {     $numargs = func_num_args(); //参数数量     echo "参数个数是: $numargs&l ...

  3. 10个实用的 Linux 网络和监控命令[转]

    本文列出了10个基础的每个Linux用户都应该知道的网络和监控命令.网络和监控命令类似于这些: hostname, ping, ifconfig, iwconfig, netstat, nslooku ...

  4. 认识Webpack

    认识Webpack   网上已经有不少Webpack教程入门教程了. 本文记录了我以我的方式方法.思路认识了解Webpack.从官方的Tutorial入手,不断提出问题.解决,一步一步认识Webpac ...

  5. 初识DIV+CSS

    div元素是用来为html文档内大声(block-level)的内容提供结构和背景的元素. css是Cascading Style Sheets(层叠样式表单)的缩写,是一种用来表现html或xml等 ...

  6. es数据恢复杂记

    kill -9或者断电等原因异常,es在重启后,会通过translog来进行数据恢复. 默认的恢复速度是较慢的,可以设置indices.recovery.current_streams:10增大恢复的 ...

  7. OI常用读入方式效率测试

    我来填坑了. 这次我用自己写的测试读入的程序来分别测试cin(不关闭流同步),scanf和读入优化的效率差别.   我们分别对三个阶段的数据量n进行测试,通过时间比对来观察性能的差异. n = 102 ...

  8. Java获得系统的外网IP

    关于如何获得系统外网IP?在网上找了好久,大多数解决方案都没法直接用,所以今天和大家分享一段获得外网IP的代码! import java.net.Inet4Address; import java.n ...

  9. R语言dplyr包初探

    昨天学了一下R语言dplyr包,处理数据框还是很好用的.记录一下免得我忘记了... 先写一篇入门的,以后有空再写一篇详细的用法. #dplyr learning library(dplyr) #fil ...

  10. scope_lock与lock_guard区别

    lock_guard:更加灵活的锁管理类模板,构造时是否加锁是可选的,在对象析构时如果持有锁会自动释放锁,所有权可以转移.对象生命期内允许手动加锁和释放锁. scope_lock:严格基于作用域(sc ...