Jordan is the basketball god I have heard of, Kobe is the basketball god I have seen. This article has been
https://www.yourbatman.cnIncluded, which together with the Spring technology stack, MyBatis, JVM, middleware and other small and beautiful
columnFor free learning. Follow the public account [
The Utopia of BAT【 break down one by one, thoroughly grasp, refuse to be tasted.

The foreword ✍

Hello, I’m YourBatman.

As a developer, I’m familiar with Bean Validation from front, middle, and back ends.

Indeed, verifying data is a programmer’s basic quality. It’s not difficult but it happens almost everywhere in our programs, as shown in the picture below:Each layer needs to be calibrated.



If you actually write the code this way (one for each layer), it’s not going to be appropriate, but it should look something like this:

As a Java developer, in the days of Spring, many of you know that data validation comes from the Spring MVC scenario, or even stops there. However, Java EE has abstracted it into the JSR standard technology, and Spring has redeemed itself by integrating it.

In my opinion, compared with the 3C strategic standard of Spring, the Bean Validation data Validation section fails to surpass the traditional Java EE, and its design is characterized by over-design and over-design.

This column is called Bean Validation and will start with the JSR standard and then delve into implementing Hibernate Validation, integrating Spring usage scenarios, and more. So this column will give you a knowledge of system data validation.

✍ body

At all timesWhen dealing with an application’s business logic, data validation is something you must consider and face. The application must passSome meansTo ensure that the input data is semantically correct, such as the birthday must be past tense, the age must be >0, etc.

Why do we need data validation?

Data validation is a very common work, which runs through all levels of code in daily development, from the upper View layer to the back-end business processing layer, and even the bottom data layer.

We know that programs are often layered, and that different layers may be developed or invoked by different people. If you’re an experienced programmer, I’m sure you’ve seen the same validation code on different layers, which is some kind of junk code:

public String queryValueByKey(String zhName, String enName, Integer age) { checkNotNull(zhName, "zhName must be not null"); checkNotNull(enName, "enName must be not null"); checkNotNull(age, "age must be not null"); validAge(age, "age must be positive"); . }

From this simple method, at least the following problems can be found:

  1. You need to write a lot of code to do basic parameter validation (more code like this is junk code)
  2. You need to use a literal comment to know what the constraint on each input parameter is (otherwise people will understand it).
  3. Each programmer may do parameter validation differently and throw different exceptions, making it almost unmaintainable later

This leads to code redundancy and administrative issues such as semantic consistency (the larger the code, the harder it is to manage and maintain). In order to avoid this situation, it is best to bind the Validation logic to the corresponding domain model, which is the new approach we will introduce in this article: Bean Validation.

About the Jakarta EE

In March 2018, Oracle decided to hand over JavaEE to open source organizationsThe Eclipse foundation, and no longer use the Java EE name. Here’s its new logo:

Corresponding name changes also include:

The old name The new name
Java EE Jakarta EE
Glassfish Eclipse Glassfish
Java Community Process (JCP) Eclipse EE.next Working Group (EE.next)
Oracle development management Eclipse Enterprise for Java (EE4J) and Project Management Committee (PMC)

The JCP will continue to support the Java SE community. However, the Jakarta EE specification will not be developed under the JCP thereafter. The Jakarta EE standard is probably developed by Eclipse Glassfish, Apache Tomee, Wildfly, Oracle WebLogic, JBoss, IBM, WebSphere Liberty, etc

The migration

Now that the name has been changed, the next step is to migrate, since the Java EE name (the javax package name) can no longer be used. The first Enterprise Java release after Eclipse takes over will be Jakarta EE 9, which will use Java EE 8 as its base release (Java8 is the minimum version requirement).

The interesting thing is that Java EE 8 was released on 2019.09.10, but the official name is actually Jakarta EE 8. It is clear that this version was not designed or developed by the new organization, and is not their product. However, the platform had been renamed Jakarta for a few months, so for some JARs you will often see two types of coordinates in the Maven marketplace:

< the dependency > < groupId > javax.mail. Validation < / groupId > < artifactId > validation - API < / artifactId > < version > 2.0.1. The Final < / version > </dependency> <dependency> <groupId>jakarta.validation</groupId> <artifactId>jakarta.validation-api</artifactId> The < version > 2.0.1 < / version > < / dependency >

Although the coordinates are different, the content is 100% the same (package names are still javax.*), which is clearly a transition period for a full name change in the future.

Strictly speaking: As long as the major version number (the first number) remains the same, the package name is
Can’t beVariable, so generally have downward compatibility

Now that Jakarta has signalled a name change, a complete change is the next step. Sure enough, all of this was implemented in Jakarta EE 9.

Jakarta EE 9

On August 31, 2020.08.31, Jakarta EE 9, the first enterprise platform after Jakarta, was released. If Jakarta EE 8 is just a name, then this one deserves its name.

Tip: As I write this, it’s not yet 2020.08.31, which is from my party on the website, so it must be accurate

The biggest highlight of this enterprise platform upgrade is:

  1. +1 for all major versions of 30 technologies (except Jakarta RESTful Web Services)
  2. The package nameallGo to thejavax.*Change, all changed tojakarta.*
  3. The JavaSE base version is still required to be Java 8 (not Java9)

You can see that the main purpose of this upgrade is to focus on feature points, which are still name changes. Although there are deep stories about Java EE’s Javax, the old will die and the new will come. Don’t be surprised if we come across a package name like Jakarta in future development.* It’s always good to be prepared.

Jakarta Bean Validation

Jakarta Bean Validation is not just a specification, it is an ecology.

Java Bean Validation will be changed to Jakarta Bean Validation after March 2018

Well, it’s already called this on the official website:

The Bean Validation technique is part of the Java EE specification and contains multiple JSRs (Java Specification Requests), there have been three JSR standard releases as of this draft:



The JCP is the organization that defines the Java standard. Most of the most famous companies in the Java industry are members of the JCP. They can participate in the development of the Java standard and influence the world. Including Oracle, as well as Eclipse, RedHat, JetBrains, and more. China can be proud of this: May 17, 2018Alibaba officially joined the JCP as a member, making it the only Chinese company.

Bean Validation is the standard, and its reference implementation includes Apache BVal in addition to the familiar Hibernate Validator, but the latter is used in a very niche way, so forget about it. In practice, you can almost assume that Hibernate Validator is the only reference implementation to the Bean Validation specification and is an equivalent.

Tips: Apache BVal is more lightweight than Apache BVal. It only has less than 1M space, so it is very lightweight. Some players like it (this project is still in development, it is still in progress, you can try it yourself if you are interested)

JSR303

This JSR was proposed a long time ago (2009) and defines a metadata model and API for annotation-based JavaBeans validation, overwriting and extending the metadata using XML validation descriptors. JSR-303 mainly validates JavaBeans, such as method level (method parameters/return values), dependency injection, etc. Validations are not specified.

As a starting point, it specifies the model and API for Java data Validation, which is Java Bean Validation version 1.0.

< the dependency > < groupId > javax.mail. Validation < / groupId > < artifactId > validation - API < / artifactId > < version > 1.0.0. GA < / version > </dependency>

This version provides common validation annotations (13 in total) :

annotations Support types meaning Whether the null value is validated
@AssertFalse bool The element must be false no
@AssertTrue bool The element must be true no
@DecimalMax Subtypes of Number (except floating-point numbers) and String The element must be a number, and the value must <= the maximum no
@DecimalMin Same as above The element must be a number, and the value must be >= the maximum no
@Max Same as above Same as above no
@Min Same as above Same as above no
@Digits Same as above Is the element composition legal (integer part and decimal part) no
@Future Time type (including JSR310) The element must be oneIn the future(does not contain equality) date (accurate to milliseconds) no
@Past Same as above The element must be oneIn the past(does not contain equality) date (accurate to milliseconds) no
@NotNull any The element cannot be NULL is
@Null any The element must be null is
@Pattern string The element must conform to the specified regular expression no
@Size String/Collection/Map/Array The elementThe size of theMust be in the specified range no

All annotations can be annotated in: methods, fields, annotations, constructors, inputs, almost anywhere

As you can see, these are some of the most common annotations in your development, but there are a few things you should keep in mind when using them:

  1. All of the above annotations are NULL immune, meaning that if you set a value to NULL, it will not trigger the corresponding validation logic (i.e. it is valid), except for @NotNull / @Null
  2. For time-type validation annotations (@Future/@Past), it is an open interval (does not contain equality). In other words: if equal is illegal, it must be greater than or less than

    1. This case is more likely to occur on LocalDate, where only a date exists. It must be a future/past date. The date is illegal
  3. @DigitsIt does not define the range of numbers, only their structure. For example, the maximum number of integer digits, the maximum number of decimal digits
  4. @SizeSpecifies a range of collection types, including strings. The range isClosed interval
  5. @DecimalMax and @Max are basically similar and can be used in most cases. The difference is that @DecimalMax sets the maximum value as a string (as long as it is legitimate, such as a scientific count), while @Max is set as a LONG

    1. Personally, I usually use @max, because that’s enough ~

Other people might ask: Why didn’t you see @notempty, @email, @positive and other common annotations? So keep reading with interest and questions

JSR349

This specification, completed in 2013 and released with Java EE 7, is known as Bean Validation 1.1.

< the dependency > < groupId > javax.mail. Validation < / groupId > < artifactId > validation - API < / artifactId > < version > 1.1.0. The Final < / version > </dependency>

There are several major improvements/optimizations over version 1.0:

  1. Standardized constraint definition, description, and validation for the Java platform
  2. Support for method-level validation (validation of incoming or return values)
  3. The Bean validates the dependency injection of the component
  4. Integration with context and DI dependency injection
  5. Error message interpolation using EL expressions to make error messages dynamic (strongly dependent on ELManager)
  6. Verify across parameters. For example, the password and the authentication password must be the same

Tip: There are no new comments compared to version 1.0

Its official reference implementation is as follows:



You can see that the Java Bean Validation version 1.1 implementation corresponds to Hibernate Validator 5.x(version 1.0 corresponds to 4.x).

<dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-validator</artifactId> < version > 5.4.3. Final < / version > < / dependency >

When you import the Hibernate -Validator, you don’t need to show import javax.validation. Hibernate – Validator 5.x version is mostly dead, only serious bugs will be fixed. Therefore, it is not recommended that you use this version unless it is a special case. In other words, you should not use Bean Validation version 1.1, let alone version 1.0.

Spring Boot1.5.x includes Bean Validation 1.1 by default, but when Boot 2.x comes in, it does not include Bean Validation 1.1

JSR380

The current mainstream version, which is what we call2.0 Java Bean ValidationandThe Jakarta Bean Validation is 2.0Version. The official explanation for the difference between the two versions:



They didn’t change anything except in terms of their names and in terms of their GAV. Their respective GAVs are as follows:

< the dependency > < groupId > javax.mail. Validation < / groupId > < artifactId > validation - API < / artifactId > < version > 2.0.1. The Final < / version > </dependency> <dependency> <groupId>jakarta.validation</groupId> <artifactId>jakarta.validation-api</artifactId> The < version > 2.0.1 < / version > < / dependency >

I don’t think I can scream nowJava EEIt should beJakarta EE. It’s the same thing, you know.The Jakarta Bean Validation is 2.0It was released in August 2019 and belongs toJakarta EE 8A part of. Its official reference implementation is the only Hibernate Validator:

This version has very important practical significance, it mainly provides the following highlights:

  1. List<@Positive Integer> Positivenumbers = List<@Positive Integer> Positivenumbers = List<@Positive Integer>

    1. More flexible cascading validation of collection types; For example, you can now verify the values and keys of a map, such as:Map<@Valid CustomerType, @Valid Customer> customersByType
    2. The java.util.Optional type is supported, and custom container types are supported by inserting additional value extractors
  2. Make @past / @future annotations support annotations on JSR310 time
  3. Added 9 built-in annotation types: @email, @notempty, @notblank, @positive, @positiveorzero, @negative, @negativeorzero, @pastorpresent and @futureorpresent
  4. All built-in constraints now support duplicate tags
  5. Use reflection to retrieve the parameter name, which is the input parameter name, as shown in the API: ParameterNameProvider

    1. This is clearly supported by Java 8’s startup parameters
  6. The namespace of the Bean validation XML descriptor has been changed to:

    1. META-INF/validation.xml -> http://xmlns.jcp.org/xml/ns/v…
    2. mapping files -> http://xmlns.jcp.org/xml/ns/v…
  7. Minimum version requirement for JDK: JDK 8

Hibernate Validator (Hibernate Validator) has fully supported the JSR 380 specification since version 6.x. In addition to supporting the standard, Hibernate Validator has also made some improvements, such as performance improvements, reduced memory footprint, etc., so it is definitely a good idea to use the latest version. It will only get better.

The new annotation

Version 2.0 adds 9 useful annotations compared to 1.x, bringing the total number to 22. The new nine annotations are explained as follows:

annotations Support types meaning Whether the null value is validated
@Email string The element must be an E-mail address no
@NotEmpty Container type The Size of the collection must be greater than 0 is
@NotBlank string The string must contain at least one non-white space character is
@Positive Numeric types Elements must be positive (excluding 0) no
@PositiveOrZero Same as above Ditto (including 0) no
@Negative Same as above Elements must be negative (excluding 0) no
@NegativeOrZero Same as above Ditto (including 0) no
@PastOrPresent Time to type Including equivalence on the basis of @past no
@FutureOrPresent Time to type Include equality based on @futrue no

like@email, @notempty, @notblankHibernate was an extra before, Hibernate is automatic after the 2.0 standardStepped backAnd marked as expired. The JSR specification lead for Bean Validation 2.0 is based in Hibernate, so this is a natural step. He is:

Tip: In addition to the 22 annotations provided by the JSR standard, Hibernate Validator also provides some very useful annotations, which will be explained later in the Hibernate Validator section

Use the sample

Import the implementation package:

<dependency> <groupId>org.hibernate.validator</groupId> <artifactId>hibernate-validator</artifactId> < version > 6.1.5. Final < / version > < / dependency >

Check the Java Bean

Write JavaBeans and validators (all using JSR standard APIs) :

@ToString
@Setter
@Getter
public class Person {

    @NotNull
    public String name;
    @NotNull
    @Min(0)
    public Integer age;
}
public static void main(String[] args) { Person person = new Person(); person.setAge(-1); // Provider/SPI validatorFactory validatorFactory = // Provider/SPI validatorFactory = Validation.buildDefaultValidatorFactory(); / / 2, get a Validator Validator Validator. = validatorFactory getValidator (); Set< ConstraintCheesecake <Person>> result = Validator.validate (Person); Map (v-> v.getPropertyPath() + "" + v.getMessage() + ": " + v.getInvalidValue()).forEach(System.out::println); }

Run the program, unfortunately throw the wrong:

Caused by: java.lang.ClassNotFoundException: javax.el.ELManager at java.net.URLClassLoader.findClass(URLClassLoader.java:382) at java.lang.ClassLoader.loadClass(ClassLoader.java:418) at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:355) .

As mentioned above, the EL manager support for dynamic interpolation of error messages is required from version 1.1, so you need to import an additional implementation of EL yourself.

Tip: EL is also a Java EE standard technology, and can be considered an expression language tool. It’s not just Web-only (even if you use it mostly in JSPs on the Web), it can be used anywhere (like Spring’s SPEL).

Here is the API of the EL technical specification:

<! -- Dependency API --> < grouppid >javax.el</ grouppid > <artifactId>javax.el-api</artifactId> <version>3.0.0</version> </dependency>

The Expression Language 3.0 specification has been released on April 29, 2013. Tomcat 8, Jetty 9, and Glasshfish 4 all support EL 3.0, so feel free to import one (if you are in a web environment, You don’t have to import it yourself).

<dependency> <groupId>org.apache.tomcat.embed</groupId> <artifactId>tomcat-embed-el</artifactId> The < version > 9.0.22 < / version > < / dependency >

After adding it, run the program again, and the normal output of the console is the message of verification failure:

Age cannot be less than 0: -1 name cannot be null: null

Validation method/validation constructor

Please move on to the following details.

Bean Validation 3.0

Jakarta Bean Validation 3.0 is officially available with the release of Jakarta EE 9.

<dependency> <groupId>jakarta.validation</groupId> <artifactId>jakarta.validation-api</artifactId> The < version > 3.0.0 < / version > < / dependency >

It’s the biggest change, evenThe onlyChange is the package name change:



At this point, not only was the name changed on GAV, but the package names that were important to code execution were completely removedjavax.*. Because the actual class has not changed, it can still be considered an implementation of JSR380 (although it is no longer the standard set by the JCP organization).

Reference implementation

No doubt the reference implementation that must beHibernate Validator. It’s also keeping pace, dropping out of the 7.x version for supportThe Jakarta Bean Validation is 3.0. Although it is a large version upgrade, you can think of it in terms of new featuresThere is no:

✍ summary

This article focuses on the JSR specification, the Bean Validation standard, and the official reference implementation Hibernate Validator, correlating the relationships between them and identifying the differences. I think this article will refresh the understanding of data validation for the general reader.

Wow, there’s so much more behind data validation

Data verification is a knowledge point that the daily working group contacts very frequently. I believe that mastering it and skillfully applying it to practical work can achieve double the result with half the effort, make the code more elegant, and even realize the overtime pay of others. So it is a small and American column with a fairly high output ratio on the way……

As the first article of this column, the JSR standard is used as a starting point to explain. It is hoped that theory and practice can be combined to learn. After all, theory plays an indispensable role in guiding. With the foundation stone of theory, the practice will be more smooth and the so-called walking on the ground will be more solid.

Recommend reading:
  • It’s time to say goodbye to FastJSON
  • 1. Get acquainted with Jackson — the best JSON library in the world
  • 2. Damn, Jackson used to write JSON like this
  • 3. Jackson will be used to write JSON on your resume
  • 4. How are JSON strings parsed? JSONParser takes a look
  • It’s just the JsonFactory. It’s quite interesting, which I didn’t expect
  • 6. At 20, ObjectMapper is no longer confused
  • 7. Jackson’s ability to work with JSON using tree models is a must

♥ ♥ Brother A

Author A brother (YourBatman)
Personal site www.yourbatman.cn
E-mail [email protected]
WeChat fsx641385712
Active platform
The public, Bat Utopia (ID: Bat-Utopia)
Knowledge of the planet The Utopia of BAT
Daily article recommendations Daily article recommendations