SpringMVC开发技术~8_1~转换器Converter

1 转换器Converter

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

Converter和Formatter,这两者均可用于将一种对象类型转换成另一种对象类型。

Converter是通用元件,可以在应用程序的任意层中使用,而Formatter则是专门为Web层设计的。

Spring的Converter是可以将一种类型转换成另一种类型的一个对象。例如,用户输入的日期可能有许多种形式,如“December 25,2014”、“12/25/2014”和“2014-12-25”,这些都表示同一个日期。

默认情况下,Spring会期待用户输入的日期样式与当前语言区域的日期样式相同。例如,对于美国的用户而言,就是月/日格式。如果希望Spring在将输入的日期字符串绑定到Date时,使用不同的日期样式,则需要编写一个Converter,才能将字符串转换成日期。

下面用一个案例来介绍转换器的使用

2 Spring MVC中转换器的使用案例

2.1 程序的目录结构

在这里插入图片描述

2.2 domain

package app06a.domain;
import java.io.Serializable;
import java.util.Date;
public class Employee implements Serializable {
    private static final long serialVersionUID = -908L;
    private long id;
    private String firstName;
    private String lastName;
    private Date birthDate;
    private int salaryLevel;
    public long getId() {return id;}
    public void setId(long id) {this.id = id;}
    public String getFirstName() {return firstName;    }
    public void setFirstName(String firstName) {this.firstName = firstName;}
    public String getLastName() {return lastName;}
    public void setLastName(String lastName) {this.lastName = lastName;}
    public Date getBirthDate() {return birthDate;}
    public void setBirthDate(Date birthDate) {this.birthDate = birthDate;}
    public int getSalaryLevel() {return salaryLevel;}
    public void setSalaryLevel(int salaryLevel) {this.salaryLevel = salaryLevel;}
}

2.3 Converter转换器类

为了创建Converter,必须编写一个实现org.springframework.core.convert.converter.Converter接口的Java类。这个接口的声明如下:Public interface Converter<S, T>
这里的S表示源类型,T表示目标类型。例如,为了创建一个可以将Long转换成Date的Converter,要像下面这样声明Conve rter类:public class MyConverter implements Convert<Long,Date>

StringToDateConverter.java

package app06a.converter;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.springframework.core.convert.converter.Converter;
public class StringToDateConverter implements Converter<String, Date> {
    private String datePattern;
    public StringToDateConverter(String datePattern) {
        this.datePattern = 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.4 Controller类

EmployeeController

package app06a.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 app06a.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());
            return "EmployeeForm";
        }        
        // save employee here        
        model.addAttribute("employee", employee);
        return "EmployeeDetails";
    }
}

2.5 Spring MVC配置文件

为了使用Spring MVC应用程序中定制的Converter,需要在Spring MVC配置文件中编写一个conversionService bean。
Bean的类名称必须为org. springframework.context. support. ConversionServiceFactoryBean。
这个bean必须包含一个converters属性,它将列出要在应用程序中使用的所有定制Converter。
例如,下面的bean声明是在注册了StringToDateConverter。随后,要给annotation-driven元素的conversion-service属性赋bean名称(本例中是conversionService),如下所示:

springmvc-config.xml

<?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:p="http://www.springframework.org/schema/p"
    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="app06a.controller"/>     
    <mvc:annotation-driven conversion-service="conversionService"/>
    <mvc:resources mapping="/css/**" location="/css/"/>
    <mvc:resources mapping="/*.html" location="/"/>    
    <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/jsp/"/>
        <property name="suffix" value=".jsp"/>
    </bean>    
    <bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean">
        <property name="converters">
            <list>
                <bean class="app06a.converter.StringToDateConverter">
                    <constructor-arg type="java.lang.String" value="MM-dd-yyyy"/>
                </bean>
            </list>
        </property>
    </bean>
</beans>

2.6 View视图层

2.6.1 EmployeeForm.jsp

<%@ 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 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>

2.6.2 EmployeeDetails.jsp

<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!DOCTYPE HTML>
<html>
<head>
<title>Save Employee</title>
<style type="text/css">@import url("<c:url value="/css/main.css"/>");</style>
</head>
<body>
<div id="global">
    <h4>The employee details have been saved.</h4>
    <p>
        <h5>Details:</h5>
        First Name: ${employee.firstName}<br/>
        Last Name: ${employee.lastName}<br/>
        Date of Birth: ${employee.birthDate}
    </p>
</div>
</body>
</html>

2.6.3 main.css

#global { text-align: left;border: 1px solid #dedede;background: #efefef;
    width: 560px;padding: 20px;margin: 100px auto;}
form {font:100% verdana;min-width: 500px;max-width: 600px;width: 560px;}
form fieldset {border-color: #bdbebf;border-width: 3px;margin: 0;}
legend {    font-size: 1.3em;}
form label {width: 250px;display: block;float: left;text-align: right;padding: 2px;}
#buttons {    text-align: right;}
#errors, li {	color: red;}
.error {    color: red;    font-size: 9pt;	}

2.7 web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xmlns="http://xmlns.jcp.org/xml/ns/javaee" 
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" 
id="WebApp_ID" version="3.1">
  <display-name>YJYSpring_MVC_Converter_PaulDeckCH06</display-name>
  <welcome-file-list>
    <welcome-file>index.jsp</welcome-file>
  </welcome-file-list>
  <servlet>
    <servlet-name>springmvc</servlet-name>
    <servlet-class>
            org.springframework.web.servlet.DispatcherServlet
        </servlet-class>
    <init-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>/WEB-INF/config/springmvc-config.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
  </servlet>
  <servlet-mapping>
    <servlet-name>springmvc</servlet-name>
    <url-pattern>/</url-pattern>
  </servlet-mapping>
</web-app>

3 运行和测试

http://localhost:8080/YJYSpring_MVC_Converter_PaulDeckCH06/employee_input

输入错误信息
在这里插入图片描述显示错误
在这里插入图片描述
修改为正确信息
在这里插入图片描述显示为正确信息
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值