第6章 Spring MVC的数据转换、格式化和数据校验

使用ConversionService转换数据

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!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>测试ConversionService</title>
</head>
<body>
<h3>注册页面</h3>
<form action="register" method="post">
    <table>
        <tr>
           <td><label>登录名:</label></td>
           <td><input type="text" id="loginname" name="loginname"></td>
        </tr>
        <tr>
            <td><label>生日:</label></td>
            <td><input type="text" id="birthday" name="birthday"></td>
        </tr>
        <tr>
            <td><input id="submit" type="submit" value="登录"></td>
        </tr>
    </table>

</form>
</body>
</html>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt"%>
<!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>测试ConversionService</title>
</head>
<body>
登录名:${requestScope.user.loginname }<br>
生日:<fmt:formatDate value="${requestScope.user.birthday}" pattern="yyyy年MM月dd日"/><br/>

</body>
</html>
package org.fkit.dmain;

import java.io.Serializable;
import java.util.Date;

public class User implements Serializable{
      private String loginname;
      private Date birthday;
      public User() {
        super();
        // TODO Auto-generated constructor stub
      }
    public String getLoginname() {
        return loginname;
    }
    public void setLoginname(String loginname) {
        this.loginname = loginname;
    }
    public Date getBirthday() {
        return birthday;
    }
    public void setBirthday(Date birthday) {
        this.birthday = birthday;
    }
    @Override
    public String toString() {
        return "User [loginname=" + loginname + ", birthday=" + birthday + "]";
    }
      
      
}
package org.fkit.converter;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

import org.springframework.core.convert.converter.Converter;

// 实现Converter<S,T>接口
public class StringToDateConverter implements Converter<String, Date>{
   // 日期类型模板:如yyyy--MM-dd
    private String datePattern;
    

    public void setDatePattern(String datePattern) {
        this.datePattern = datePattern;
    }
    // Converter<S,T>接口的类型转换方法
    public Date convert(String date) {
        try {
        // TODO Auto-generated method stub
        SimpleDateFormat dateFormat = new SimpleDateFormat(this.datePattern);
        // 将日期字符串转换成Date类型返回

            return dateFormat.parse(date);
        } catch (ParseException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            System.out.println("日期转换失败!");
            return null;
        }

    }
    
}
package org.fkit.controller;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.fkit.dmain.User;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

@Controller
public class UserController {
  private static final Log logger = LogFactory.getLog(UserController.class);
  
  
  
  @RequestMapping(value="/{formName}")
  public String loginForm(@PathVariable String formName){
      
      
      // 动态跳转页面
      return formName;
  }
  
  @RequestMapping(value="/register",method=RequestMethod.POST,produces="text/html;charset=UTF-8")
/*  public String register(
          @ModelAttribute User user,
          Model model){*/
  public String register(
          User user,
          Model model){
      logger.info(user);
      System.out.println(user);
      model.addAttribute("user", user);
      System.out.println(user);
      return "success";
      
  }
}
<?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-4.2.xsd
        http://www.springframework.org/schema/mvc
        http://www.springframework.org/schema/mvc/spring-mvc-4.2.xsd     
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context-4.2.xsd">
        
        <!-- spring可以自动去扫描base-pack下面的包或者子包下面的java文件,
                          如果扫描到有Spring的相关注解的类,则把这些类注册为Spring的bean
        
         -->
        <context:component-scan base-package="org.fkit.controller"></context:component-scan>
        
        <!-- 装配自定义的类型转换器 -->
        <mvc:annotation-driven conversion-service="conversionService"></mvc:annotation-driven>
        
        <!-- 自定义的类型转换器 -->
        <bean id="conversionService" 
               class="org.springframework.context.support.ConversionServiceFactoryBean">
               <property name="converters">
                  <list>
                     <bean class="org.fkit.converter.StringToDateConverter"
                     p:datePattern="yyyy-MM-dd"></bean>
                  </list>
               
               </property>
               
               
               </bean>
               
               
        <!-- 视图解析器 -->
        <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
           <!-- 前缀 -->
           <property name="prefix">
           
              <value>/WEB-INF/content/</value>
           </property>
           <!-- 后缀 -->
           <property name="suffix">
              <value>.jsp</value>
           </property>
        </bean>
        
        
        
        </beans>
<?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">
        <filter>
       <filter-name>characterEncodingFilter</filter-name>
       <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
       <init-param>
          <param-name>encoding</param-name>
           <param-value>UTF-8</param-value>
       </init-param>
       <init-param>
           <param-name>forceEncoding</param-name>
           <param-value>true</param-value>
       </init-param>
    </filter>
    <filter-mapping>
        <filter-name>characterEncodingFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
    <!-- 定义Spring MVC的前端控制器 -->
    <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/springmvc-config.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
    
    </servlet>
    <!-- 让Spring MVC的前端控制器拦截所有请求 -->
    <servlet-mapping>
      <servlet-name>springmvc</servlet-name>
      <url-pattern>/</url-pattern>
    </servlet-mapping>

