0060 Spring MVC的数据类型转换--ConversionService--局部PropertyEditor--全局WebBindingInitializer
浏览器向服务器提交的数据,多是字符串形式,而有些时候,浏览器需要Date、Integer等类型的数据,这时候就需要数据类型的转换器
使用Spring的ConversionService及转换器接口
下面以字符串转Date为例:
<!DOCTYPE html>
<html>
<head>
<title>Spring MVC的数据类型转换</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<script type="text/javascript" src="resources/jquery-3.1.0.js"></script>
<script type="text/javascript" src="resources/json2.js"></script>
</head>
<body>
<form action="register" method="post">
姓名:<input type="text" name="name" /> <br><br>
生日:<input type="text" name="birth" /> <br><br> <!-- 浏览器提交的数据是表示日期的字符串,比如1980-2-3 -->
<input type="submit" value="提交" />
</form>
</body>
</html>
下面是实体类User
package net.sonng.mvcdemo.entity;
import java.util.Date;
public class User {
private String name;
private Date birth; //注意这个birth是Date,而不是String类型
//.......
}
下面是controller
package net.sonng.mvcdemo.controller;
import net.sonng.mvcdemo.entity.User;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
public class UserController {
@RequestMapping("/register")
public String register(User user,Model model){
model.addAttribute("user", user);
return "result";
}
}
部署运行,然后会出现400错误:The request sent by the client was syntactically incorrect.
接下来写个转换器:
package net.sonng.mvcdemo.converter;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.springframework.core.convert.converter.Converter;
public class StringToDateConverter implements Converter<String,Date>{ //实现Converter接口
private String datePattern;
public void setDatePattern(String pattern){
this.datePattern=pattern;
}
@Override
public Date convert(String date){
try{
SimpleDateFormat dateFormat=new SimpleDateFormat(this.datePattern);
return dateFormat.parse(date);
}catch(Exception ex){
ex.printStackTrace();
System.out.println("日期转换失败");
return null;
}
}
}
将其配置到applicationContext.xml中:
<mvc:annotation-driven conversion-service="conversionService" />
<bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean" >
<property name="converters" >
<list> <!-- 这里可以配置多个转换器 -->
<bean class="net.sonng.mvcdemo.converter.StringToDateConverter" p:datePattern="yyyy-MM-dd" />
</list>
</property>
</bean>
重新部署访问,成功
几个接口
- ConversionService:
- 这是Spring 类型转换体系的核心接口
- ConversionServiceFactoryBean
- 这个相当于是类型转换器的容器,里面可以配置很多个转换器
- 转换器接口:
- Converter<S,T>:最简单的转换器接口,将S类型转为T类型
- ConverterFactory<S,R>:将S类型转换为另一种类型T及其子类型R的转换器接口。将相同系列多个Converter封装到一起
- GenericConverter:相对于Converter接口,该接口会根据源类型与目标类型的上下文信息进行转换
使用局部的java.beans.PropertyEditor接口
该接口是Java SE中的接口,其核心功能是将字符串转为Java对象,只能用与字符串和Java对象的转换,不能识别到源类型及目标类型的上下文信息,不能实现高级转换逻辑
写一个转换类继承PropertyEditorSupport,该类实现了PropertyEditor接口
package net.sonng.mvcdemo.converter;
import java.beans.PropertyEditorSupport;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class DateEditor extends PropertyEditorSupport {
@Override
public void setAsText(String text){
SimpleDateFormat dateFormat=new SimpleDateFormat("yyyy-MM-dd");
try{
Date date=dateFormat.parse(text);
setValue(date);
}catch(ParseException e){
e.printStackTrace();
}
}
}
再在Controller中添加一个方法:
package net.sonng.mvcdemo.controller;
import java.util.Date;
import net.sonng.mvcdemo.converter.DateEditor;
import net.sonng.mvcdemo.entity.User;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
public class UserController {
@InitBinder /*该注解会在该Controller初始化的时候注册一个转换器(属性编辑器)*/
public void initBinder(WebDataBinder binder){ /*WebDataBinder是Spring提供的支持*/
binder.registerCustomEditor(Date.class, new DateEditor()); /*表示DateEditor的目标类型是Date*/
}
@RequestMapping("/register")
public String register(User user,Model model){
model.addAttribute("user", user);
return "result";
}
}
部署访问,ok
使用全局的PropertyEditor
上面一个示例中,用@InitBinder注解只是让自定义的PropertyEditor在当前Controller范围内使用,如果要在全局范围内使用,则需要写个类实现WebBindingInitializer接口,再将自定义的PropertyEditor注册在其中,再到applicationContext.xml中进行装配
写个WebBindingInitializer的实现类
package net.sonng.mvcdemo.converter;
import java.util.Date;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.support.WebBindingInitializer;
import org.springframework.web.context.request.WebRequest;
public class DateBindingInitializer implements WebBindingInitializer { //实现该接口
@Override
public void initBinder(WebDataBinder binder, WebRequest request) {
binder.registerCustomEditor(Date.class,new DateEditor()); //注册自定义的PropertyEditor
}
}
applicationContext.xml中配置该实现类
<!-- 《Spring MVC + MyBatis 企业应用实战》里面用的AnnotationMethodHandlerAdapter,实际测试下来无效,得用RequestMappingHandlerAdapter;并且要将<mvc:annotation-driven />写在下方,写在上面无效 -->
<!-- <bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter"> -->
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter" >
<property name="webBindingInitializer">
<bean class="net.sonng.mvcdemo.converter.DateBindingInitializer" />
</property>
<property name="cacheSeconds" value="0" />
</bean>
<mvc:annotation-driven /> <!-- 特别注意,这条配置要写在下方,写在上方无效 -->
这里参考:webBindingInitializer 在XML中无效
三者优先级
- @InitBinder
- ConversionService
- WebBindingInitializer
总结
这里写了三种配置转换器的方法:
----全局的ConversionService,实现三个转换器接口之一,再在xml中配置
----局部的PropertyEditor,在Controller中写个注册方法,再用@InitBinder注释
----全局的PropertyEditor,写个类实现 WebBindingInitializer接口,将写好的转换器注册到其中,然后到xml中配置,配置要特别注意用RequestMappingHandlerAdapter,并且要把<mvc:annotation-driven />写在下方
0060 Spring MVC的数据类型转换--ConversionService--局部PropertyEditor--全局WebBindingInitializer的更多相关文章
- 0061 Spring MVC的数据格式化--Formatter--FormatterRegistrar--@DateTimeFormat--@NumberFormat
Converter只完成了数据类型的转换,却不负责输入输出数据的格式化工作,日期时间.货币等虽都以字符串形式存在,却有不同的格式. Spring格式化框架要解决的问题是:从格式化的数据中获取真正的数据 ...
- Spring MVC 前后台数据交互
本文是转载文章,感觉比较好,如有侵权,请联系本人,我将及时删除. 原文网址地址:<Spring MVC 前后台数据交互> 1.服务端数据到客户端 (1)返回页面,Controller中方法 ...
- spring mvc 4数据校验 validator
注解式控制器的数据验证.类型转换及格式化——跟着开涛学SpringMVC http://jinnianshilongnian.iteye.com/blog/1733708Spring4新特性——集成B ...
- 【Spring学习笔记-MVC-10】Spring MVC之数据校验
作者:ssslinppp 1.准备 这里我们采用Hibernate-validator来进行验证,Hibernate-validator实现了JSR-303验证框架支持注解风格的验证.首先 ...
- Spring MVC防止数据重复提交
现实开发中表单重复提交的例子很多,就包括手上这个门户的项目也有这种应用场景,用的次数多,但是总结,这还是第一次. 一.基本原理 使用token,给所有的url加一个拦截器,在拦截器里面用java的UU ...
- Spring MVC防止数据重复提交(防止二次提交)
SpringMvc使用Token 使用token的逻辑是,给所有的url加一个拦截器,在拦截器里面用java的UUID生成一个随机的UUID并把这个UUID放到session里面,然后在浏览器做数据提 ...
- Spring MVC—模型数据,转发重定向,静态资源处理方式
Spring MVC处理模型数据 添加模型数据的方法 ModelAndView Map及Model SessionAttribute ModelAttribute Spring MVC转发和重定向 S ...
- Spring MVC 解决无法访问静态文件和"全局异常处理"
我们都知道,Spring MVC的请求都会去找controller控制器,若果我们页面中引入了一个外部样式,这样是没效果的, 我们引入样式的时候是通过<like href="...&q ...
- spring mvc fastJson 自定义类型转换(返回数据) 实现对ObjectId类型转换
json用的alibaba fastJson ValueFilter filter = new ValueFilter() { @Override public Object process(Obje ...
随机推荐
- angular学习笔记(十一)-表达式
本篇只要介绍angular表达式: 在之前的例子中,我们多半是直接把数据作为angular标识符的值,但其实可以使用表达式来做更多的事情: 比如: {{number}} 也可以是: {{number+ ...
- ny495 少年 DXH
少年 DXH 时间限制:1000 ms | 内存限制:65535 KB 难度:2 描述 大家都知道,DXH 幼时性格怪癖,小朋友都不喜欢和他玩,这种情况一直到 DXH 的少年时期也没有改变.少 ...
- python+xpath+requests爬取维基百科历史上的今天
import requests import urllib.parse import datetime from lxml import etree fhout = open("result ...
- shadowshocks下载地址
https://github.com/shadowsocks/shadowsocks-windows/releases
- Django 缓存、信号
Reference: http://www.cnblogs.com/lianzhilei/p/6365877.html 缓存 由于Django是动态网站,所有每次请求均会去数据进行相应的操作,当程序访 ...
- Unity3d中使用摄像机制作实时显示小地图
Unity3d中使用摄像机制作实时显示小地图,以之前的tank为例.开始制作之前场景中物体如图. 开始制作,步骤1:新建一个camera及一个plane.对齐位置,将camera改名为camera_U ...
- NFS服务的端口分配
常规的一些NFS服务设置我们已经了解了.那么对于端口问题,很多朋友并不是很清楚.这里我们就来详细介绍一下端口的分配.portmapper在NFS服务启动的时候给每一个NFS服务分配了一个动态的端口,如 ...
- 利用JavaScript计算引擎进行字符串公式运算
1.通过js计算引擎计算(java自带) 2.计算公式除了支持基本的方法之外还支持简单js脚本分支计算 3.通过设定map传入参数 4.默认返回最后一个计算结果,如果需返回特定值,将变量补写在公式最后 ...
- ansible register when: result | succeeded when: item.rc != 0
ansible register 这个功能非常有用.当我们需要判断对执行了某个操作或者某个命令后,如何做相应的响应处理(执行其他 ansible 语句),则一般会用到register . 举个例子: ...
- Struts2- 设置默认拦截器
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE struts PUBLIC "- ...