day09-2-验证以及国际化
验证以及国际化
1.概述
(1)概述
- 对于输入的数据(比如表单数据),进行必要的验证,并给出相应的提示信息
- 对于验证表单数据,SpringMVC 提供了很多使用的注解,这些注解由 JSR 303验证框架提供。
(2)JSR 303 验证框架
- JSR 303 是 Java 为 Bean 数据合法性校验提供的标准框架,它已经包含在 JavaEE 中
- JSR 303 通过在 Bean 属性上标注类似于 @NotNull、@Max 等标注的注解指定校验规则,并通过标准的验证接口对 Bean 进行验证
- JSR 303 提供的基本验证注解有:
注解 | 功能说明 |
---|---|
@Null | 被注释的元素必须为null |
@NotNull | 被注释的元素不能为null |
@AssertTrue | 被注释的元素必须为true |
@AssertFalse | 被注释的元素必须为false |
@Min(value) | 被注释的元素必须是一个数字,其值必须大于等于指定的最小值 |
@Max(value) | 被注释的元素必须是一个数字,其值必须小于等于指定的最大值 |
@DecimalMin(value) | 被注释的元素必须是一个数字,其值必须大于等于指定的最小值 |
@DecimalMax(value) | 被注释的元素必须是一个数字,其值必须小于等于指定的最大值 |
@Size(max,min) | 被注释的元素的大小必须在指定的范围内 |
@Digits(integer,fraction) | 被注释的元素必须是一个数字,其值必须在可接受的范围内 |
@Past | 被注释的元素必须是一个过去的日期 |
@Future | 被注释的元素必须是一个将来的日期 |
@Pattern(value) | 被注释的元素必须符合指定的正则表达式 |
(3)Hibernate Validator 扩展注解
Hibernate Validator 和 Hibernate 没有关系,只是 JSR 303 实现的一个扩展
Hibernate Validator 是 JSR 303的一个参考实现,除支持所有标准的校验注解外,它还支持以下的扩展注解:
注解 | 功能说明 |
---|---|
被注释的元素必须是电子邮件地址 | |
@Length | 被注释的字符串的大小必须在指定的范围内 |
@NotEmpty | 被注释的字符串必须非空 |
@Range | 被注释的元素必须在合适的范围内 |
2.应用实例
需求说明
指定表单的数据格式,后端在接收到数据后,能够对数据进行校验,并给不符合格式的数据返回提示信息,显示在前端页面
2.1代码实现
(1)引入验证和国际化相关的jar包
(2)Monster.java,属性添加注解以验证格式
package com.li.web.datavalid.entity;
import org.hibernate.validator.constraints.Email;
import org.hibernate.validator.constraints.NotEmpty;
import org.hibernate.validator.constraints.Range;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.format.annotation.NumberFormat;
import java.util.Date;
/**
* @author 李
* @version 1.0
*/
public class Monster {
@NotEmpty
private Integer id;
@Email
private String email;
//表示接收到的age的值必须在1-100之间
@Range(min = 1, max = 100)
private Integer age;
//Asserts that the annotated string, collection,
// map or array is not {@code null} or empty.
@NotEmpty
private String name;
@DateTimeFormat(pattern = "yyyy-MM-dd")
private Date birthday;
@NumberFormat(pattern = "###,###.##")
private Float salary;
public Monster() {
}
public Monster(Integer id, String email, Integer age, String name, Date birthday, Float salary) {
this.id = id;
this.email = email;
this.age = age;
this.name = name;
this.birthday = birthday;
this.salary = salary;
}
public Integer getId() {
return id;
}
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
public Float getSalary() {
return salary;
}
public void setSalary(Float salary) {
this.salary = salary;
}
public void setId(Integer id) {
this.id = id;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Monster{" +
"id=" + id +
", email='" + email + '\'' +
", age=" + age +
", name='" + name + '\'' +
", birthday=" + birthday +
", salary=" + salary +
'}';
}
}
(3)MonsterHandler.java
package com.li.web.datavalid;
import com.li.web.datavalid.entity.Monster;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;
import org.springframework.validation.Errors;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import javax.validation.Valid;
import java.util.Map;
/**
* @author 李
* @version 1.0
*/
@Controller
@Scope(value = "prototype")
public class MonsterHandler {
/**
* 1.SpringMVC可以将提交的数据,按照参数名和形参对象的属性名匹配,
* 然后直接封装到对象中[模型数据]
* 2.@Valid Monster monster 表示对monster接收的数据进行校验
* 3.校验的发生的时机:在SpringMVC底层反射调用目标方法时,会接收到http请求接收到的数据,
* 然后根据注解来进行验证。在验证过程中,如果出现了错误,就把错误信息填充到errors和 map中
* @param monster
* @param errors 表示如果校验出现了错误,会将校验的错误信息保存到errors中
* @param map map不但会保存monster对象,如果校验出现错误,也会将校验的错误信息放到map中
* @return
*/
@RequestMapping(value = "/save", method = RequestMethod.POST)
public String save(@Valid Monster monster, Errors errors, Map<String, Object> map) {
System.out.println("----monster----" + monster);
//为了查看验证的情况,输出map和errors
System.out.println("=======map=======");
for (Map.Entry<String, Object> entry : map.entrySet()) {
System.out.println("key=" + entry.getKey() +
" value=" + entry.getValue());
System.out.println("--------");
}
System.out.println("=======errors=======");
for (ObjectError error : errors.getAllErrors()) {
System.out.println("error="+error);
}
return "datavalid/success";
}
}
(4)monster_addUI.jsp:
<%@taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>添加妖怪</title>
</head>
<body>
<h3>添加妖怪</h3>
<form:form action="save" method="post" modelAttribute="monster">
妖怪id:<form:input path="id"/><br/><br/>
妖怪名字:<form:input path="name"/><br/><br/>
妖怪年龄:<form:input path="age"/><br/><br/>
妖怪生日:<form:input path="birthday"/> 要求以"yyyy-MM-dd"的格式<br/><br/>
妖怪工资:<form:input path="salary"/> 要求以"###,###.##"的格式<br/><br/>
电子邮件:<form:input path="email"/><br/><br/>
<input type="submit" value="添加妖怪"/>
</form:form>
</body>
</html>
(5)测试
提交的数据:年龄这里故意填写不符合格式的数据(1-100)
后台输出了默认的错误信息:
----monster----Monster{id=1, email='king@sohu.com', age=999, name='king', birthday=Tue Jan 01 00:00:00 CST 1924, salary=1267.22}
=======map=======
key=monster value=Monster{id=1, email='king@sohu.com', age=999, name='king', birthday=Tue Jan 01 00:00:00 CST 1924, salary=1267.22}
--------
key=org.springframework.validation.BindingResult.monster value=org.springframework.validation.BeanPropertyBindingResult: 1 errors
Field error in object 'monster' on field 'age': rejected value [999]; codes [Range.monster.age,Range.age,Range.java.lang.Integer,Range]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [monster.age,age]; arguments []; default message [age],100,1]; default message [需要在1和100之间]
--------
=======errors=======
error=Field error in object 'monster' on field 'age': rejected value [999]; codes [Range.monster.age,Range.age,Range.java.lang.Integer,Range]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [monster.age,age]; arguments []; default message [age],100,1]; default message [需要在1和100之间]
(6)自定义错误信息:配置 springDispatcherServlet-servlet.xml
<!--配置国际化错误信息的资源处理 bean-->
<bean class="org.springframework.context.support.ResourceBundleMessageSource"
id="messageSource">
<!--
配置国际化文件名字
如果下面这样配置,表示 messageSource对象会到src/i18nXXX.properties 去读取错误信息
-->
<property name="basename" value="i18n"/>
</bean>
(7)在src 目录下创建国际化文件 i18n.properties
中文要使用 unicode 编码处理
NotEmpty.monster.name=\u7528\u6237\u540d\u4e0d\u80fd\u4e3a\u7a7a
typeMismatch.monster.age=\u5e74\u9f84\u8981\u6c42\u5728\u0031\u002d\u0031\u0035\u0030\u4e4b\u95f4
typeMismatch.monster.birthday=\u751f\u65e5\u683c\u5f0f\u4e0d\u6b63\u786e
typeMismatch.monster.salary=\u85aa\u6c34\u683c\u5f0f\u4e0d\u6b63\u786e
(8)修改 monster_addUI.jsp 的 form ,回显错误信息
<form:form action="save" method="post" modelAttribute="monster">
妖怪id:<form:input path="id"/><form:errors path="id"/><br/><br/>
妖怪名字:<form:input path="name"/><form:errors path="name"/><br/><br/>
妖怪年龄:<form:input path="age"/><form:errors path="age"/><br/><br/>
妖怪生日:<form:input path="birthday"/><form:errors path="birthday"/>
要求以"yyyy-MM-dd"的格式<br/><br/>
妖怪工资:<form:input path="salary"/><form:errors path="salary"/>
要求以"###,###.##"的格式<br/><br/>
电子邮件:<form:input path="email"/><form:errors path="email"/><br/><br/>
<input type="submit" value="添加妖怪"/>
</form:form>
(9)再次进行测试
没有在properties文件中配置的提示,将会按照默认的错误信息回显
2.2细节说明和注意事项
在需要验证的 Javabean/POJO 的字段上添加相应的验证注解
目标方法上,在 Javabean/POJO 类型的参数前,添加 @Valid 注解以告知 SpringMVC 该 Bean 是需要验证的
在 @Valid 注解之后,添加一个 Errors 或 BindingResult 类型的参数,可以获取到验证的错误信息
校验的发生的时机:SpringMVC 底层反射调用目标方法前,会接收到 http 请求接收到的数据,然后根据验证注解来进行验证。在验证过程中,如果出现了错误,就把错误信息填充到 errors,map 等参数中
需要使用
<form:errors path="xxx"></form:errors>
标签来显示错误信息,该标签需要写在<form:form>
标签内生效自定义错误消息的国际化文件 i18n.properties,如果是中文需要使用 unicode 编码处理。
格式为:
验证规则.表单modelAttribute值.属性名=错误提示信息
注意@NotNull 和 @NotEmpty 的区别
@NotEmpty:
Asserts that the annotated string, collection, map or array is not {@code null} or empty.
@NotNull:
The annotated element must not be {@code null}. Accepts any type.
如果是字符串验证空,建议使用 @NotEmpty
SpringMVC 验证时,同一个属性,会根据不同的验证错误,返回不同的错误信息
3.注解的结合使用
day09-2-验证以及国际化的更多相关文章
- springBoot系列教程06:参数验证及验证信息国际化
在springboot应用中要验证参数是否正确很简单,web应用已经包含了validation的 1.定义需要被验证的参数实体,并用注解标明错误类别和错误信息 package com.xiao.dom ...
- SpringBoot学习之验证信息国际化
以登录为例: 1.controller的登录方法: @RequestMapping("/SSOAuth/login") @ResponseBody public ResponseV ...
- spring MVC 使用 hibernate validator验证框架,国际化配置
spring mvc使用hibernate validator框架可以实现的功能: 1. 注解java bean声明校验规则. 2. 添加message错误信息源实现国际化配置. 3. 结合sprin ...
- jQuery学习之:Validation表单验证插件
http://polaris.blog.51cto.com/1146394/258781/ 最近由于公司决定使用AJAX + Struts2来重构项目,让我仔细研究一下这两个,然后集中给同事讲讲,让每 ...
- Spring MVC -- 验证器
输入验证是Spring处理的最重要Web开发任务之一.在Spring MVC中,有两种方式可以验证输入,即利用Spring自带的验证框架,或者利用JSR 303实现.本篇博客将介绍这两种输入验证方法. ...
- SpringMVC表单验证器
本章讲解SpringMVC中怎么通过注解对表单参数进行验证. SpringBoot配置 使用springboot,spring-boot-starter-web会自动引入hiberante-valid ...
- [转载]一个标准java程序员的进阶过程
第一阶段:Java程序员 技术名称 内 容 说明 Java语法基础 基本语法.数组.类.继承.多态.抽象类.接口.object对象.常用类(Math\Arrarys\S ...
- Java技术体系图
Java程序员高级特性 反射.泛型.注释符.自动装箱和拆箱.枚举类.可变 参数.可变返回类型.增强循环.静态导入 核心编程 ...
- Struts2.X——搭建
今天是我第一次用博客,虽然还有好多的不懂,但是我还是会努力的把自己学到的写下来,分享给大家: 一,SSH框架中的struts2的搭建流程 1.在搭建struts2之前,我们首先要有struts2的ja ...
- 从程序员到CTO的Java技术路线图(我爱分享)
在技术方面无论我们怎么学习,总感觉需要提升自已不知道自己处于什么水平了.但如果有清晰的指示图供参考还是非常不错的,这样我们清楚的知道我们大概处于那个阶段和水平. Java程序员 高级特性 反射.泛型. ...
随机推荐
- 2022春每日一题:Day 11
题目:高斯消元法 高斯消元法是一个模板,下面简单介绍其内容以及实现方法. 高斯消元是求一个求多元一次方程组的解的算法. 就是形式如下的关于x1,x2...xn的方程组的解. a11x1 + a12x2 ...
- Go语言核心36讲33
我们在前几次讲的互斥锁.条件变量和原子操作都是最基本重要的同步工具.在Go语言中,除了通道之外,它们也算是最为常用的并发安全工具了. 说到通道,不知道你想过没有,之前在一些场合下里,我们使用通道的方式 ...
- 单节点部署 gpmall 商城
个人名片: 对人间的热爱与歌颂,可抵岁月冗长 Github:念舒_C.ying CSDN主页️:念舒_C.ying 个人博客 :念舒_C.ying 1 修改主机名: [root@localhost ...
- 视频超分之BasicVSR-阅读笔记
1.介绍 对于视频超分提出了很多方法,EDVR中采用了多尺度可变形对齐模块和多个注意层进行对齐和定位并且从不同的帧聚合特征,在RBPN中,多个投影模块用于顺序聚合多个帧中的特征.这样的设计是有效的,但 ...
- 【大数据课程】高途课程实践-Day01:Python编写Map Reduce函数实现各商品销售量展示(类似wordcount)
〇.概述 1.工具 http://www.dooccn.com/python3/ 在线运行Python代码 2.步骤 (1)⽣成代码测试数据 (2)编写Mapper逻辑 (3)编写Reducer逻辑 ...
- 线上服务异常的定位、处理与优化的探索 - 第三章 Java虚拟机
Java虚拟机 之所以引入关于JVM的篇章,是发现多数项目发生的线上问题很大的几率源自JVM调优配置不当引起.对JVM的内存模型.GC垃圾回收机制.调优方式有一个系统化的了解后,可以快速处理或避免 ...
- 【HarmonyOS】ArkTS Native开发——使用 system函数创建文件
ArkTS是HamronyOS优选的主力语言,但官方文档指南中对于Native应用开发并没有详细的描述,只有一篇Codelab可以学习(简易Native C++ 示例(ArkTS) (huawei ...
- 【leetcode】剑指offer04二维数组查找
很巧妙地把矩阵转化为二叉搜索树(不过好像没什用) class Solution { public: bool findNumberIn2DArray(vector<vector<int&g ...
- 巧如范金,精比琢玉,一分钟高效打造精美详实的Go语言技术简历(Golang1.18)
研发少闲月,九月人倍忙.又到了一年一度的"金九银十"秋招季,又到了写简历的时节,如果你还在用传统的Word文档寻找模板,然后默默耕耘,显然就有些落后于时代了,本次我们尝试使用云平台 ...
- 在windows上构建OpenCascade
基于作者QuaoarsWorkshop的视频Open Cascade Lessons,讲的非常详细,观看需要魔法 什么是OCCT?. 首先,Open CASCADE Technology SDK 是一 ...