Spring MVC数据校验与国际化

简介: <div class="markdown_views"><h2 id="1-jsr-303">1、 JSR-303</h2><p>JSR-303 是JAVA EE 6 中的一项子规范,叫做Bean Validation,官方参考实现是Hibernate Validator。 <br>此实现与Hibernate ORM 没有任何关系。JSR 303 用于对Java Be

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>
目录
相关文章
|
19天前
|
设计模式 前端开发 Java
步步深入SpringMvc DispatcherServlet源码掌握springmvc全流程原理
通过对 `DispatcherServlet`源码的深入剖析,我们了解了SpringMVC请求处理的全流程。`DispatcherServlet`作为前端控制器,负责请求的接收和分发,处理器映射和适配负责将请求分派到具体的处理器方法,视图解析器负责生成和渲染视图。理解这些核心组件及其交互原理,有助于开发者更好地使用和扩展SpringMVC框架。
31 4
|
2月前
|
前端开发 Java 开发者
Spring MVC中的请求映射:@RequestMapping注解深度解析
在Spring MVC框架中,`@RequestMapping`注解是实现请求映射的关键,它将HTTP请求映射到相应的处理器方法上。本文将深入探讨`@RequestMapping`注解的工作原理、使用方法以及最佳实践,为开发者提供一份详尽的技术干货。
142 2
|
3月前
|
JSON 前端开发 Java
SSM:SpringMVC
本文介绍了SpringMVC的依赖配置、请求参数处理、注解开发、JSON处理、拦截器、文件上传下载以及相关注意事项。首先,需要在`pom.xml`中添加必要的依赖,包括Servlet、JSTL、Spring Web MVC等。接着,在`web.xml`中配置DispatcherServlet,并设置Spring MVC的相关配置,如组件扫描、默认Servlet处理器等。然后,通过`@RequestMapping`等注解处理请求参数,使用`@ResponseBody`返回JSON数据。此外,还介绍了如何创建和配置拦截器、文件上传下载的功能,并强调了JSP文件的放置位置,避免404错误。
|
4月前
|
缓存 前端开发 Java
【Java面试题汇总】Spring,SpringBoot,SpringMVC,Mybatis,JavaWeb篇(2023版)
Soring Boot的起步依赖、启动流程、自动装配、常用的注解、Spring MVC的执行流程、对MVC的理解、RestFull风格、为什么service层要写接口、MyBatis的缓存机制、$和#有什么区别、resultType和resultMap区别、cookie和session的区别是什么?session的工作原理
|
3月前
|
前端开发 Java 应用服务中间件
【Spring】Spring MVC的项目准备和连接建立
【Spring】Spring MVC的项目准备和连接建立
66 2
|
3月前
|
XML 前端开发 Java
Spring,SpringBoot和SpringMVC的关系以及区别 —— 超准确,可当面试题!!!也可供零基础学习
本文阐述了Spring、Spring Boot和Spring MVC的关系与区别,指出Spring是一个轻量级、一站式、模块化的应用程序开发框架,Spring MVC是Spring的一个子框架,专注于Web应用和网络接口开发,而Spring Boot则是对Spring的封装,用于简化Spring应用的开发。
230 0
Spring,SpringBoot和SpringMVC的关系以及区别 —— 超准确,可当面试题!!!也可供零基础学习
|
4月前
|
XML 缓存 前端开发
springMVC02,restful风格,请求转发和重定向
文章介绍了RESTful风格的基本概念和特点,并展示了如何使用SpringMVC实现RESTful风格的请求处理。同时,文章还讨论了SpringMVC中的请求转发和重定向的实现方式,并通过具体代码示例进行了说明。
springMVC02,restful风格,请求转发和重定向
|
5月前
|
Java 数据库连接 Spring
后端框架入门超详细 三部曲 Spring 、SpringMVC、Mybatis、SSM框架整合案例 【爆肝整理五万字】
文章是关于Spring、SpringMVC、Mybatis三个后端框架的超详细入门教程,包括基础知识讲解、代码案例及SSM框架整合的实战应用,旨在帮助读者全面理解并掌握这些框架的使用。
后端框架入门超详细 三部曲 Spring 、SpringMVC、Mybatis、SSM框架整合案例 【爆肝整理五万字】
|
5月前
|
XML JSON 数据库
SpringMVC入门到实战------七、RESTful的详细介绍和使用 具体代码案例分析(一)
这篇文章详细介绍了RESTful的概念、实现方式,以及如何在SpringMVC中使用HiddenHttpMethodFilter来处理PUT和DELETE请求,并通过具体代码案例分析了RESTful的使用。
SpringMVC入门到实战------七、RESTful的详细介绍和使用 具体代码案例分析(一)
|
5月前
|
前端开发 应用服务中间件 数据库
SpringMVC入门到实战------八、RESTful案例。SpringMVC+thymeleaf+BootStrap+RestFul实现员工信息的增删改查
这篇文章通过一个具体的项目案例,详细讲解了如何使用SpringMVC、Thymeleaf、Bootstrap以及RESTful风格接口来实现员工信息的增删改查功能。文章提供了项目结构、配置文件、控制器、数据访问对象、实体类和前端页面的完整源码,并展示了实现效果的截图。项目的目的是锻炼使用RESTful风格的接口开发,虽然数据是假数据并未连接数据库,但提供了一个很好的实践机会。文章最后强调了这一章节主要是为了练习RESTful,其他方面暂不考虑。
SpringMVC入门到实战------八、RESTful案例。SpringMVC+thymeleaf+BootStrap+RestFul实现员工信息的增删改查