您的位置:首页 > 编程语言 > Java开发

Spring MVC数据校验与国际化

2015-07-01 14:09 609 查看

1、 JSR-303

JSR-303 是JAVA EE 6 中的一项子规范,叫做Bean Validation,官方参考实现是Hibernate Validator。

此实现与Hibernate ORM 没有任何关系。JSR 303 用于对Java Bean 中的字段的值进行验证。

Spring MVC 3.x之中也大力支持 JSR-303,可以在控制器中对表单提交的数据方便地验证。

JSR 303内置的约束规则:

@AssertTrue / @AssertFalse

验证适用字段:boolean

注解说明:验证值是否为true / false

属性说明:-

@DecimalMax / @DecimalMin

验证适用字段:BigDecimal,BigInteger,String,byte,short,int,long

注解说明:验证值是否小于或者等于指定的小数值,要注意小数存在精度问题

属性说明:公共

@Digits

验证适用字段:BigDecimal,BigInteger,String,byte,short,int,long

注解说明:验证值的数字构成是否合法

属性说明:integer:指定整数部分的数字的位数。fraction: 指定小数部分的数字的位数。

@Future / @Past

验证适用字段:Date,Calendar

注解说明:验证值是否在当前时间之后 / 之前

属性说明:公共

@Max / @Min

验证适用字段:BigDecimal,BigInteger,String,byte,short,int,long

注解说明:验证值是否小于或者等于指定的整数值

属性说明:公共

@NotNull / @Null

验证适用字段:引用数据类型

注解说明:验证值是否为非空 / 空

属性说明:公共

@Pattern

验证适用字段:String

注解说明:验证值是否配备正则表达式

属性说明:regexp:正则表达式flags: 指定Pattern.Flag 的数组,表示正则表达式的相关选项。

@Size

验证适用字段:String,Collection,Map,数组

注解说明:验证值是否满足长度要求

属性说明:max:指定最大长度,min:指定最小长度。

@Valid

验证适用字段:引用类型

注解说明:验证值是否需要递归验证

属性说明:无

使用Spring MVC 和 JSR-303的标注做表单提交的服务器端验证时,@Valid 标注的Command对象和BindingResult参数一定要紧挨着。要不然数据绑定错误直接抛异常,不会封装成一个BindingResult对象。

2、Spring MVC数据校验

<mvc:annotation-driven/>会默认装配好一个LocalValidatorFactoryBean,通过在处理方法的入参上标注@Valid注解就可让Spring MVC在完成数据绑定后执行数据校验操作。


A、需要的额外的JAR包

除了Spring MVC本身的JAR包外,我们还需要一些额外的JAR包。



B、添加JSR 303注解

package cn.framelife.mvc.entity;

import java.util.Date;

import javax.validation.constraints.DecimalMax;
import javax.validation.constraints.DecimalMin;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Past;
import javax.validation.constraints.Pattern;
import javax.validation.constraints.Size;

import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.format.annotation.NumberFormat;

public class User implements java.io.Serializable {

private Integer id;

/*
* 测试的时候,发现在页面获取到的数据传到User模式后,都是非空的。
*/
@NotNull(message = "用户名不能为空")
private String username;

@Size(min = 2, max = 6, message = "长度是2-6之间")
private String password;

@Past(message = "必须是一个过去的时间")
@DateTimeFormat(pattern = "yyyy-MM-dd")
private Date birthday;

@DecimalMin(value = "1000.00", message = "工资必须大于1000.00")
@DecimalMax(value = "10000.00", message = "工资必须小于10000.00")
@NumberFormat(pattern = "#,###.##")
private long salary;

@Pattern(regexp = "1[3|4|5|8][0-9]\\d{4,8}", message = "手机号码不匹配")
private String phone;

public String getPhone() {
return phone;
}

public void setPhone(String phone) {
this.phone = phone;
}

public long getSalary() {
return salary;
}

public void setSalary(long salary) {
this.salary = salary;
}

public Date getBirthday() {
return birthday;
}

public void setBirthday(Date birthday) {
this.birthday = birthday;
}

public Integer getId() {
return id;
}

public void setId(Integer id) {
this.id = id;
}

public String getUsername() {
return username;
}

public void setUsername(String username) {
this.username = username;
}

public String getPassword() {
return password;
}

public void setPassword(String password) {
this.password = password;
}
}


