SpringMVC中实现Bean Validation(JSR 303 JSR 349 JSR 380)
JSR 303是针对bean数据校验提出的一个规范。使用注解方式实现数据校验。
每个注解的用法这里就不多介绍,请移步JSR 303 - Bean Validation 介绍及最佳实践
笔者上面提到的JSR303是专家组成员向JCP提交的第一版Bean Validation,
主流Bean Validation使用Hibernate的实现,本文使用hibernate-validator
各个版本的规范对应关系如下:
- JSR 380 (Bean Validation 2.0)
- JSR 349 (Bean Validation 1.1)
- JSR 303 (Bean Validation 1.0)
JSR 303伴随着JAVAEE 6在2009年发布,Hibernate实现版本4.3.1.Final,Apache BVal实现版本0.5
JSR349伴随着JAVAEE 7在2013年发布,Hibernate实现版本5.1.1.Final,Apache BVal实现版本1.1.2
JSR380伴随着JAVAEE 8在2017年8月发布,完全兼容低版本的JAVASE,Hibernate实现版本6.0.1.Final,Apache BVal实现版本2.0.3(不太确定)
所以如果使用2.0规范,hibernate必须选择6.0.1以上版本
以下是Springmvc中Bean Validation配置过程:
1、在maven中添加规范与实现,缺一不可
<!--bean validation规范-->
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
<version>2.0.1.Final</version>
</dependency>
<!--bean validation规范实现-->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>6.0.17.Final</version>
</dependency>
2、在实体类类上使用注解
public class Post implements Serializable {
private Integer pid;
@Size(min = 5, message = "标题太短,无效,长度必须大于5")
private String title;
@Size(min = 20, message = "内容太短无效,长度必须大于20")
private String content;
//两个时间
private LocalDateTime publishTime;
private LocalDateTime replyTime;
//三个数量
private Integer replyCount;
private Integer likeCount;
private Integer scanCount;
//两个外键
private Integer uid;
private User user;
@Min(value = 1,message = "请选择话题分类") //话题分类id必须大于0
private Integer tid;
private Topic topic;
3、在Controller添加代码(@Valid @ModelAttribute)
@RequestMapping("publishPost.do")
public String publishPost(@Valid @ModelAttribute Post post,
BindingResult bindingResult,
Errors errors, Model model,String action) {
model.addAttribute("post",post);
model.addAttribute("action",action);
if(errors.hasErrors()){
FieldError fieldError = bindingResult.getFieldError();
System.out.println("Code:"+fieldError.getCode()+", object:"+fieldError.getObjectName()
+", field:"+fieldError.getField());
List<Topic> topicList = topicService.listTopic();
model.addAttribute("topicList",topicList);
return "post/editor";
}
spring-mvc.xml配置
<bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean" />
前端代码:
<%@ page contentType="text/html;charset=UTF-8" pageEncoding="UTF-8" trimDirectiveWhitespaces="true"%>
<%@ taglib uri="http://www.springframework.org/tags/form" prefix="form"%> <form:form action="publishPost.do" method="post" commandName="post">
<input type="hidden" name="uid" value="${post.uid}">
<input type="hidden" name="pid" value="${post.pid}">
<%--<input type="hidden" name="user.uid" value="${post.uid}">--%>
<input type="hidden" name="action" value="${action}">
<div class="pub-header"><span></span> 话题发布</div>
<div class="pub-title">
<form:input path="title" placeholder="标题:一句话说明你遇到的问题或想分享的经验"/>
<form:errors path="title" cssClass="has-error" element="div"/>
${error}
</div>
<div class="pub-topic">
<span>分类:</span>
<div class="topic-list">
<form:select path="tid">
<form:option value="0">--请选择--</form:option>
<c:forEach items="${topicList}" var="topic">
<option value="${topic.tid}" title="${topic.tid}"${topic.tid eq post.tid?'selected':''}>${topic.name}</option>
</c:forEach>
</form:select>
<form:errors path="tid" cssClass="has-error" element="div"/>
</div>
</div> <div class="pub-textarea">
<div style="width: 920px;">
<form:textarea path="content" id="textarea" cssStyle="height: 300px;max-height: 1000px;"></form:textarea>
<form:errors path="content" cssClass="has-error" element="div"/>
</div>
<button class="pub-button">发布</button>
</div>
</form:form>
效果

更新:
对于待校验的Bean属性,一定要使用NotNull约束。否则bean属性为null,也不会报错,插入数据时候就出错了,出现dao错误,让人摸不着头脑

更新后的JavaBean如下
package com.fc.model; import lombok.Data;
import lombok.NoArgsConstructor; import javax.validation.constraints.Min;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import java.io.Serializable;
import java.time.LocalDateTime; @Data
@NoArgsConstructor
public class Post implements Serializable {
private Integer pid; @Size(min = 5, message = "标题太短,无效,长度必须大于5")
@NotNull(message = "标题必填")
private String title; @Size(min = 20, message = "内容太短无效,长度必须大于20")
@NotNull(message = "内容必填")
private String content; //两个时间
private LocalDateTime publishTime;
private LocalDateTime replyTime; //三个数量
private Integer replyCount;
private Integer likeCount;
private Integer scanCount; //两个外键
private Integer uid;
private User user; @Min(value = 1,message = "请选择话题分类") //话题分类id必须大于0
@NotNull(message = "分类必选")
private Integer tid;
private Topic topic; private Post(Builder builder) {
setPid(builder.pid);
setUid(builder.uid);
setTid(builder.tid);
} @Override
public String toString() {
return "Post{" +
"pid=" + pid +
", title='" + title + '\'' +
", content='" + content + '\'' +
", publishTime='" + publishTime + '\'' +
", replyTime='" + replyTime + '\'' +
", replyCount=" + replyCount +
", likeCount=" + likeCount +
", scanCount=" + scanCount +
", user=" + user +
", topic=" + topic +
'}';
} public static final class Builder {
private Integer pid;
private Integer uid;
private Integer tid; public Builder() {
} public Builder pid(Integer pid) {
this.pid = pid;
return this;
} public Builder uid(Integer uid) {
this.uid = uid;
return this;
} public Builder tid(Integer tid) {
this.tid = tid;
return this;
} public Post build() {
return new Post(this);
}
}
}
校验代码:
//发帖
@RequestMapping("publishPost.do")
public String publishPost(@Valid Post post,
BindingResult bindingResult,
Errors errors, Model model,String action) { model.addAttribute("post",post);
model.addAttribute("action",action); if(errors.hasErrors()){
FieldError fieldError = bindingResult.getFieldError();
System.out.println("Code:"+fieldError.getCode()+", object:"+fieldError.getObjectName()
+", field:"+fieldError.getField());
List<Topic> topicList = topicService.listTopic();
model.addAttribute("post",post);
model.addAttribute("topicList",topicList);
return "post/editor";
} //更新文章
if("edit".equals(action)) {
int effected = postService.updatePost(post); if(effected == 0)
{
model.addAttribute("topicList",topicService.listTopic());
model.addAttribute("error","更新失败");
return "post/editor";
}
} //默认新增文章
Integer id = postService.publishPost(post);
return "redirect:post.do?pid=" + id;
}
参考内容:
https://blog.csdn.net/w_linux/article/details/80585468
https://docs.spring.io/spring/docs/3.0.0.RC2/spring-framework-reference/html/ch05s07.html
https://www.boraji.com/spring-4-mvc-form-validation-example-using-hibernate-validator
https://docs.spring.io/spring/docs/4.3.x/spring-framework-reference/html/validation.html
https://howtodoinjava.com/spring-mvc/spring-bean-validation-example-with-jsr-303-annotations/
https://www.iteye.com/blog/jinnianshilongnian-1990081
SpringMVC中实现Bean Validation(JSR 303 JSR 349 JSR 380)的更多相关文章
- 在系统中使用Bean Validation验证参数
转自:http://www.importnew.com/18561.html 为什么要使用Bean Validation? 当我们实现某个接口时,都需要对入参数进行校验.例如下面的代码 1 2 3 ...
- SpringMVC中使用bean来接收form表单提交的参数时的注意点
这是前辈们对于SpringMVC接收表单数据记录下来的总结经验: SpringMVC接收页面表单参数 springmvc请求参数获取的几种方法 下面是我自己在使用时发现的,前辈们没有记录的细节和注意点 ...
- springMvc中自定义bean转换接收前台传的参数
转载:https://blog.csdn.net/u013476435/article/details/81538099 因前端整体传参时,参数名都不是驼峰写法,类似 music_name,music ...
- JSR 303 - Bean Validation 介绍及最佳实践
JSR 303 - Bean Validation 介绍及最佳实践 JSR 303 – Bean Validation 是一个数据验证的规范,2009 年 11 月确定最终方案.2009 年 12 月 ...
- JSR教程1——JSR 303 - Bean Validation介绍
1.Bean Validation 在任何时候,当你要处理一个应用程序的业务逻辑,数据校验是你必须要考虑和面对的事情.应用程序必须通过某种手段来确保输入进来的数据从语义上来讲是正确的.在通常的情况下, ...
- JSR 303 - Bean Validation 介绍及最佳实践(转)
JSR 303 – Bean Validation 是一个数据验证的规范,2009 年 11 月确定最终方案.2009 年 12 月 Java EE 6 发布,Bean Validation 作为一个 ...
- 利用 Bean Validation 来简化接口请求参数校验
团队新来了个校招实习生静静,相互交流后发现竟然是我母校同实验室的小学妹,小学妹很热情地认下了我这个失散多年的大湿哥,后来... 小学妹:大湿哥,咱们项目里的 Controller 怎么都看不到参数校验 ...
- SpringMVC中的 JSR 303 数据校验框架说明
JSR 303 是java为Bean数据合法性校验提供的标准框架,它已经包含在JavaEE 6.0中. JSR 303 通过在Bean属性上标注类似于@NotNull.@Max等标准的注解指定校验规则 ...
- JSR 303 - Bean Validation 是什么?
关于 Bean Validation JSR 303 - Bean Validation 是jree6 中的一项子规范,JSR 303 - Bean Validation着重解决以下实际问题: 在任何 ...
随机推荐
- MYSQL8.0+ 使用JDBC查询中文乱码的问题
在建表时,附加一句 DROP TABLE IF EXISTS `sys_table`;CREATE TABLE `sys_table` ( ... ) ENGINE=InnoDB DEFAULT CH ...
- [SDOI2010]代码拍卖会——DP
原题戳这里 绝对是一道好题 需要注意到两个东西 1.符合条件的数可以拆成一堆\(11...11\)相加的形式,比如\(1145=1111+11+11+11+1\) 2.\(1,11,111,1111, ...
- Series拼接回DataFrame
从这样的表,如何计算一行汇总层拼接回去
- [2019HDU多校第一场][HDU 6578][A. Blank]
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6578 题目大意:长度为\(n\)的数组要求分别填入\(\{0,1,2,3\}\)四个数中的任意一个,有 ...
- 在当前目录下配置ansible
配置ansible.cfg [defaults] inventory = myhost # 指定主机清单文件 host_key_checking = False 配置主机清单文件 [node] nod ...
- nginx+tomcat遇到的https重定向到http问题
nginx做反向代理时,需要把请求头信息一起发送给tomcat,不然tomcat中的域名绑定就无法发挥作用了. 今天又遇到https请求被拦截器重定向到登陆页居然变成http的问题,导致小程序无法访问 ...
- net core 3 使用 autofac
参考官方:https://docs.autofac.org/en/latest/integration/aspnetcore.html#startup-class 有一些变动,现在暂时还没用net c ...
- 关于单片机特殊功能寄存器(SFR)和内存(RAM)公用地址:80-FF 如何区分
RAM 的 80-FF 需要间接寻址进行访问 如: MOV R0,#80H; MOV A,@R0 ; (内存 80H地址内的数据放到A中) SFR的80-FF需要直接寻址进行访问如: MOV ...
- [Luogu] 引水入城
https://www.luogu.org/problemnew/show/P1514 bfs + 线段覆盖 #include<bits/stdc++.h> using namespace ...
- 集合家族——LinkedList
一.概述: LinkedList 与 ArrayList 一样实现 List 接口,只是 ArrayList 是 List 接口的大小可变数组的实现,LinkedList 是 List 接口链表的实现 ...