浏览器向服务器提交的数据,多是字符串形式,而有些时候,浏览器需要Date、Integer等类型的数据,这时候就需要数据类型的转换器

使用Spring的ConversionService及转换器接口

下面以字符串转Date为例:

  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <title>Spring MVC的数据类型转换</title>
  5. <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  6. <script type="text/javascript" src="resources/jquery-3.1.0.js"></script>
  7. <script type="text/javascript" src="resources/json2.js"></script>
  8. </head>
  9. <body>
  10. <form action="register" method="post">
  11. 姓名:<input type="text" name="name" /> <br><br>
  12. 生日:<input type="text" name="birth" /> <br><br> <!-- 浏览器提交的数据是表示日期的字符串,比如1980-2-3 -->
  13. <input type="submit" value="提交" />
  14. </form>
  15. </body>
  16. </html>

下面是实体类User

  1. package net.sonng.mvcdemo.entity;
  2. import java.util.Date;
  3. public class User {
  4. private String name;
  5. private Date birth; //注意这个birth是Date,而不是String类型
  6. //.......
  7. }

下面是controller

  1. package net.sonng.mvcdemo.controller;
  2. import net.sonng.mvcdemo.entity.User;
  3. import org.springframework.stereotype.Controller;
  4. import org.springframework.ui.Model;
  5. import org.springframework.web.bind.annotation.RequestMapping;
  6. @Controller
  7. public class UserController {
  8. @RequestMapping("/register")
  9. public String register(User user,Model model){
  10. model.addAttribute("user", user);
  11. return "result";
  12. }
  13. }

部署运行,然后会出现400错误:The request sent by the client was syntactically incorrect.

接下来写个转换器:

  1. package net.sonng.mvcdemo.converter;
  2. import java.text.SimpleDateFormat;
  3. import java.util.Date;
  4. import org.springframework.core.convert.converter.Converter;
  5. public class StringToDateConverter implements Converter<String,Date>{ //实现Converter接口
  6. private String datePattern;
  7. public void setDatePattern(String pattern){
  8. this.datePattern=pattern;
  9. }
  10. @Override
  11. public Date convert(String date){
  12. try{
  13. SimpleDateFormat dateFormat=new SimpleDateFormat(this.datePattern);
  14. return dateFormat.parse(date);
  15. }catch(Exception ex){
  16. ex.printStackTrace();
  17. System.out.println("日期转换失败");
  18. return null;
  19. }
  20. }
  21. }

将其配置到applicationContext.xml中:

  1. <mvc:annotation-driven conversion-service="conversionService" />
  2. <bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean" >
  3. <property name="converters" >
  4. <list> <!-- 这里可以配置多个转换器 -->
  5. <bean class="net.sonng.mvcdemo.converter.StringToDateConverter" p:datePattern="yyyy-MM-dd" />
  6. </list>
  7. </property>
  8. </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接口

  1. package net.sonng.mvcdemo.converter;
  2. import java.beans.PropertyEditorSupport;
  3. import java.text.ParseException;
  4. import java.text.SimpleDateFormat;
  5. import java.util.Date;
  6. public class DateEditor extends PropertyEditorSupport {
  7. @Override
  8. public void setAsText(String text){
  9. SimpleDateFormat dateFormat=new SimpleDateFormat("yyyy-MM-dd");
  10. try{
  11. Date date=dateFormat.parse(text);
  12. setValue(date);
  13. }catch(ParseException e){
  14. e.printStackTrace();
  15. }
  16. }
  17. }

