zoukankan      html  css  js  c++  java
  • SpringMVC入门学习(五)----SpringMVC自定义类型转换器

    1、转换器的概述

    实际上在SpringMVC框架中,框架本身就内置了很多类型转换器,这些默认的类型转换器,可以将String类型的数据,自动转换为相应类型的数据。比如在前面的各种演示案例中,表单提交的无论是int还是double类型的请求参数,通过默认转换器均可直接接收到相应类型的相应数据,而非接收到String再手动转换,都是会自动帮你转换。这些默认的转换器就在包 org.springframework.core.convert.converter 下,如图所示:

    image

    但是有的时候内置的类型转换器不足够满足业务需求,因为默认转换器并不是可以将用户提交的String转换为所有用户需要的类型。此时,就需要自定义类型转换器了。例如,在Spring MVC的默认类型转换器中,没有日期类型的转换器,因为日期的格式太多。若要使表单中提交的日期字符串,被处理器方法形参直接接收为日期类型,则需要自定义类型转换器了,否则肯定会报错。下面就来学习一下怎么操作的。

    2、实现Converter接口

    依旧使用前面的提交Book举例,首先创建一个实现Converter接口的DateConverter实现类,代码如下:

    package com.thr.convert;
     
    import org.springframework.core.convert.converter.Converter;
    import java.time.LocalDate;
    import java.time.format.DateTimeFormatter;
     
    /**
     * 自定义转换器
     */
    //@Component
    public class DateConverter implements Converter<String, LocalDate> {
        //Java8 的日期格式化器
        DateTimeFormatter formatter=DateTimeFormatter.ofPattern("yyyy-MM-dd");
        public LocalDate convert(String source) {
            // 根据格式化器将String类型解析为LocalDate类型
            return LocalDate.parse(source, formatter);
        }
    }
    

    上面是在自定义的参数类型转换器中,将一个前台传来的 String 转为 LocalDate 对象。

    然后我们在Book类添加一个日期类型的属性,用来表示图书的出版日期,Book实体类代码如下:

    public class Book {
        //书的ID
        private Integer id;
        //书名
        private String name;
        //出版社
        private String publisher;
        //图书出版日期
        private LocalDate publishDate;
     
        //getter,setter和toString省略
    }
    

    接下来,在 SpringMVC 的配置文件(spring-mvc.xml)中配置相关的 Bean使之生效。

    <!-- 注册自定义转换器 -->
    <bean id="dateConverter" class="com.thr.convert.DateConverter"/>
    <!-- 注册类型转换服务bean -->
    <bean id="conversionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
        <property name="converters">
            <set>
                <ref bean="dateConverter"/>
            </set>
        </property>
    </bean>
    <!-- 配置MVC注解驱动。-->
    <mvc:annotation-driven conversion-service="conversionService"/>
    

    创建用于提交图书信息的index.jsp页面,具体代码如下:

    <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" isELIgnored="false" %>
    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title>首页</title>
    </head>
    <body>
    <form action="${pageContext.request.contextPath}/book" method="post">
        <table>
            <tr>
                <td>图书ID:</td>
                <td><input type="text" name="id"></td>
            </tr>
            <tr>
                <td>图书名称:</td>
                <td><input type="text" name="name"></td>
            </tr>
            <tr>
                <td>出版社:</td>
                <td><input type="text" name="publishingHouse"></td>
            </tr>
            <tr>
                <td>图书出版日期:</td>
                <td><input type="date" name="publishDate"></td>
            </tr>
            <tr>
                <td colspan="2">
                    <input type="submit" value="提交">
                </td>
            </tr>
        </table>
    </form>
    </body>
    </html>
    

    image

    image

    3、使用@InitBinder注解(推荐)

    当然也可以不在XML中配置类型转换服务,而是使用@InitBinder注解来实现,推荐这种方式。在需要日期转换的 Controller 中使用 SpringMVC 的注解 @InitBinder 和 Spring 自带的 WebDateBinder 类来操作,WebDataBinder 是用来绑定请求参数到指定的属性编辑器。由于前端传到 Controller 里的值是 String 类型的,当往 Model 里 Set这个值的时候,如果 set 的这个属性是个对象,Spring 就会去找到对应的 editor 进行转换,然后再 SET 进去。注意:@InitBinder用于在@Controller中标注的方法,表示为当前控制器注册一个属性编辑器,只对当前的Controller有效。这个方法会在控制器中其他方法之前调用,这样就可以预先处理数据。

    //@Controller:表示一个Controller实例,该实例由Spring容器管理
    @Controller
    public class BookController {
    
        //添加initBinder注解
        @InitBinder
        public void initBinder(WebDataBinder binder) {
            //注册原类型和目标类型的转换格式
            binder.registerCustomEditor(LocalDate.class, new PropertyEditorSupport() {
                @Override
                public void setAsText(String text) throws IllegalArgumentException {
                    System.out.println("-----进入了initBinder()----");
                    setValue(LocalDate.parse(text, DateTimeFormatter.ofPattern("yyyy-MM-dd")));
                }
            });
        }
        //配置请求的地址
        @RequestMapping(value = "book", method = RequestMethod.POST)
        public String getInfo(Book book) {
            System.out.println(book.getId());
            System.out.println(book.getName());
            System.out.println(book.getPublisher());
            System.out.println(book.getPublishDate());
            //成功后跳转的页面
            return "success";
        }
    }
    
    作者: 唐浩荣
    本文版权归作者和博客园共有,欢迎转载,但是转载需在博客的合适位置给出原文链接,否则保留追究法律责任的权利。
  • 相关阅读:
    go语言学习笔记四(函数、包和错误处理)
    objection内存漫游实战
    脱壳工具FRIDA-DEXDump
    jsdom 用法技巧
    关于adb安装指定版本
    ob混淆
    js原型链hook
    js逆向核心:扣代码2
    ssl_logger捕获得物app双向验证数据
    js逆向核心:扣代码
  • 原文地址:https://www.cnblogs.com/tanghaorong/p/14529273.html
Copyright © 2011-2022 走看看