C、Controller中的处理

@Controller
@RequestMapping("/user")
public class UserControl {

/**
* 此方法是用于第一次给页面添加一个user模型数据的
*/
@RequestMapping(value="/add",method = RequestMethod.GET)
public ModelAndView initForm(){
User user = new User();
return new ModelAndView("/add").addObject(user);
}

/**
* 给入参的模型对象User加入@Valid注解,说明这个对象里面的属性需要校验
* BindingResult入参是用以判断上面的校验是否出错
*/
@RequestMapping("create")
public ModelAndView createUser(@Valid User user,BindingResult bindingResult){
ModelAndView view = new ModelAndView();
System.out.println(user.getUsername()+"----");

//如果校验有问题,跑回原来的add.jsp页面,如果没问题跑到success.jsp页面
if(bindingResult.hasErrors()){
view.setViewName("/add");
}else{
view.setViewName("/success");
}

return view;
}
}


D、页面输入及输出

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<!-- 导入spring的表单标签库 -->
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">

<title>增加</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<!--
<link rel="stylesheet" type="text/css" href="styles.css">
-->
</head>

<body>

<!-- 在使用表单标签的时候需要获取到一个user模型数据,那我们不能直接访问页面(通过/user/add.abc访问),必须通过访问一次服务器,获取到一个user数据模型后才行,否则会出错 -->
<form:form modelAttribute="user" action="user/create.abc">
<!-- 输出所有的错误信息 -->
<form:errors path="*" /><br/>
<hr/>

<!-- 输出单个错误信息 -->
<form:errors path="username" ></form:errors><br/>
用户名:<form:input path="username"/><br/>

<form:errors path="password" ></form:errors><br/>
密 码:<form:password path="password"/><br/>

<form:errors path="birthday" ></form:errors><br/>
生日:<form:input path="birthday"/><br/>

<form:errors path="salary" ></form:errors><br/>
工资:<form:input path="salary"/><br/>

<form:errors path="phone" ></form:errors><br/>
电话:<form:input path="phone"/><br/>

<input type="submit">
</form:form>
</body>
</html>


3、通过国际化资源显示错误信息

A、校验属性

/*
* 使用资源文件,这里不再需要message参数
*/
@Pattern(regexp = "1[3|4|5|8][0-9]\\d{4,8}")
private String phone;


B、资源文件(src下的messages.properties)

Pattern.user.phone=\u624B\u673A\u53F7\u7801\u4E0D\u5339\u914D


上面键值对中,

键是校验类javax.validation.constraints.Pattern的类名+被校验的模型对象名+属性名

值是”手机号码不匹配”

C、配置本地化资源文件(mvc-servlet.xml)

<!-- 配置国际化资源文件 -->
<!--
ReloadableResourceBundleMessageSource加载时,默认使用DefaultResourceLoader,他会先判断资源path是否带有classpath:前缀,如果有,用ClassPathResource去加载资源文件,如果没有试着用文件协议的url去访问,再没有就在contextPath即WEB-INF下查找
-->
<bean id="messageSource"
class="org.springframework.context.support.ReloadableResourceBundleMessageSource"
p:basename="classpath:messages">
</bean>


D、显示

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<!-- 导入spring的表单标签库 -->
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">

<title>增加</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<!--
<link rel="stylesheet" type="text/css" href="styles.css">
-->
</head>

<body>

<!-- 在使用表单标签的时候需要获取到一个user模型数据,那我们不能直接访问页面(通过/user/add.abc访问),必须通过访问一次服务器,获取到一个user数据模型后才行,否则会出错 -->
<form:form modelAttribute="user" action="user/create.abc">
<!-- 输出所有的错误信息 -->
<form:errors path="*" /><br/>
<hr/>

<!-- 输出单个错误信息 -->
<form:errors path="username" ></form:errors><br/>
用户名:<form:input path="username"/><br/>

<form:errors path="password" ></form:errors><br/>
密 码:<form:password path="password"/><br/>

<form:errors path="birthday" ></form:errors><br/>
生日:<form:input path="birthday"/><br/>

<form:errors path="salary" ></form:errors><br/>
工资:<form:input path="salary"/><br/>

<form:errors path="phone" ></form:errors><br/>
电话:<form:input path="phone"/><br/>

<input type="submit">
</form:form>
</body>
</html>
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息