再在Controller中添加一个方法:

  1. package net.sonng.mvcdemo.controller;
  2. import java.util.Date;
  3. import net.sonng.mvcdemo.converter.DateEditor;
  4. import net.sonng.mvcdemo.entity.User;
  5. import org.springframework.stereotype.Controller;
  6. import org.springframework.ui.Model;
  7. import org.springframework.web.bind.WebDataBinder;
  8. import org.springframework.web.bind.annotation.InitBinder;
  9. import org.springframework.web.bind.annotation.RequestMapping;
  10. @Controller
  11. public class UserController {
  12. @InitBinder /*该注解会在该Controller初始化的时候注册一个转换器(属性编辑器)*/
  13. public void initBinder(WebDataBinder binder){ /*WebDataBinder是Spring提供的支持*/
  14. binder.registerCustomEditor(Date.class, new DateEditor()); /*表示DateEditor的目标类型是Date*/
  15. }
  16. @RequestMapping("/register")
  17. public String register(User user,Model model){
  18. model.addAttribute("user", user);
  19. return "result";
  20. }
  21. }

部署访问,ok

使用全局的PropertyEditor

上面一个示例中,用@InitBinder注解只是让自定义的PropertyEditor在当前Controller范围内使用,如果要在全局范围内使用,则需要写个类实现WebBindingInitializer接口,再将自定义的PropertyEditor注册在其中,再到applicationContext.xml中进行装配

写个WebBindingInitializer的实现类

  1. package net.sonng.mvcdemo.converter;
  2. import java.util.Date;
  3. import org.springframework.web.bind.WebDataBinder;
  4. import org.springframework.web.bind.support.WebBindingInitializer;
  5. import org.springframework.web.context.request.WebRequest;
  6. public class DateBindingInitializer implements WebBindingInitializer { //实现该接口
  7. @Override
  8. public void initBinder(WebDataBinder binder, WebRequest request) {
  9. binder.registerCustomEditor(Date.class,new DateEditor()); //注册自定义的PropertyEditor
  10. }
  11. }

applicationContext.xml中配置该实现类

  1. <!-- 《Spring MVC + MyBatis 企业应用实战》里面用的AnnotationMethodHandlerAdapter,实际测试下来无效,得用RequestMappingHandlerAdapter;并且要将<mvc:annotation-driven />写在下方,写在上面无效 -->
  2. <!-- <bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter"> -->
  3. <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter" >
  4. <property name="webBindingInitializer">
  5. <bean class="net.sonng.mvcdemo.converter.DateBindingInitializer" />
  6. </property>
  7. <property name="cacheSeconds" value="0" />
  8. </bean>
  9. <mvc:annotation-driven /> <!-- 特别注意,这条配置要写在下方,写在上方无效 -->

这里参考:webBindingInitializer 在XML中无效

三者优先级

  1. @InitBinder
  2. ConversionService
  3. WebBindingInitializer

总结

这里写了三种配置转换器的方法:

----全局的ConversionService,实现三个转换器接口之一,再在xml中配置

----局部的PropertyEditor,在Controller中写个注册方法,再用@InitBinder注释

----全局的PropertyEditor,写个类实现 WebBindingInitializer接口,将写好的转换器注册到其中,然后到xml中配置,配置要特别注意用RequestMappingHandlerAdapter,并且要把<mvc:annotation-driven />写在下方