</web-app>

使用@InitBinder添加自定义编辑器转换数据

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!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>测试@InitBinder</title>
</head>
<body>
<h3>测试@InitBinder</h3>
<form action="register" method="post">
      <table>
         <tr>
            <td><label>登录名:</label></td>
            <td><input type="text" id="loginname" name="loginname"></td>
         </tr>
         <tr>
            <td><label>生日:</label></td>
            <td><input type="text" id="birthday" name="birthday"></td>
         </tr>
         <tr>
             <td><input id="submit" type="submit" value="登录"></td>
         </tr>
      </table>

</form>
</body>
</html>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt"%>
<!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>测试@InitBinder</title>
</head>
<body>
登录名:${requestScope.user.loginname}<br>
生日:<fmt:formatDate value="${requestScope.user.birthday}" pattern="yyyy年MM月dd日"/><br>

</body>
</html>
package org.fkit.domain;

import java.io.Serializable;
import java.util.Date;

public class User implements Serializable{
      private String loginname;
      private Date birthday;
    public User() {
        super();
        // TODO Auto-generated constructor stub
    }
    public String getLoginname() {
        return loginname;
    }
    public void setLoginname(String loginname) {
        this.loginname = loginname;
    }
    public Date getBirthday() {
        return birthday;
    }
    public void setBirthday(Date birthday) {
        this.birthday = birthday;
    }
    @Override
    public String toString() {
        return "User [loginname=" + loginname + ", birthday=" + birthday + "]";
    }
    
}
package org.fkit.converter;

import java.beans.PropertyEditorSupport;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;


//自定义属性编辑器
public class DateEditor extends PropertyEditorSupport{
    // 将传入的字符串数据转换成Date类型
    @Override
    public void setAsText(String text) throws IllegalArgumentException {
        // TODO Auto-generated method stub
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
        try {
            Date date = dateFormat.parse(text);
            setValue(date);
        } catch (ParseException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        
    }
}
package org.fkit.controller;



import java.util.Date;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.fkit.converter.DateEditor;
import org.fkit.domain.User;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;


@Controller
public class UserController {
    private static final Log logger = LogFactory.getLog(UserController.class);
    
    @RequestMapping(value="/{formName}")
    public String loginForm(@PathVariable String formName){
        // 动态跳转页面
        return formName;
    }
    
    // 在控制器初始化时注册属性编辑器
    @InitBinder
      public void initBinder(WebDataBinder binder){
        //注册自定义编辑器
        binder.registerCustomEditor(Date.class, new DateEditor());
    }
    
    
    
    @RequestMapping(value="/register",method=RequestMethod.POST)
    public String register(
                  @ModelAttribute User user,
                  Model mode){
        logger.info(user);
        mode.addAttribute("user", user);
        return "success";
        
    }
    
}
<?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-4.2.xsd
        http://www.springframework.org/schema/mvc
        http://www.springframework.org/schema/mvc/spring-mvc-4.2.xsd     
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context-4.2.xsd">
        
        <!-- spring可以自动去扫描base-pack下面的包或者子包下面的java文件,
                          如果扫描到有Spring的相关注解的类,则把这些类注册为Spring的bean
        
         -->
        <context:component-scan base-package="org.fkit.controller"></context:component-scan>
        <!-- 视图解析器 -->
          <bean id="viewResolver"
               class="org.springframework.web.servlet.view.InternalResourceViewResolver">
               <!-- 前缀 -->
               <property name="prefix">
                  <value>/WEB-INF/content/</value>
               
               </property>
               <!-- 后缀 -->
               <property name="suffix">
                   <value>.jsp</value>
               </property>
               </bean>
        </beans>
<?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">
    <!-- 定义Spring MVC的前端控制器 -->
    <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/springmvc-config.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
    
    </servlet>
    <!-- 让Spring MVC的前端控制器拦截所有请求 -->
    <servlet-mapping>
       <servlet-name>springmvc</servlet-name>
       <url-pattern>/</url-pattern>
    </servlet-mapping>
    
    <!-- 编码过滤器 -->
    <filter>
       <filter-name>characterEncodingFilter</filter-name>
       <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
       <init-param>
          <param-name>encoding</param-name>
          <param-value>UTF-8</param-value>
       
       </init-param>
    
