SPRINGMVC integrated Hibernate validator for annotation-type parameter checking
--Get less code and focus more on business logic
1 issue background:
Parameter validation is a common problem, such as verifying that the password entered by the user is empty, that the mailbox is legitimate, and so on. However, both the front end and the backend need to verify the user input to ensure the correctness of the system data. For the web, some people may take it for granted that the front-end verification is OK, but this is a very wrong approach, the front desk verification is generally through the JAVASCRIPT,JS code can be disabled and tampered with, so relative to the background test, the security will be lower. The front-end code is transparent to the user, and a slightly technical person can bypass this verification and submit the data directly to the backend. Whether it is the interface of the front-end Web page submission or the interface provided to the external, parameter validation is ubiquitous and essential. In short, all user input is not trustworthy.
Based on this common sense, in the backend code development, parameter checking is a topic that can never be opened. However, the process of writing parameter check code is a low technical content, and it is time consuming and tedious process. For example, most of the parameters check code is: To determine whether the user name is already present, the length of the user name to meet the requirements, the user filled out the mailbox is legitimate. The age parameter is not an integer and so on. In order to reduce the development of repetitive code, many companies with technical accumulation will generally provide one or more sets of unique parameter checking tool classes. This reduces the amount of code. This approach is very common in projects, and with these tools libraries, programmers can greatly improve their productivity while writing business code.
However, even if smart as described above, our business logic still can see a lot of parameter check logic, if the project structure is not reasonable, these parameters and parameter check logic related to the amount of code will be more, really xxx binding cloth, smelly and long. A large number of complex parameter check code mixed in the business logic, one to reduce the readability of the code, and the second is to make the business itself more difficult to understand, many people just joined the company is often through reading code to understand the business, some of the company's business training can only speak a general, but in the process of reading the code will be these "Extra" code to disrupt the idea, for the novice, that is an abnormal nightmare, if the old staff resigned, let go of the new, such a project can be maintained is a problem.
2 Hibernate Validator Introduction:
But it's getting easier for Java developers to solve these challenges. With the advent of a large number of bean Validation frameworks, and the mainstream framework for the integration and support of these calibration frameworks. We are very easy to separate the business logic and parameter check code, in fact, is not enough separation is not appropriate, here is about to introduce the Hibernate validator can be annotated to verify the parameters, the business logic of the large majority of parameters check code can be omitted, can make the code more concise and focus more on business logic. Hibernate Validator is a reference implementation of Bean Validation, and Hibernate Validator provides all the built-in constraint implementations of the JSR 303 specification, plus some additional constraint. To meet specific needs, users can also self-implement more constraint to meet specific needs.
3 Set Hibernate validator before and after code comparison:
In order to see the benefits of integrating hibernate validator at a glance, let's compare the following code. Suppose we have a method that extracts from the controller layer of a SSM (Spring MVC + spring + Mybatis) project. The purpose of this method is to query all names of male or female compatriots named XXX. The name parameter name cannot be a null value, and the gender parameter gender must be "F" or "M", respectively, to represent the female or male. Note that the sample code here puts the parameter check logic in the controller layer, and the validation passes before it enters the service layer. There may be projects that move parameters to the service layer, which is of course not the point. The code for this query method is as follows:
@RequestMapping (value = "/all", method = Requestmethod.get)
@ResponseBody public
list<string> Getallpeople (string name, String gender) {
if (stringutils.isempty (name)) {
throw new businessexception (FALL, " User name cannot be empty ");
}
if (gender = = NULL | | (!gender.equals ("F") &&!gender.equals ("M")) {
throw new businessexception (FALL, "sex is not legal");
}
Return Cityservice.getallcitys (name, gender);
}
The above query method is in a project without integrated hibernate validator, the general way of parameter check, in order to assist the completion of parameter verification, we also have to encapsulate a tool class stringutils to determine whether the string is empty. If the parameter is abnormal, a business exception is thrown and the exception is passed to the framework's exception handling mechanism for processing. We can see that only two simple parameters have to be written on multiple lines of code to complete the requirements. However, when we integrate the above SSM project with Hibernate validator, the parameter check can be done in the method signature, and the method body does not have to write any code logic related to the parameter check. If the parameter check does not pass, it also throws an exception, and the exception is also given to the framework's exception handling mechanism for processing.
@RequestMapping (value = "/all", method = Requestmethod.get)
@ResponseBody public
list<string> Getallpeople (
@NotBlank (message = "User name cannot be empty") string name,
@Gender (message = "Gender Not valid") string Gender) {
Return Cityservice.getallcitys (name, gender);
}
Through the comparison of the above code, it is obvious that the latter code is a lot more concise, in the number of parameters, business complex methods, the difference in code volume will be more obvious, the same, the readability of the code will also have a different.
4. Spring MVC integrated Hibernate validator steps:
4.1 If you use MAVEN in your project, you need to add the following paragraph in Pom.xml, Hibernate requires a Java El expression, so you need to add El Dependencies.
<dependency>
<groupId>org.hibernate</groupId>
<artifactid>hibernate-validator </artifactId>
<version>5.3.4.Final</version>
</dependency>
<dependency >
<groupId>javax.el</groupId>
<artifactId>javax.el-api</artifactId>
<version>2.2.4</version>
</dependency>
<dependency>
<groupId> org.glassfish.web</groupid>
<artifactId>javax.el</artifactId>
<version>2.2.4 </version>
</dependency>
4.2 In the SPRINGMVC configuration file (here using the default name: Spring-mvc.xml) to add the following configuration to turn on the check function
<mvc:annotation-driven validator= "validator"/> <!--the parameter bean in the bean-level method must be added @val ID note, followed by Bindingresult result parameter--<bean id= "validator" class= "Org.springframework.validation.beanvalid ation. Localvalidatorfactorybean "> <property name=" providerclass "value=" Org.hibernate.validator.HibernateValidato R "/> </bean> <!--Method-level checksum for the method in which the class must be added @validated annotations--<bean class=" Org.springframe Work.validation.beanvalidation.MethodValidationPostProcessor "> <!--can reference your own validator configuration, which can be found in this article (below) Valida Tor's reference configuration, if not specified, the system uses the default--<property name= "validator" ref= "validator"/> </bean>
4.3 Adding @validated Annotations to the class on which the checksum is located can turn on method-level validation, 3rd code comparison sake, parameter check annotations directly before the method parameters on the method signature, which is called method-level validation. The so-called Bean-level check is that the parameter of the method is a Java bean, and the annotated annotation is added to the corresponding property of the Java bean. Currently, in a project that uses spring MVC, the bean-level checksum must add @valid annotations to the bean parameters. However, there is no requirement to replace the Spring MVC Project with Jersey, a standard implementation framework for rest full. So the code will be more convenient. Introduction to the
5 built-in constraint in Hibernate Validator
Annotation Effect
@Valid The annotated element is an object that needs to be checked for all field values of this object
@Null The annotated element must be Null
@NotNull 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 whose value must be greater than or equal to the specified minimum value
@Max (value) The annotated element must be a number whose value must be less than or equal to the specified maximum value
@DecimalMin (value) The annotated element must be a number whose value must be greater than or equal to the specified minimum value
@DecimalMax (value) The annotated element 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 whose 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
6 custom Check Annotation example
6.1 In the 3rd section, we used the @gender annotation to denote the gender of both sexes, which is not actually a hibernate validator, but a custom annotation. Since standard annotations in HV may not meet certain validation scenarios, it is necessary to customize the validation annotations. The purpose of this article is to recommend the company's projects can also try to use this excellent bean validation framework, so the implementation details of the custom annotations are not described here, just give two of the implementation of the illustration, one is used before the annotated @gender, used to verify the gender of the user. Another annotation is @phonenumber, which restricts the upload parameter to a mobile phone number.
6.2 @Gender Annotation Class code is as follows:
@Retention (retentionpolicy.runtime)
@Constraint (Validatedby = Gender.Validator.class)
@SuppressWarnings ( "Javadoc") public
@interface Gender
{
String message () default "Invalid Gender";
Boolean Allowblank () default false;
Class<?>[] Groups () default {};
class<? Extends payload>[] Payload () default{};
public class Validator implements Constraintvalidator<gender, String>
{
Boolean allowblank;
@Override public
Void Initialize (Gender Gender)
{
Allowblank = Gender.allowblank ();
}
@Override Public
Boolean isValid (String arg0, Constraintvalidatorcontext arg1)
{
if (arg0 = = null)
{
return allowblank;
}
Return Arg0.equalsignorecase ("M") | | Arg0.equalsignorecase ("F");}}}
6.2 @PhoneNumber notes are as follows:
@Retention (retentionpolicy.runtime)
@Constraint (Validatedby = PhoneNumber.Validator.class)
@ Suppresswarnings ("Javadoc") public
@interface PhoneNumber {
String message () default "invalid phone number";
Class<?>[] Groups () default {};
class<? Extends payload>[] Payload () default {};
public class Validator implements Constraintvalidator<phonenumber, string> {
@Override public
Void Initialize (PhoneNumber arg0)
{
}
@Override public
boolean isValid (String arg0, Constraintvalidatorcontext arg1)
{
return stringutil.isphonenumber (arg0);}}
}
The Isphonenumber method for the tool class Stringutil used in @PhoneNumber annotations is as follows:
Public final String PHONE = "^ ((13[0-9]) | ( 14[5,7]) | (15[^4,\\d]) | (17[0,5-8]) | (18[0-9])) \\d{8}$ ";
public static Boolean Isphonenumber (String phone)
{
if (stringutil.isnullorempty (phone))
{
return false;
}
Return match (Regexp.phone, PHONE);
}
7 Simple Summary
This paper mainly introduces the excellent bean validation framework of Hibernate validator. This paper also introduces how to integrate this parameter check box in spring MVC to separate the business logic from the parameter check logic to keep the code streamlined and elegant. Easy to read and maintain. I used this approach to multiple projects in my previous company, making the project code incredibly refreshing. I am also willing to share their accumulated a little bit of knowledge, if the technology involved in this article and the previous article on the experience of the contents of the joint use, will make the project more color, I hope in the follow-up project, I can witness the application of this mature technology.