0060 Spring MVC的数据类型转换--ConversionService--局部PropertyEditor--全局WebBindingInitializer的更多相关文章

  1. 0061 Spring MVC的数据格式化--Formatter--FormatterRegistrar--@DateTimeFormat--@NumberFormat

    Converter只完成了数据类型的转换,却不负责输入输出数据的格式化工作,日期时间.货币等虽都以字符串形式存在,却有不同的格式. Spring格式化框架要解决的问题是:从格式化的数据中获取真正的数据 ...

  2. Spring MVC 前后台数据交互

    本文是转载文章,感觉比较好,如有侵权,请联系本人,我将及时删除. 原文网址地址:<Spring MVC 前后台数据交互> 1.服务端数据到客户端 (1)返回页面,Controller中方法 ...

  3. spring mvc 4数据校验 validator

    注解式控制器的数据验证.类型转换及格式化——跟着开涛学SpringMVC http://jinnianshilongnian.iteye.com/blog/1733708Spring4新特性——集成B ...

  4. 【Spring学习笔记-MVC-10】Spring MVC之数据校验

    作者:ssslinppp       1.准备 这里我们采用Hibernate-validator来进行验证,Hibernate-validator实现了JSR-303验证框架支持注解风格的验证.首先 ...

  5. Spring MVC防止数据重复提交

    现实开发中表单重复提交的例子很多,就包括手上这个门户的项目也有这种应用场景,用的次数多,但是总结,这还是第一次. 一.基本原理 使用token,给所有的url加一个拦截器,在拦截器里面用java的UU ...

  6. Spring MVC防止数据重复提交(防止二次提交)

    SpringMvc使用Token 使用token的逻辑是,给所有的url加一个拦截器,在拦截器里面用java的UUID生成一个随机的UUID并把这个UUID放到session里面,然后在浏览器做数据提 ...

  7. Spring MVC—模型数据,转发重定向,静态资源处理方式

    Spring MVC处理模型数据 添加模型数据的方法 ModelAndView Map及Model SessionAttribute ModelAttribute Spring MVC转发和重定向 S ...

  8. Spring MVC 解决无法访问静态文件和"全局异常处理"

    我们都知道,Spring MVC的请求都会去找controller控制器,若果我们页面中引入了一个外部样式,这样是没效果的, 我们引入样式的时候是通过<like href="...&q ...

  9. spring mvc fastJson 自定义类型转换(返回数据) 实现对ObjectId类型转换

    json用的alibaba fastJson ValueFilter filter = new ValueFilter() { @Override public Object process(Obje ...

随机推荐

  1. SDL2中文教程

    SDL2.0 Tutorial Index 原文地址:SDL 2.0 Tutorial Index Welcome! 下面的教程旨在为你提供一个SDL2.0以及c++中游戏设计和相关概念的介绍.在本教 ...

  2. Python中将字典转换为有序列表、无序列表的方法

    说明:列表不可以转换为字典 1.转换后的列表为无序列表 a = {'a' : 1, 'b': 2, 'c' : 3} #字典中的key转换为列表 key_value = list(a.keys()) ...

  3. python+spark程序代码片段

    处理如此的字符串: time^B1493534543940^Aid^B02CD^Aasr^B叫爸爸^Anlp^B{"domain":"com.abc.system.cha ...

  4. openldap 备份与导入 及相关问题

    摘要: 对openldap进行备份时,直接使用slapcat命令进行备份,使用ldapadd还原出现问题及解决. 介绍: 对openldap进行备份时,直接使用slapcat命令进行备份(如代码一), ...

  5. BAT-SVN自动更新代码目录

    1.安装“TortoiseSVN-1.7.15.25753-x64-svn-1.7.18.msi”. 2.“运行”->“cmd”->输入“svn help”->出现用说明代表正常,提 ...

  6. Android笔记(十一)第一个Fragment

    Fragment是碎片的意思,能够參照Activity来理解Fragment,由于它们都能包括布局,都有自己的生命周期. 以下我们要让主活动包括两个碎片,而且让两个碎片充满屏幕 1.首先,新建两个碎片 ...

  7. linux查找系统中占用磁盘空间最大的文件

    Q:下午有一客户磁盘空间占用很大,使用df查看磁盘剩余空间很小了,客户想知道是哪些文件占满了文件. Q1:在Linux下如何查看系统占用磁盘空间最大的文件? Q2:在Linux下如何让文件夹下的文件让 ...

  8. 【C#/WPF】图像数据格式转换时,透明度丢失的问题

    问题:工作中涉及到图像的数据类型转换,经常转着转着发现,到了哪一步图像的透明度丢失了! 例如,Bitmap转BitmapImage的经典代码如下: public static BitmapImage ...

  9. C语言 · 分数统计

    算法提高 分数统计   时间限制:1.0s   内存限制:512.0MB      问题描述 2016.4.5已更新此题,此前的程序需要重新提交. 问题描述 给定一个百分制成绩T,将其划分为如下五个等 ...

  10. 4G模块ME3760_V2 端口映射

    /dev/ttyUSB0      ECM        // ECM 口 /dev/ttyUSB1      /             //ECM口 /dev/ttyUSB2      AT    ...