zoukankan      html  css  js  c++  java
  • spring 转换器和格式化

      Spring总是试图用默认的语言区域将日期输入绑定 到java.util.Date。假如想让Spring使用不同的日期样 式,就需要用一个Converter(转换器)或者 Formatter(格式化)来协助Spring完成。

    一. Converter

      利用Converter进行日期的格式化

      Spring的Converter是一个可以将一种类型转换成另 一种类型的对象。例如,用户输入的日期可能有许多种 形式,如“December 25,2014”“12/25/2014”“2014-12- 25” ,这些都表示同一个日期。默认情况下,Spring会 期待用户输入的日期样式与当前语言区域的日期样式相 同。例如,对于美国的用户而言,就是月/日/年格式。 如果希望Spring在将输入的日期字符串绑定到Date时, 使用不同的日期样式,则需要编写一个Converter,才能 将字符串转换成日期。

    1. 日期格式化需要的类:org.springframework.core.convert.converter.Converter

     需要实现org.springframework.core.convert.converter.Converter的接口

    public interface Converter<S, T

    例如

    package converter;
    
    import java.text.ParseException;
    import java.text.SimpleDateFormat;
    import java.util.Date;
    import org.springframework.core.convert.converter.Converter;
    //必须实现 Converter
    public class StringToDateConverter implements Converter<String, Date> {
        private String datePattern;
    
        public StringToDateConverter(String datePattern) {
            this.datePattern = datePattern;
            System.out.println("instantiating .... converter with pattern:*" + datePattern);
        }
        // 转换日期格式
    @Override
    public Date convert(String s) { try { SimpleDateFormat dateFormat = new SimpleDateFormat(datePattern); dateFormat.setLenient(false); return dateFormat.parse(s); } catch (ParseException e) { // the error message will be displayed when using // <form:errors> throw new IllegalArgumentException("invalid date format. Please use this pattern"" + datePattern + """); } } }

    2. springmvc-cofing.xml配置

    <mvc:annotation-driven conversion-service="conversionService"/>
        <bean id="conversionService"
            class="org.springframework.context.support.ConversionServiceFactoryBean">
            <property name="converters">
                <list>
                    <bean class="converter.StringToDateConverter">
                        <constructor-arg type="java.lang.String"
                            value="MM-dd-yyyy" />
                    </bean>
                </list>
            </property>
        </bean>

    3.controller类

    package controller;
    
    import org.apache.commons.logging.Log;
    import org.apache.commons.logging.LogFactory;
    import org.springframework.ui.Model;
    import org.springframework.validation.BindingResult;
    import org.springframework.validation.FieldError;
    import org.springframework.web.bind.annotation.ModelAttribute;
    import org.springframework.web.bind.annotation.RequestMapping;
    import domain.Employee;
    
    @org.springframework.stereotype.Controller
    public class EmployeeController {
        private static final Log  logger = LogFactory.getLog(EmployeeController.class);
        
        @RequestMapping(value="employee_input")
        public String inputEmployee(Model model) {
            model.addAttribute(new Employee());
            return "EmployeeForm";
        }
        
        @RequestMapping(value="employee_save")
        public  String saveEmployee(@ModelAttribute Employee employee,BindingResult bindingResult,Model model) {
            if(bindingResult.hasErrors()) {
                FieldError fieldError = bindingResult.getFieldError();
                logger.info("Code:" + fieldError.getCode()
                + ", field:" + fieldError.getField());
            }
            // save  employee here
            model.addAttribute("employee",employee);
            
            return "EmployeeDetails";
        }
    }

    4.view视图

    <%@ taglib prefix="form" uri="http://www.springframework.org/ta
    gs/form" %>
    <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %
    >
    <!DOCTYPE html>
    <html>
    <head>
    <title>Add Employee Form</title>
    <style type="text/css">@import url("<c:url
    value="/css/main.css"/>");</style>
    </head>
    <body>
    <div id="global">
    <form:form commandName="employee" action="employee_save" method
    ="post">
    <fieldset>
    <legend>Add an employee</legend>
    <p>
    <label for="firstName">First Name: </label>
    <form:input path="firstName" tabindex="1"/>
    </p>
    <p>
    <label for="lastName">First Name: </label>
    <form:input path="lastName" tabindex="2"/>
    </p>
    <p>
    <!-- 打印错误 -->
    <form:errors path="birthDate" cssClass="error"/> </p> <p> <label for="birthDate">Date Of Birth: </label> <form:input path="birthDate" tabindex="3" /> </p> <p id="buttons"> <input id="reset" type="reset" tabindex="4"> <input id="submit" type="submit" tabindex="5" value="Add Employee"> </p> </fieldset> </form:form> </div> </body> </html>

    二. Formatter

      Formatter就像Converter一样,也是将一种类型转换 成另一种类型。但是,Formatter的源类型必须是一个 String,而Converter则适用于任意的源类型。Formatter 更适合Web层,而Converter则可以用在任意层中。为了 转换Spring MVC应用程序表单中的用户输入,始终应 该选择Formatter,而不是Converter。

    1. 为了创建Formatter,要编写一个实现 org.springframework.format.Formatter接口的Java类。下 面是这个接口的声明:

    public interface Formatter<T >

      这里的T表示输入字符串要转换的目标类型。该接 口有parse和print两个方法,所有实现都必须覆盖:

    T parse(String text, java.util.Locale locale)
    String print(T object, java.util.Locale locale)

      parse方法利用指定的Locale将一个String解析成目 标类型。print方法与之相反,它是返回目标对象的字符 串表示法。

      例如,app20a应用程序中用一个DateFormatter将 String转换成Date

    DateFormatter类

    package fomatter;
    
    import java.text.ParseException;
    import java.text.SimpleDateFormat;
    import java.util.Date;
    import java.util.Locale;
    
    import org.springframework.format.Formatter;
    
    public class DateFormatter implements Formatter<Date>{
        private String datePattern;
        private SimpleDateFormat dateFormat;
        /* 这里的datepattern 从springmvc-config.xml传入 */
        public DateFormatter(String datePattern) {
            this.datePattern = datePattern;
            dateFormat = new SimpleDateFormat(datePattern);
            dateFormat.setLenient(false);
        }
    
        @Override
        public String print(Date date, Locale locale) {
            return dateFormat.format(date);
        }
    
        @Override
        public Date parse(String s, Locale locale) throws ParseException {
            
            try {
                return dateFormat.parse(s);
            }catch(ParseException e) {
                // the error message will be displayed when using
                // <form:errors>
                throw new IllegalArgumentException(
                "invalid date format. Please use this pattern""
                + datePattern + """);
            }
        }
    }

    app20b的Spring配置文件

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:mvc="http://www.springframework.org/schema/mvc"
        xmlns:context="http://www.springframework.org/schema/context"
        xsi:schemaLocation="http://www.springframework.org/schema/beans
            http://www.springframework.org/schema/beans/spring-beans.xsd 
            http://www.springframework.org/schema/mvc 
            http://www.springframework.org/schema/mvc/spring-mvc.xsd 
            http://www.springframework.org/schema/context 
            http://www.springframework.org/schema/context/spring-context.xsd">
    
        <!-- 配置自定义扫描的包 -->
        <context:component-scan
            base-package="controller">
        </context:component-scan>    
        <context:component-scan base-package="formatter"/>
        <bean
            class="org.springframework.web.servlet.view.InternalResourceViewResolver">
            <!-- 前缀 和 后缀 -->
            <property name="prefix" value="/WEB-INF/jsp/" />
            <property name="suffix" value=".jsp" />
        </bean>
        
        <!-- 转换器 -->
        <mvc:annotation-driven conversion-service="conversionService" />
            
        <bean id="conversionService"
            class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
            <property name="formatters">
                <set>
                    <bean class="fomatter.DateFormatter">
                        <constructor-arg type="java.lang.String"
                            value="MM-dd-yyyy" />
                    </bean>
                </set>
            </property>
        </bean>
    </beans>

    EmployeeController类

    package controller;
    
    import org.apache.commons.logging.Log;
    import org.apache.commons.logging.LogFactory;
    import org.springframework.ui.Model;
    import org.springframework.validation.BindingResult;
    import org.springframework.validation.FieldError;
    import org.springframework.web.bind.annotation.ModelAttribute;
    import org.springframework.web.bind.annotation.RequestMapping;
    import domain.Employee;
    
    @org.springframework.stereotype.Controller
    public class EmployeeController {
        private static final Log  logger = LogFactory.getLog(EmployeeController.class);
        
        @RequestMapping(value="employee_input")
        public String inputEmployee(Model model) {
            model.addAttribute(new Employee());
            return "EmployeeForm";
        }
        
        @RequestMapping(value="employee_save")
        public  String saveEmployee(@ModelAttribute Employee employee,BindingResult bindingResult,Model model) {
            if(bindingResult.hasErrors()) {
                FieldError fieldError = bindingResult.getFieldError();
                logger.info("Code:" + fieldError.getCode()
                + ", field:" + fieldError.getField());
            }
            // save  employee here
            model.addAttribute("employee",employee);
            
            return "EmployeeDetails";
        }
    }

    EmployeeForm.jsp页面

    <%@ page language="java" contentType="text/html; charset=UTF-8"
        pageEncoding="UTF-8"%>
    <%@ taglib prefix="form"
        uri="http://www.springframework.org/tags/form"%>
    <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
    <!DOCTYPE html>
    <html>
    <head>
    <title>Add Employee Form</title>
    <style type="text/css">
    @import url("<c:url value= "/css/main.css"/>");
    </style>
    </head>
    <body>
        <div id="global">
            <form:form modelAttribute="employee" action="employee_save" method="post">
                <fieldset>
                    <legend>Add an employee</legend>
                    <p>
                        <label for="firstName">First Name: </label>
                        <form:input path="firstName" tabindex="1" />
                    </p>
                    <p>
                        <label for="lastName">First Name: </label>
                        <form:input path="lastName" tabindex="2" />
                    </p>
                    <p>
                        <form:errors path="birthDate" cssClass="error" />
                    </p>
                    <p>
                        <label for="birthDate">Date Of Birth: </label>
                        <form:input path="birthDate" tabindex="3" />
                    </p>
                    <p id="buttons">
                        <input id="reset" type="reset" tabindex="4"> <input
                            id="submit" type="submit" tabindex="5" value="Add Employee">
                    </p>
                </fieldset>
            </form:form>
        </div>
    </body>
    </html>

     三. 用Registrar注册Formatter

      注册Formatter的另一种方法是使用Registrar。例 如,以下app20b就是注册DateFormatter的一个例子

    MyFormatterRegistrar类

    package formatter;
    
    import org.springframework.format.FormatterRegistrar;
    import org.springframework.format.FormatterRegistry;
    
    public class MyFormatterRegistrar implements FormatterRegistrar {
        private String datePattern;
    
        public MyFormatterRegistrar(String datePattern) {
            this.datePattern = datePattern;
        }
    
        @Override
        public void registerFormatters(FormatterRegistry registry) {
            registry.addFormatter(new DateFormatter(datePattern));
    // register more formatters here
        }
    }

      有了Registrar,就不需要在Spring MVC配置文件中 注册任何Formatter了,只在Spring配置文件中注册 Registrar

    springmvc-config配置

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:mvc="http://www.springframework.org/schema/mvc"
        xmlns:context="http://www.springframework.org/schema/context"
        xsi:schemaLocation="http://www.springframework.org/schema/beans
            http://www.springframework.org/schema/beans/spring-beans.xsd 
            http://www.springframework.org/schema/mvc 
            http://www.springframework.org/schema/mvc/spring-mvc.xsd 
            http://www.springframework.org/schema/context 
            http://www.springframework.org/schema/context/spring-context.xsd">
    
        <!-- 配置自定义扫描的包 -->
        <context:component-scan
            base-package="controller">
        </context:component-scan>
        <context:component-scan base-package="formatter" />
        <bean
            class="org.springframework.web.servlet.view.InternalResourceViewResolver">
            <!-- 前缀 和 后缀 -->
            <property name="prefix" value="/WEB-INF/jsp/" />
            <property name="suffix" value=".jsp" />
        </bean>
    
        <!-- 转换器 -->
        <mvc:annotation-driven
            conversion-service="conversionService" />
    
        <bean id="conversionService"
            class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
            <property name="formatterRegistrars">
                <set>
                    <bean class="formatter.MyFormatterRegistrar">
                        <constructor-arg type="java.lang.String"
                            value="MM-dd-yyyy" />
                    </bean>
                </set>
            </property>
        </bean>
    
    </beans>

    四. 选择Converter,还是 Formatter

      Converter是一般工具,可以将一种类型转换成另一 种类型。例如,将String转换成Date,或者将Long转换 成Date。Converter既可以用在Web层,也可以用在其他 层中

      将String转换成Date,但它不能将Long转换成 Date。因此,Formatter适用于Web层。为此,在Spring MVC应用程序中,选择Formatter比选择Converter更合 适。

      

      

  • 相关阅读:
    微服务架构 ------ DockerCompose从安装到项目部署
    微服务架构 ------ Dockerfile定制镜像
    微服务架构 ------ Ubuntu下Docker的安装
    微服务架构 ------ 插曲 linux LVM磁盘扩容
    Ubuntu java环境变量配置
    微服务架构 ------ 插曲 hikari连接池的配置
    微服务架构 ------ 插曲 Mybatis逆向工程
    微服务架构 ------ 插曲 Linux平台 Ubuntu的安装
    微服务架构 ------ Day01 微服务架构优缺点
    k8s配置storage-class
  • 原文地址:https://www.cnblogs.com/jiangfeilong/p/10806361.html
Copyright © 2011-2022 走看看