六(一)、springMVC数据转换&格式化&校验&错误消息显示和国际化
一、概述
问题由来:
当form表单传数据到后台,后台接收参数,form表单传入数据都是字符串类型,但是后台接收参数可以是字符串、int、boolean、Date..此时会存在数据转换,如果是日期,还需要格式转换,数据校验:比如生日数据,那么生日日期,必须比当前日期小;
springmvc是如何做到数据转换、格式化和校验:
- Spring MVC 主框架将 ServletRequest 对象及目标方法的入参实例传递给 WebDataBinderFactory 实例,以创建 DataBinder 实例对象
- DataBinder 调用装配在 Spring MVC 上下文中的 ConversionService 组件进行数据类型转换、数据格式化工作。将 Servlet 中的请求信息填充到入参对象中
- 调用 Validator 组件对已经绑定了请求消息的入参对象进行数据合法性校验,并最终生成数据绑定结果 BindingData 对象
- Spring MVC 抽取 BindingResult 中的入参对象和校验错误对象,将它们赋给处理方法的响应入参
Spring MVC 通过反射机制对目标处理方法进行解析,将请求消息绑定到处理方法的入参中。数据绑定的核心部件是 DataBinder,运行机制如下图
annotation-driven配置
<mvc:annotation-driven />会自动注册一下三个bean:
DefaultAnnotationHandlerMapping -> RequestMappingHandlerMapping
AnnotationMethodHandlerAdapter -> RequestMappingHandlerAdapter
AnnotationMethodHandlerExceptionResolver -> ExceptionHandlerExceptionResolver
还提供一下支持:
- 支持数据绑定,@NumberFormatannotation支持,@DateTimeFormat支持,
- 支持@Valid,对Javabean实例惊喜JSR303验证;
- 支持@RequestBody 和@ResponseBody
- 支持使用ConversionService实例对表单参数进行类型转换;
@InitBinder:
@InitBinder标识的方法,可以对WebDataBinder对象进行初始化。WebDataBinder是DataBinder的子类,用来完成表单字段到Javabean属性的绑定。有2个基本用途,类型转换和参数绑定。
@InitBinder方法不能有返回值,它必须声明为void;
@InitBinder方法参通常是WebDataBinder;
数据转换和格式化:
对属性对象的输入/输出进行格式化,从其本质上讲依然属于“类型转换”的范畴,String在格式化模块中定义了一个实现类ConversionService实现类,该实现类扩展了GenericConversionService,因此它既有类型转换的功能,又具有格式化的功能;FormattingConversionService拥有一个FormattingConversionServiceFactroyBean工厂类,后者拥于在spring上下文中构造前者;
FormattingConversionServiceFactroyBean内部已经注册:NumberFormatAnnotationFormatterFactroy、JodaDateTimeFormatAnnotationFormatterFactroy;
- NumberFormatAnnotationFormatterFactroy:支持对数字类型的属性使用@NumberFormat注解
- JodaDateTimeFormatAnnotationFormatterFactroy:支持对日期类型的属性属性使用@DateTimeFormat注解;
<mvc:annotation-driven /> 默认创建的ConversionService实例即为FormattingConversionServiceFactroyBean;
@DateTimeFormat
,互斥属性:
- iso。类型为
DateTimeFormat.ISO
DateTimeFormat.ISO.DATE
: 格式yyyy-MM-dd
。DateTimeFormat.ISO.DATE_TIME
: 格式yyyy-MM-dd HH:mm:ss .SSSZ
。DateTimeFormat.ISO.TIME
: 格式HH:mm:ss .SSSZ
。DateTimeFormat.ISO.NONE
: 表示不使用ISO格式的时间。
- pattern。类型为String,使用自定义的时间格式化字符串。
- style。类型为String,通过样式指定日期时间的格式,由两位字符组成,第1位表示日期的样式,第2位表示时间的格式:
- S: 短日期/时间的样式;
- M: 中日期/时间的样式;
- L: 长日期/时间的样式;
- F: 完整日期/时间的样式;
- -: 忽略日期/时间的样式;
@NumberFormat
- pattern。类型为String,使用自定义的数字格式化字符串,"##,###.##"。
- style。类型为
NumberFormat.Style
,常用值:Style.NUMBER
正常数字类型Style.PERCENT
百分数类型Style.CURRENCY
货币类型
多个属性以逗号分隔@NumberFormat(style=Style.NUMBER, pattern="#,###")
实例验证:
1.目录结构:
2.实体类Employee.java
实体类中,Date类型的参数birthDay,float类型的参数 salary 上分别加了@DateTimeFormat(pattern = "yyyy-MM-dd") 和@NumberFormat(pattern = "###,###.##")
1 package handler.entity; 2 3 import java.util.Date; 4 5 import org.springframework.format.annotation.DateTimeFormat; 6 import org.springframework.format.annotation.NumberFormat; 7 8 public class Employee { 9 private int id; 10 private String name; 11 private String gender; 12 @DateTimeFormat(pattern = "yyyy-MM-dd") 13 private Date birthDay; 14 private String email; 15 @NumberFormat(pattern = "###,###.##") 16 private float salary; 17 18 public int getId() { 19 return id; 20 } 21 22 public void setId(int id) { 23 this.id = id; 24 } 25 26 public String getName() { 27 return name; 28 } 29 30 public void setName(String name) { 31 this.name = name; 32 } 33 34 public String getGender() { 35 return gender; 36 } 37 38 public void setGender(String gender) { 39 this.gender = gender; 40 } 41 42 public Date getBirthDay() { 43 return birthDay; 44 } 45 46 public void setBirthDay(Date birthDay) { 47 this.birthDay = birthDay; 48 } 49 50 public String getEmail() { 51 return email; 52 } 53 54 public void setEmail(String email) { 55 this.email = email; 56 } 57 58 public float getSalary() { 59 return salary; 60 } 61 62 public void setSalary(float salary) { 63 this.salary = salary; 64 } 65 66 @Override 67 public String toString() { 68 return "Employee [id=" + id + ", name=" + name + ", gender=" + gender + ", birthDay=" + birthDay + ", email=" 69 + email + ", salary=" + salary + "]"; 70 } 71 72 }
3.控制器EmployeeController.java
BindingResult的作用:方法参数之后立即声明一个Errors
或BindingResult
参数,用来获取访问来自命令对象(即@ModelAttribute
参数)的验证和数据绑定的错误或来自一个@RequestBody
或多个@RequestPart
参数的验证的错误;
当前,如果birthDay传入一个“aaa”,那么控制台就好打印错误;
1 package handler; 2 3 import org.springframework.stereotype.Controller; 4 import org.springframework.validation.BindingResult; 5 import org.springframework.validation.FieldError; 6 import org.springframework.web.bind.annotation.RequestMapping; 7 import org.springframework.web.servlet.ModelAndView; 8 9 import handler.entity.Employee; 10 11 @RequestMapping("/emp") 12 @Controller 13 public class EmployeeController { 14 15 @RequestMapping("/dataOperate") 16 public ModelAndView dataOperate(Employee employee, BindingResult bindingResult) { 17 if (bindingResult.getErrorCount() > 0) { 18 for (FieldError fieldError : bindingResult.getFieldErrors()) { 19 System.out.println(fieldError.getField() + "出错了:" + fieldError.getDefaultMessage()); 20 } 21 } 22 if (employee != null) { 23 if (employee.getId() > 0) { 24 System.out.println("添加的数据:" + employee); 25 int count = employee.getId(); 26 employee.setId(count + 1); 27 } else { 28 employee = new Employee(); 29 employee.setId(1); 30 System.out.println("首次添加:" + employee); 31 } 32 } 33 ModelAndView mv = new ModelAndView("index"); 34 mv.addObject("employee", employee); 35 return mv; 36 } 37 }
4.index.jsp页面
使用了spring的form标签,用来渲染带格式数据的页面;
spring的form标签的说明文档:https://docs.spring.io/spring-framework/docs/3.0.0.M4/reference/html/ch16s02.html
1 <%@ page language="java" contentType="text/html; charset=UTF-8" 2 pageEncoding="UTF-8"%> 3 <%@page import="java.util.*" %> 4 <%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %> 5 <!DOCTYPE html> 6 <html> 7 <head> 8 <meta charset="UTF-8"> 9 <title>Insert title here</title> 10 </head> 11 <body> 12 <h3>添加第${employee.id}人</h3> 13 14 <% 15 Map<String,String> genders= new HashMap<>(); 16 genders.put("0", "女"); 17 genders.put("1", "男"); 18 request.setAttribute("genders",genders); 19 %> 20 <form:form method="POST" action="dataOperate" modelAttribute="employee"> 21 name:<form:input path="name"></form:input><br> 22 性别:<form:radiobuttons path="gender" items="${genders}"></form:radiobuttons><br> 23 邮箱:<form:input path="email"></form:input><br> 24 生日:<form:input path="birthDay" ></form:input> <br> 25 薪资:<form:input path="salary"></form:input><br> 26 <form:hidden path="id"></form:hidden> 27 <input type="submit" value="提交"/> 28 </form:form> 29 </body> 30 </html>
5.web.xml
1 <?xml version="1.0" encoding="UTF-8"?> 2 <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"> 3 <display-name>DataOperate</display-name> 4 <servlet> 5 <servlet-name>springDispatcherServlet</servlet-name> 6 <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> 7 <!-- 配置DispatcherServletd 一个初始化参数:配置springmvc配置文件的位置和名称 --> 8 <!-- 实际上也可以不通过 contextConfigLocation 来配置Springmvc的配置文件,而是用默认的 即默认的配置文件为 9 /WEB-INF/<servlet-name>-servlet.xml 本项目默认位置配置文件即为: /WEB-INF/springDispatcherServlet-servlet.xml --> 10 <init-param> 11 <param-name>contextConfigLocation</param-name> 12 <param-value>classpath:spring.xml</param-value> 13 </init-param> 14 <!-- 表示springDispatcherServlet在加载的时候被创建 --> 15 <load-on-startup>1</load-on-startup> 16 </servlet> 17 18 <!-- Map all requests to the DispatcherServlet for handling --> 19 <servlet-mapping> 20 <servlet-name>springDispatcherServlet</servlet-name> 21 <url-pattern>/</url-pattern> 22 </servlet-mapping> 23 </web-app>
6.spring.xml
一定要配置<mvc:annotation-driven></mvc:annotation-driven>
1 <?xml version="1.0" encoding="UTF-8"?> 2 <beans xmlns="http://www.springframework.org/schema/beans" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 xmlns:mvc="http://www.springframework.org/schema/mvc" 5 xmlns:context="http://www.springframework.org/schema/context" 6 xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd 7 http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd 8 http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> 9 10 <context:component-scan base-package="handler"></context:component-scan> 11 <!-- 配置视图解析器 如何把handler 方法返回值解析为实际的物理视图 --> 12 <bean 13 class="org.springframework.web.servlet.view.InternalResourceViewResolver"> 14 <property name="prefix" value="/"></property> 15 <property name="suffix" value=".jsp"></property> 16 </bean> 17 <mvc:annotation-driven></mvc:annotation-driven> 18 </beans>
运行结果:
访问http://localhost:8080/DataOperate/emp/dataOperate,并且填写添加人员信息提交,回显在原来的页面:显示的结果为:生日和薪资按照实体类设定的格式显示;且控制台打印:
首次添加:Employee [id=1, name=null, gender=null, birthDay=null, email=null, salary=0.0]
添加的数据:Employee [id=1, name=aaa, gender=0, birthDay=Mon Sep 23 00:00:00 CST 1991, email=1602211058@qq.com, salary=111111.0]
数据校验和错误显示的显示:
1.如何校验,是否能用注解:
- 使用JSR 303验证标准;JSR303是Java为Bean数据合法性校验提供的标准框架,它已经包含在javaEE6.0中。通过在Bean属性上标注类似于@NotNull、@Max等标注的注解指定校验规则,并通过标注的验证接口对Bean进行验证;
- 加入hibernate validator 验证框架。加入7个jar包: hibernate-validator-cdi-6.1.7.Final.jar、hibernate-validator-annotation-processor-6.1.7.Final.jar、hibernate-validator-6.1.7.Final.jar、paranamer-2.8.jar、joda-time-2.9.7.jar、jakarta.persistence-api-2.2.3.jar、log4j-core-2.13.3.jar。hibernate validator是JSR303的一个参考实现,除支持所有标注的校验注解外,它还支持@Email @Length @NotEmpt @Range 。
注解 说明 备注 @null 被注释的元素必须为 null @NotNull 被注释的元素必须不为 null @AssertTrue 被注释的元素必须为 true @AssertFalse 被注释的元素必须为 false @Min(value) 被注释的元素必须是一个数字,其值必须大于等于指定的最小值 @Max(value) 被注释的元素必须是一个数字,其值必须小于等于指定的最小值 eg.@DecimalMax("5.0") @DecimalMin(value) 被注释的元素必须是一个数字,其值必须大于等于指定的最小值 @DecimalMax(value) 被注释的元素必须是一个数字,其值必须小于等于指定的最大值 @Size(max=, min=) 被注释的元素的大小必须在指定的范围内 @Digits (integer, fraction) 被注释的元素必须是一个数字,其值必须在可接受的范围内 @Past 被注释的元素必须是一个过去的日期 @Future 被注释的元素必须是一个将来的日期 @Pattern(regex=,flag=) 被注释的元素必须符合指定的正则表达式 @NotBlank(message =) 验证字符串非null,且长度必须大于0 @Email 被注释的元素必须是电子邮箱地址 Hibernate Validator 附加的 @Length(min=,max=) 被注释的字符串的大小必须在指定的范围内;eg.@Length(min = 2, max = 3)
Hibernate Validator 附加的,length的区间是[min,max] @NotEmpty 被注释的字符串的必须非空 Hibernate Validator 附加的 @Range(min=,max=,message=) 被注释的元素必须在合适的范围内 Hibernate Validator 附加的 - 在springmvc 配置文件中添加<mvc:annotation-driven/>
- 需要在bean的属性上添加对应的注解;
- 在目标方法bean类型的前面添加@Validate
实例验证:
1.目录结构:
2.lib包:
- 红色框jar包为jstl 需要的jar包;
- 黄色框jar包为springMVC需要的jar包
- 剩下的为 JSR303需要的jar包
3.配置方式:
web.xml只配置了DispatcherServlet;
1 <?xml version="1.0" encoding="UTF-8"?> 2 <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"> 3 <display-name>DataOperate</display-name> 4 <servlet> 5 <servlet-name>springDispatcherServlet</servlet-name> 6 <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> 7 <!-- 配置DispatcherServletd 一个初始化参数:配置springmvc配置文件的位置和名称 --> 8 <!-- 实际上也可以不通过 contextConfigLocation 来配置Springmvc的配置文件,而是用默认的 即默认的配置文件为 9 /WEB-INF/<servlet-name>-servlet.xml 本项目默认位置配置文件即为: /WEB-INF/springDispatcherServlet-servlet.xml --> 10 <init-param> 11 <param-name>contextConfigLocation</param-name> 12 <param-value>classpath:spring.xml</param-value> 13 </init-param> 14 <!-- 表示springDispatcherServlet在加载的时候被创建 --> 15 <load-on-startup>1</load-on-startup> 16 </servlet> 17 18 <!-- Map all requests to the DispatcherServlet for handling --> 19 <servlet-mapping> 20 <servlet-name>springDispatcherServlet</servlet-name> 21 <url-pattern>/</url-pattern> 22 </servlet-mapping> 23 </web-app>
spring.xml配置了 扫描包、视图解析器、<mvc:annotation-driven></mvc:annotation-driven>;
1 <?xml version="1.0" encoding="UTF-8"?> 2 <beans xmlns="http://www.springframework.org/schema/beans" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 xmlns:mvc="http://www.springframework.org/schema/mvc" 5 xmlns:context="http://www.springframework.org/schema/context" 6 xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd 7 http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd 8 http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> 9 10 <context:component-scan base-package="handler"></context:component-scan> 11 <!-- 配置视图解析器 如何把handler 方法返回值解析为实际的物理视图 --> 12 <bean 13 class="org.springframework.web.servlet.view.InternalResourceViewResolver"> 14 <property name="prefix" value="/"></property> 15 <property name="suffix" value=".jsp"></property> 16 </bean> 17 <mvc:annotation-driven></mvc:annotation-driven> 18 </beans>
4.实体类:在对应的成员变量上添加了相关的属性
1 package handler.entity; 2 3 import java.util.Date; 4 5 import javax.validation.constraints.Email; 6 import javax.validation.constraints.NotBlank; 7 import javax.validation.constraints.NotNull; 8 import javax.validation.constraints.Past; 9 10 import org.springframework.format.annotation.DateTimeFormat; 11 import org.springframework.format.annotation.NumberFormat; 12 13 public class Employee { 14 private int id; 15 @NotBlank 16 private String name; 17 private String gender; 18 @Email 19 private String email; 20 @NumberFormat(pattern = "###,###.##") 22 private float salary; 23 @Past 24 @DateTimeFormat(pattern = "yyyy-MM-dd") 25 private Date birthDay; 26 27 public int getId() { 28 return id; 29 } 30 31 public void setId(int id) { 32 this.id = id; 33 } 34 35 public String getName() { 36 return name; 37 } 38 39 public void setName(String name) { 40 this.name = name; 41 } 42 43 public String getGender() { 44 return gender; 45 } 46 47 public void setGender(String gender) { 48 this.gender = gender; 49 } 50 51 public Date getBirthDay() { 52 return birthDay; 53 } 54 55 public void setBirthDay(Date birthDay) { 56 this.birthDay = birthDay; 57 } 58 59 public String getEmail() { 60 return email; 61 } 62 63 public void setEmail(String email) { 64 this.email = email; 65 } 66 67 public float getSalary() { 68 return salary; 69 } 70 71 public void setSalary(float salary) { 72 this.salary = salary; 73 } 74 75 @Override 76 public String toString() { 77 return "Employee [id=" + id + ", name=" + name + ", gender=" + gender + ", email=" + email + ", salary=" 78 + salary + ", birthDay=" + birthDay + "]"; 79 } 80 81 }
5.EmployeeController.java:
1 package handler; 2 3 import javax.validation.Valid; 4 5 import org.springframework.stereotype.Controller; 6 import org.springframework.validation.BindingResult; 7 import org.springframework.validation.FieldError; 8 import org.springframework.web.bind.annotation.RequestMapping; 9 import org.springframework.web.servlet.ModelAndView; 10 11 import handler.entity.Employee; 12 13 @RequestMapping("/emp") 14 @Controller 15 public class EmployeeController { 16 17 @RequestMapping("/dataOperate") 18 public ModelAndView dataOperate(@Valid Employee employee, BindingResult bindingResult) { 19 if (bindingResult.getErrorCount() > 0) { 20 for (FieldError fieldError : bindingResult.getFieldErrors()) { 21 System.out.println(fieldError.getField() + "出错了:" + fieldError.getDefaultMessage()); 22 } 23 } 24 if (employee != null) { 25 if (employee.getId() > 0) { 26 System.out.println("添加的数据:" + employee); 27 int count = employee.getId(); 28 employee.setId(count + 1); 29 } else { 30 employee = new Employee(); 31 employee.setId(1); 32 System.out.println("首次添加:" + employee); 33 } 34 } 35 ModelAndView mv = new ModelAndView("index"); 36 mv.addObject("employee", employee); 37 return mv; 38 } 39 }
6.index.jsp
1 <%@ page language="java" contentType="text/html; charset=UTF-8" 2 pageEncoding="UTF-8"%> 3 <%@page import="java.util.*" %> 4 <%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %> 5 <!DOCTYPE html> 6 <html> 7 <head> 8 <meta charset="UTF-8"> 9 <title>Insert title here</title> 10 </head> 11 <body> 12 <h3>添加第${employee.id}人</h3> 13 14 <% 15 Map<String,String> genders= new HashMap<>(); 16 genders.put("0", "女"); 17 genders.put("1", "男"); 18 request.setAttribute("genders",genders); 19 %> 20 <form:form method="POST" action="dataOperate" modelAttribute="employee"> 21 name:<form:input path="name"></form:input><br> 22 性别:<form:radiobuttons path="gender" items="${genders}"></form:radiobuttons><br> 23 邮箱:<form:input path="email"></form:input><br> 24 生日:<form:input path="birthDay" ></form:input> <br> 25 薪资:<form:input path="salary"></form:input><br> 26 <form:hidden path="id"></form:hidden> 27 <input type="submit" value="提交"/> 28 </form:form> 29 </body> 30 </html>
运行结果:
访问显示http://localhost:8080/DataOperate/emp/dataOperate 显示页面如下图,且控制台打印:
name出错了:不能为空
首次添加:Employee [id=1, name=null, gender=null, email=null, salary=0.0, birthDay=null]
填写相关信息提交,显示页面如下,且控制台打印:
birthDay出错了:Failed to convert property value of type 'java.lang.String' to required type 'java.util.Date' for property 'birthDay'; nested exception is org.springframework.core.convert.ConversionFailedException: Failed to convert from type [java.lang.String] to type [@javax.validation.constraints.Past @org.springframework.format.annotation.DateTimeFormat java.util.Date] for value '123123'; nested exception is java.lang.IllegalArgumentException: Invalid format: "123123" is too short
salary出错了:Failed to convert property value of type 'java.lang.String' to required type 'float' for property 'salary'; nested exception is java.lang.NumberFormatException: For input string: "aaaa"
name出错了:不能为空
email出错了:不是一个合法的电子邮件地址
添加的数据:Employee [id=1, name=, gender=1, email=111, salary=0.0, birthDay=null]
错误消息的显示和国际化
1.显示错误消息,只要在对应的input上面添加<form:errors即可,比如<form:errors path="email"></form:errors>;
1 <form:form method="POST" action="dataOperate" modelAttribute="employee"> 2 name:<form:input path="name"></form:input><form:errors path="name"></form:errors><br> 3 性别:<form:radiobuttons path="gender" items="${genders}"></form:radiobuttons><br> 4 邮箱:<form:input path="email"></form:input><form:errors path="email"></form:errors><br> 5 生日:<form:input path="birthDay" ></form:input><form:errors path="birthDay"></form:errors> <br> 6 薪资:<form:input path="salary"></form:input><form:errors path="salary"></form:errors><br> 7 <form:hidden path="id"></form:hidden> 8 <input type="submit" value="提交"/> 9 </form:form>
2.消息的国际化配置:1.spring.xml中配置对应的i18n文件即可
1 <?xml version="1.0" encoding="UTF-8"?> 2 <beans xmlns="http://www.springframework.org/schema/beans" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 xmlns:mvc="http://www.springframework.org/schema/mvc" 5 xmlns:context="http://www.springframework.org/schema/context" 6 xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd 7 http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd 8 http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> 9 10 <context:component-scan base-package="handler"></context:component-scan> 11 <!-- 配置视图解析器 如何把handler 方法返回值解析为实际的物理视图 --> 12 <bean 13 class="org.springframework.web.servlet.view.InternalResourceViewResolver"> 14 <property name="prefix" value="/"></property> 15 <property name="suffix" value=".jsp"></property> 16 </bean> 17 <mvc:annotation-driven></mvc:annotation-driven> 18 19 <!-- 配置国际化资源 --> 20 <!-- 注意id必须为messageSource 否则 使用<s:message code=''></s:message>会报错 --> 21 <bean id="messageSource" 22 class="org.springframework.context.support.ResourceBundleMessageSource"> 23 <property name="basename" value="i18n"></property> 24 </bean> 25 </beans>
3.i18n文件:
1 NotBlank.employee.name=名称不能为空 2 Email.employee.email=邮箱格式不对 3 Past.employee.birthDay=需要一个过去的时间
运行结果:
访问http://localhost:8080/DataOperate/emp/dataOperate后,填写错误信息,显示对应的i18n提示消息,如下图;若不配置i18n国际化文件,则显示默认的错误消息;
参考地址
https://www.cnblogs.com/softidea/p/10079869.html
https://blog.csdn.net/sjjsh2/article/details/53100728