Spring MVC学习总结(六):自定义类型转换

       在表单提交的任何数据类型全都是字符串类型,后台在接收到请求之后,Spring框架内部的HandlerAdapter 会默认进行数据类型转换。但是如果其中包含了非基本数据类型,例如在用户表单中需要用户的生日,则HandlerAdapter 无法将 String类型自动转换成 Date类型的,此时需要实现 Converter接口来辅助 Spring MVC完成数据类型转换。先来看不使用自定义的类型转换器的效果,实现步骤如下:

(1)创建实体类

public class User {
    private String name;
    private String password;
    private Integer age;
    private Date birthday;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public Date getBirthday() {
        return birthday;
    }

    public void setBirthday(Date birthday) {
        this.birthday = birthday;
    }

    @Override
    public String toString() {
        return "User{" +
                "name='" + name + '\'' +
                ", password='" + password + '\'' +
                ", age=" + age +
                ", birthday=" + birthday +
                '}';
    }
}

(2)在index.jsp中加入用户表单。


<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<form method="post" action="${pageContext.request.contextPath}/user/login">
    姓名:<input type="text" name="name"><br>
    密码:<input type="text" name="password"><br>
    年龄:<input type="text" name="age"><br>
    生日:<input type="text" name="birthday"><br>
    <input type="submit" value="提交">
</form>
</body>
</html>

(3)创建UserController类

@Controller
@RequestMapping("/user")
public class UserController {
    @RequestMapping("/login")
    public String login(User user){
        System.out.println(user);
        return "success";
    }
}

(4)success.jsp页面

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<h3>SUCCESS</h3>
</body>
</html>

启动项目,在页面输入信息并点击提交,此时在页面中输入的生日格式为1997/12/12。

但是如果输入1997-10-10,此时数据就会封装错误,如下:

Spring MVC中提供了Converter<S,T> ,可以将一种数据类型转换成另一种数据类型的接口,这里 S 表示源类型,T 表示目标类型。实现过程如下:

(1)自定义类型转换器,实现接口

public class MyDateConverter implements Converter<String, Date> {
    @Override
    public Date convert(String s) {
        if(s == null){
            throw new RuntimeException("日期数据为空");
        }
        DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
        try{
            return df.parse(s);
        }catch (Exception e){
            throw new RuntimeException("日期数据转换失败");
        }
    }
}

(2)在springmvc.xml中加入配置

<mvc:annotation-driven conversion-service="conversionServiceFactoryBean"></mvc:annotation-driven>
    <!--  注册自定义类型转换器  -->
    <bean id="conversionServiceFactoryBean" class="org.springframework.context.support.ConversionServiceFactoryBean">
        <property name="converters">
            <set>
                <bean class="com.yht.example1.utils.MyDateConverter"></bean>
            </set>
        </property>
    </bean>

此时再在页面输入1997-12-12,则运行成功,如下:

需要注意的是两种格式:1997/12/12和1997-12-12。前面介绍了Spring MVC框架可以自动将1997/12/12映射为pojo对象的日期类型,但是无法将1997-12-12进行映射,所以我们使用了自定义类型转换器来处理1997-12-12该格式的输入数据,但是当自定义的类型转换器起作用之后,原来的1997/12/12这种格式的日期则无法映射成功。我简单查看了一下ConversionServiceFactoryBean的源码,觉得问题出在set方法里,如下:

 我个人认为在配置文件中通过property对converters属性进行了赋值,而使得原来的Spring MVC中默认进行的类型转换操作被覆盖掉了。我使用的spring mvc中的jar包都是4.2.3版本,是否在低版本中该类的实现方式不同,还有待后续深入研究。

目前查阅了大量博客还没找到能够同时使用这两种格式的方案,如果有小伙伴找到了,可以评论,大家共同进步。

关于日期格式化,在Spring MVC中还有一个注解@DateTimeFormat(pattern = "yyyy-MM-dd"),只需要将该注解加在User类的birthday属性之上即可,如果里面pattern是yyyy-MM-dd,则支持1997-12-12格式。如果pattern是yyyy/MM/dd,则支持1997/12/12。

 

猜你喜欢

转载自blog.csdn.net/weixin_47382783/article/details/113574318