9, Spring Boot data verification
9.1 what is data verification?
-
Data verification?
Data verification is to make semantic analysis and judgment on the input data in the application, block the data that does not conform to the rules, and release the data that conforms to the rules, so as to ensure that the saved data conforms to our data storage rules.
-
How to verify data?
There are two ways to do data verification in Spring MVC: one is Spring's own verification framework, and the other is to use JSR to realize data verification.
-
First acquaintance with JSR
JSR is the abbreviation of Java Specification Requests, which means Java specification proposal. It is a formal request to add a standardized technical specification to the JCP(Java Community Process). Anyone can submit a JSR to add new API s and services to the Java platform. JSR has become an important standard in the Java world.
In other words, JSR is just a specification. It provides a complete set of API s to add constraints by labeling object attributes. Hibernate Validator is the concrete implementation of all annotations of JSR specification. In addition, there are some additional constraint annotations. Of course, users can also customize constraint annotations.
9.2 JSR-303 calibration standard
JSR-303 is a sub specification in JAVAEE6, called the Bean Validation specification, which defines the metadata model and API for Bean Validation. The default metadata model is described by Annotations, but it can also be overloaded or extended by XML. We generally recommend using Annotations for verification.
Hibernate Validator is the reference implementation of Bean Validation. Hibernate Validator provides the implementation of all built-in constraints in JSR 303 specification. In addition, there are some additional constraints.
This implementation has nothing to do with Hibernate ORM. JSR 303 is used to validate the value of a field in a Java Bean. Spring MVC 3. JSR-303 is also strongly supported in X, which can directly verify the data submitted by the form in the controller.
9.3 JSR-303 common verification notes
Built in constraint in Bean Validation:
constraint | describe |
---|---|
@Null | The annotated element must be null |
@NotNull | The annotated element must not be null |
@AssertTrue | The annotated element must be true |
@AssertFalse | The annotated element must be false |
@Min(value) | The annotated element must be a number and its value must be greater than or equal to the specified minimum value |
@Max(value) | The annotated element must be a number and its value must be less than or equal to the specified maximum value |
@DecimalMin(value) | The annotated must be a number whose value must be greater than or equal to the specified minimum value |
@DecimalMax(value) | The annotated must be a number whose value must be less than or equal to the specified maximum value |
@Size(max,min) | The size of the annotated element must be within the specified range |
@Digits(integer,fraction) | The annotated element must be a number and its value must be within an acceptable range |
@Past | The annotated element must be a past date |
@Future | The annotated element must be a future date |
@Pattern(value) | The annotated element must conform to the specified regular expression |
constraint attached to Hibernate Validator:
constraint | describe |
---|---|
The annotated element must be an email address | |
@Length | The size of the annotated string must be within the specified range |
@NotEmpty | The annotated string must be non empty |
@Range | The annotated element must be within the appropriate range |
9.4 server side data verification based on Hibernate validator verification framework
In the actual development process, we will always encounter such a situation that users forget to enter their user name or password when logging in. At this time, our background does not allow users to log in directly. In view of these "careless" users, we must give them some reminders or warnings, that is, remind them that they can log in successfully only after completely and correctly entering their user name and password!
So, how to implement such data verification? The following code
-
Import dependent
Here is the implementation of data verification based on JSR-303, so these two dependencies must not be less! Otherwise, the verification will not take effect!!
<!--JSR-303 Calibration specification--> <dependency> <groupId>javax.validation</groupId> <artifactId>validation-api</artifactId> <version>2.0.1.Final</version> </dependency> <!--JSR-303 be based on Hibernate-validator Standardized data verification--> <dependency> <groupId>org.hibernate.validator</groupId> <artifactId>hibernate-validator</artifactId> <version>6.0.22.Final</version> </dependency>
-
Annotate some properties on the entity class SystemUserInfo
Because the attributes that may be used in the verification process are uncertain, I am generally used to adding annotations to all fields in case it needs to be modified many times in the future (whisper: if you are lazy, it is the same as Xiaobian, hahaha).
package cn.boot.pojo; import javax.validation.constraints.NotEmpty; import java.io.Serializable; public class SystemUserinfo implements Serializable { private String userinfoUid; @NotEmpty(message = "User name cannot be empty") private String userinfoLoginid; @NotEmpty(message = "Name cannot be empty") private String userinfoName; @NotEmpty(message = "Password cannot be empty") private String userinfoPassword; @NotEmpty(message = "Gender cannot be empty") private String userinfoSex; @NotEmpty(message = "Mailbox cannot be empty") private String userinfoEmail; @NotEmpty(message = "Mobile phone number cannot be empty") private String userinfoMobile; @NotEmpty(message = "Status cannot be empty") private Short userinfoStatus; @NotEmpty(message = "Role cannot be empty") private String userinfoRole; private SystemRole systemRole; }
-
Bind the verification information in the SystemUserinfoController class of the control layer
/** * Go to login page * @return */ @RequestMapping("/toLogin") public String toLogin(){ return "login"; } /** * Realize login * @param systemUserinfo * @param bindingResult * @param request * @return */ @RequestMapping("/doLogin") public String doLogin(@Valid SystemUserinfo systemUserinfo, BindingResult bindingResult, HttpServletRequest request){ //Is the current error if(bindingResult.hasErrors()) { List<ObjectError> listError = bindingResult.getAllErrors(); for (ObjectError objectError : listError) { FieldError fieldError = (FieldError) objectError; //fieldError. The key obtained by getfield () is equivalent to the key. The name of this key is the attribute name in the entity class. The information of the annotated value in the entity class is obtained through the key request.setAttribute(fieldError.getField(),objectError.getDefaultMessage()); } return "login"; }else { SystemUserinfo systemUserinfo1 = systemUserinfoService.login(systemUserinfo.getUserinfoLoginid(),systemUserinfo.getUserinfoPassword()); if (systemUserinfo1 == null) { request.setAttribute("MSG", "Wrong user name or password!"); return "login"; } return "redirect:/selectAllByJS"; } }
-
On the login page, login Display in HTML view
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns:th="http://www.thymeleaf.org"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>Yimai.com - home page</title> <link type="text/css" rel="stylesheet" href="css/style.css" /> <script type="text/javascript" src="scripts/function.js"></script> </head> <body> <div id="register" class="wrap"> <div class="shadow"> <em class="corner lb"></em> <em class="corner rt"></em> <div class="box"> <form id="loginForm" method="post" action="doLogin" onsubmit="return checkValidate()"> <table> <tr> <td class="field">user name:</td> <td><input class="text" type="text" id="userinfoLoginid" name="userinfoLoginid" onfocus="FocusItem(this)" onblur="CheckItem(this);" /><span style="display: inline-block" th:text="${userinfoLoginid}"></span></td> </tr> <tr> <td class="field">Login password:</td> <td><input class="text" type="password" id="userinfoPassword" name="userinfoPassword" onfocus="FocusItem(this)" onblur="CheckItem(this);" /><span style="display: inline-block" th:text="${userinfoPassword}"></span></td> </tr> <tr> <td></td> <td><label class="ui-green"><input type="submit" name="submit" value="Log in now" /> </label> <label th:text="${MSG}" style="color: red"></label> </td> </tr> </table> </form> </div> </div> <div class="clear"></div> </div> </body> </html>
9.5 group data verification
We verified the user name and password earlier. In the actual development process, it is inevitable to encounter the scenario of different verification rules for the attributes of an entity class and different requests.
For example, when a user registers, the user's id needs to be checked whether it is empty, because the unique id is often generated by the system itself. However, when the user changes the password, we need to pass in an id as the condition of the where statement to judge the update. At this time, we need to use group verification.
When grouping verification is required, we set the grouping of the verification annotation through the groups attribute in the annotation. The value of groups must be a class object. Generally, we create multiple empty interfaces for grouping. Of course, if there are many groups, the interface used to verify the group can be managed under the same class.
- Create related grouping interfaces
-
Interface for login:
package cn.boot.util; public interface LoginGroup { }
-
Interface to update users
package cn.boot.util; public interface UpdateGroup { }
-
Interface to add users
package cn.boot.util; public interface AddGroup { }
-
Annotation in entity class SystemUserInfo
The principle of grouping is to classify which attributes are used into one category.
package cn.boot.pojo; import cn.boot.util.AddGroup; import cn.boot.util.LoginGroup; import cn.boot.util.UpdateGroup; import javax.validation.constraints.NotEmpty; import java.io.Serializable; public class SystemUserinfo implements Serializable { private String userinfoUid; @NotEmpty(message = "User name cannot be empty",groups = {LoginGroup.class, UpdateGroup.class, AddGroup.class}) private String userinfoLoginid; @NotEmpty(message = "Name cannot be empty",groups = {UpdateGroup.class,AddGroup.class}) private String userinfoName; @NotEmpty(message = "Password cannot be empty",groups = {LoginGroup.class,UpdateGroup.class,AddGroup.class}) private String userinfoPassword; @NotEmpty(message = "Gender cannot be empty",groups = {UpdateGroup.class,AddGroup.class}) private String userinfoSex; @NotEmpty(message = "Mailbox cannot be empty",groups = {UpdateGroup.class,AddGroup.class}) private String userinfoEmail; @NotEmpty(message = "Mobile phone number cannot be empty",groups = {UpdateGroup.class,AddGroup.class}) private String userinfoMobile; @NotEmpty(message = "Status cannot be empty",groups = {UpdateGroup.class}) private Short userinfoStatus; @NotEmpty(message = "Role cannot be empty",groups = {UpdateGroup.class,AddGroup.class}) private String userinfoRole; private SystemRole systemRole; }
-
Bind the verification information in the SystemUserinfoController class of the control layer
-
Add user
/** * Add user information interface * @param request * @return */ @RequestMapping(method = RequestMethod.GET,value = "/toAddUserInfo") public String toAddUserInfo(HttpServletRequest request){ List<SystemRole> listRole = systemRoleService.selectAll(); request.setAttribute("listRole",listRole); return "ebuy/addUserinfo"; } /** * Add user information operation * @param systemUserinfo * @param request * @return */ @RequestMapping(method = RequestMethod.POST,value = "/doAddUserInfo") public String doAddUserInfo(@Validated(value = {AddGroup.class}) SystemUserinfo systemUserinfo, BindingResult bindingResult, HttpServletRequest request, ModelAndView modelAndView){ if (bindingResult.hasErrors()){ List<SystemRole> listRole = systemRoleService.selectAll(); request.setAttribute("listRole",listRole); List<ObjectError> listError = bindingResult.getAllErrors(); for (ObjectError objectError:listError){ FieldError fieldError = (FieldError) objectError; request.setAttribute(fieldError.getField(),objectError.getDefaultMessage()); } return "ebuy/addUserinfo"; }else{ int r = systemUserinfoService.insert(systemUserinfo); if (r == 1){ return "redirect:/selectAllByJS"; } request.setAttribute("msg","Failed to add user, please add again!"); return "ebuy/addUserinfo"; } }
-
Modify user information
/** * To update user page * @param userinfoUid * @param request * @return */ @RequestMapping(method = RequestMethod.GET,value = "/toUpdateUserInfo") public String toUpdateUserInfo(String userinfoUid,HttpServletRequest request){ SystemUserinfo systemUserinfo = systemUserinfoService.selectByPrimaryKey(userinfoUid); List<SystemRole> listRole = systemRoleService.selectAll(); request.setAttribute("listRole",listRole); request.setAttribute("systemUserinfo",systemUserinfo); return "ebuy/updateUserInfo"; } /** * Update user information operation * @param systemUserinfo * @param request * @return */ @RequestMapping(method = RequestMethod.POST,value = "/doUpdateUserInfo") public String doUpdateUserInfo(@Validated(value = {UpdateGroup.class}) SystemUserinfo systemUserinfo,BindingResult bindingResult, HttpServletRequest request) { if (bindingResult.hasErrors()) { List<SystemRole> listRole = systemRoleService.selectAll(); request.setAttribute("listRole", listRole); List<ObjectError> listError = bindingResult.getAllErrors(); for (ObjectError objectError:listError){ FieldError fieldError = (FieldError) objectError; request.setAttribute(fieldError.getField(),objectError.getDefaultMessage()); } return "ebuy/updateUserInfo"; } else { int r = systemUserinfoService.updateByPrimaryKey(systemUserinfo); if (r > 0) { return "redirect:/selectAllByJS"; } request.setAttribute("msg", "Failed to update user information!"); return "ebuy/updateUserInfo"; } }
- Show in view
-
Add user adduserinfo html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Add user information</title> </head> <body> <div style="color: red" th:text="${msg}"></div> <div style="width: 700px;margin: 50px auto;"> <form method="post" action="doAddUserInfo"> Login name:<input type="text" name="userinfoLoginid" /> <span style="color: red" th:text="${userinfoLoginid}"></span> <br/><br/> full name:<input type="text" name="userinfoName" /> <span style="color: red" th:text="${userinfoName}"></span> <br/><br/> password:<input type="password" name="userinfoPassword" /> <span style="color: red" th:text="${userinfoPassword}"></span> <br/><br/> Gender: <input type="radio" name="userinfoSex" value="male" />male <input type="radio" name="userinfoSex" value="female"/> female <span style="color: red" th:text="${userinfoSex}"></span> <br/><br/> Email:<input type="text" name="userinfoEmail" /> <span style="color: red" th:text="${userinfoEmail}"></span> <br/><br/> Telephone:<input type="text" name="userinfoMobile" /> <span style="color: red" th:text="${userinfoMobile}"></span> <br/><br/> Role: <select name="userinfoRole" > <option value="">--Please select--</option> <option th:each="role:${listRole}" th:value="${role.roleId}" th:text="${role.roleName}"></option> </select> <span style="color: red" th:text="${userinfoRole}"></span> <br/><br/> <input type="submit" value="preservation"/> </form> </div> </body> </html>
-
Update user information updateuserinfo html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Update user information</title> </head> <body> <div style="color: red" th:text="${msg}"></div> <div style="width: 700px;margin: 50px auto;"> <form method="post" action="doUpdateUserInfo"> <input type="hidden" id="userinfoUid" name="userinfoUid" th:value="${systemUserinfo.userinfoUid}"/> Login name:<input type="text" id="userinfoLoginid" name="userinfoLoginid" th:value="${systemUserinfo.userinfoLoginid}"/> <span style="color: red" th:text="${userinfoLoginid}"></span> <br/><br/> full name:<input type="text" id="userinfoName" name="userinfoName" th:value="${systemUserinfo.userinfoName}"/> <span style="color: red" th:text="${userinfoName}"></span> <br/><br/> password:<input type="password" id="userinfoPassword" name="userinfoPassword" th:value="${systemUserinfo.userinfoPassword}"/> <span style="color: red" th:text="${userinfoPassword}"></span> <br/><br/> Gender: <input type="radio" name="userinfoSex" value="male" th:checked="${systemUserinfo.userinfoSex}==male"/>male <input type="radio" name="userinfoSex" value="female" th:checked="${systemUserinfo.userinfoSex}==female"/>female <span style="color: red" th:text="${userinfoSex}"></span> <br/><br/> Email:<input type="text" name="userinfoEmail" th:value="${systemUserinfo.userinfoEmail}"/> <span style="color: red" th:text="${userinfoEmail}"></span> <br/><br/> Telephone:<input type="text" name="userinfoMobile" th:value="${systemUserinfo.userinfoMobile}"/> <span style="color: red" th:text="${userinfoMobile}"></span> <br/><br/> Role: <select name="userinfoRole" > <option th:each="role:${listRole}" th:value="${role.roleId}" th:text="${role.roleName}"></option> </select> <span style="color: red" th:text="${userinfoRole}"></span> <br/><br/> <input type="submit" value="to update"/> </form> </div> </body> </html>