    </filter>
    <filter-mapping>
       <filter-name>characterEncodingFilter</filter-name>
       <url-pattern>/*</url-pattern>
    </filter-mapping>
</web-app>

示例:使用WebBindingInitializer注册全局自定义编辑器转换数据

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!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>测试WebBindingInitializer</title>
</head>
<body>
<h3>测试WebBindingInitializer</h3>
<form action="register" method="post">

   <table>
      <tr>
         <td><label>登录名:</label></td>
         <td><input type="text" id="loginname" name="loginname"></td>
      </tr>
      <tr>
         <td><label>生日:</label></td>
         <td><input type="text" id="birthday" name="birthday"></td>
      </tr>
      <tr>
         <td><input id="submit" type="submit" value="登录"></td>
      
      </tr>
   </table>

</form>


</body>
</html>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt"%>
<!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>测试WebBindingInitializer</title>
</head>
<body>
登录名:${requestScope.user.loginname}<br>
生日: <fmt:formatDate value="${requestScope.user.birthday}" pattern="yyyy年MM月dd日"/><br>
</body>
</html>
<?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-4.2.xsd
        http://www.springframework.org/schema/mvc
        http://www.springframework.org/schema/mvc/spring-mvc-4.2.xsd     
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context-4.2.xsd">
        
        <!-- spring可以自动去扫描base-pack下面的包或者子包下面的java文件,
                                      如果扫描到有Spring的相关注解的类,则把这些类注册为Spring的bean
         -->
        <context:component-scan base-package="org.fkit.controller"></context:component-scan>
        
        <!-- 视图解析器 -->
        <bean id="viewResolver"
              class="org.springframework.web.servlet.view.InternalResourceViewResolver">
              
          <!-- 前缀 -->
          <property name="prefix">
              <value>/WEB-INF/content/</value>
          </property>    
          <!-- 后缀 -->
          <property name="suffix">
              <value>.jsp</value>
          </property> 
          </bean>
        
        <!-- 通过AnnotationMethodHandlerAdapter装配自定义编辑器 -->
        <bean 
             class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
               <property name="webBindingInitializer">
                  <bean class="org.fkjava.binding.DateBindingInitializer"></bean>
                  
               </property>
             </bean>
        </beans>
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
  <!-- 定义Spring MVC的前端控制器 -->
    <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/springmvc-config.xml</param-value>      
       
       </init-param>
       <load-on-startup>1</load-on-startup>
    </servlet>
    
    <!-- 让Spring MVC的前端控制器拦截所有请求 -->
    <servlet-mapping>
       <servlet-name>springmvc</servlet-name>
       <url-pattern>/</url-pattern>
    </servlet-mapping>

    <!-- 编码过滤器 -->
    <filter>
        <filter-name>characterEncodingFilter</filter-name>
        <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
        <init-param>
           <param-name>encoding</param-name>
           <param-value>UTF-8</param-value>
        </init-param>
    </filter>
    
    <filter-mapping>
       <filter-name>characterEncodingFilter</filter-name>
       <url-pattern>/*</url-pattern>    
    
    </filter-mapping>
    

    
    
</web-app>
package org.fkit.controller;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.fkit.domain.User;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

/**
 * UserController是一个基于注解的控制器,
 * 可以同时处理多个请求动作,并且无须实现任何接口。
 * org.springframework.stereotype.Controller注解用于指示该类是一个控制器
 * @author ZHONGZHENHUA
 *
 */
@Controller
public class UserController {

    
     private static final Log logger = LogFactory.getLog(UserController.class);
     
     @RequestMapping(value="/{formName}")
      public String loginForm(@PathVariable String formName){
         
         // 动态跳转页面
         return formName;
     }
     
     @RequestMapping(value="/register",method=RequestMethod.POST)
     public String register(
             @ModelAttribute User user,
             Model model) {
         logger.info(user);
         model.addAttribute("user", user);
        return "success";
         
     }
     
     
}
package org.fkit.converter;

import java.beans.PropertyEditorSupport;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;


public class DateEditor extends PropertyEditorSupport{

    
    // 将传入的字符串数据转换成Date类型
    @Override
    public void setAsText(String text) throws IllegalArgumentException {
        // TODO Auto-generated method stub
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
        
        try {
            Date date = dateFormat.parse(text);
            setValue(date);
        } catch (ParseException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
    
    
    
}
package org.fkit.domain;

import java.io.Serializable;
import java.util.Date;

public class User implements Serializable{
   private String loginname;
   private Date birthday;
   public User() {
      super();
    // TODO Auto-generated constructor stub
   }
   public String getLoginname() {
      return loginname;
   }
   public void setLoginname(String loginname) {
      this.loginname = loginname;
   }
   public Date getBirthday() {
      return birthday;
   }
   public void setBirthday(Date birthday) {
     this.birthday = birthday;
   }
   
   
}
package org.fkjava.binding;
import java.util.Date;

import org.fkit.converter.DateEditor;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.support.WebBindingInitializer;
import org.springframework.web.context.request.WebRequest;

// 实现WebBindingInitializer接口
public class DateBindingInitializer implements WebBindingInitializer{

    @Override
    public void initBinder(WebDataBinder binder, WebRequest request) {
        // TODO Auto-generated method stub
        // 注册自定义编辑器
        binder.registerCustomEditor(Date.class, new DateEditor());
    }

}
原文地址:https://www.cnblogs.com/ZHONGZHENHUA/p/8063746.html