The JSR 303–bean Validation is a data validation specification that determines the final scenario in November 2009. December 2009 Java EE 6 was released, and Bean Validation was included as an important feature. This article introduces the main features of Bean Validation and demonstrates how to use bean Validation correctly in the Java development process with some examples.
About Bean Validation
At any time, when you are dealing with the business logic of an application, data validation is something you have to consider and face. The application must have some means to ensure that the input data is semantically correct. In the usual case, the application is layered and different layers are done by different developers. Many times the same data validation logic appears on different layers, which leads to code redundancy and some management issues, such as semantic consistency. To avoid this situation, it is best to bind the validation logic to the appropriate domain model.
Bean Validation defines the corresponding metadata model and API for JavaBean validation. The default metadata is Java Annotations, which allows you to overwrite and extend the original metadata information by using XML. In the application, you @NotNull
@Max
@ZipCode
can ensure the correctness of the data Model (JavaBean) by using Bean Validation or your own defined constraint, for example. Constraint can be attached to fields, getter methods, classes, or interfaces above. For some specific needs, users can easily develop customized constraint. Bean Validation is a runtime data validation framework that verifies that the error message is returned immediately after validation.
Download JSR 303–bean Validation Specification http://jcp.org/en/jsr/detail?id=303
Hibernate Validator is a reference implementation of Bean Validation. Hibernate Validator provides the implementation of all the built-in constraint in the JSR 303 specification, in addition to some additional constraint. To learn more about Hibernate Validator, see http://www.hibernate.org/subprojects/validator.html
Constraint table 1 in Bean Validation. Built-in constraint in Bean Validation
Constraint |
More Information |
@Null |
The annotated element must be anull |
@NotNull |
The annotated element must not be anull |
@AssertTrue |
The annotated element must be atrue |
@AssertFalse |
The annotated element must be afalse |
@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 |
Table 2. Hibernate Validator Additional constraint
Constraint |
More Information |
@Email |
The annotated element must be an e-mail 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 |
A constraint is usually composed of annotation and the corresponding constraint validator, which are a one-to-many relationship. This means that there can be multiple constraint validator corresponding to a annotation. At run time, the Bean Validation framework itself validates the data by selecting the appropriate constraint validator based on the type of the annotated element.
In some cases, more complex constraint are needed in the user's application. Bean Validation provides a mechanism for extending constraint. There are two ways to do this, one is to combine existing constraint to generate a more complex constraint, and the other is to develop a new constraint.
Create a simple app that contains validation logic (based on JSP)
In this article, you demonstrate how to apply Bean Validation in Java development by creating a fictitious order management system (JSP-based web App). This streamlined system allows users to create and retrieve orders.
System design and application of the technology Figure 1. System architecture
Figure 1 is a structure diagram of the report management system and is a typical MVC (Model-view-controller) application. The controller is responsible for receiving and processing requests, and the Servlet plays the role of controller to process requests, business logic, and move to the appropriate JSP page. Validates the data in the Servlet. JSP plays the role of view as a graphical interface to present the data in model to facilitate user interaction. Models are the data model for the operation of this system, and we simplify this part to not persist the data.
Data Model Figure 2. Data model
Figure 2 shows the data model of the order management system.
Declares the JavaBean Listing 1 for contraint. Order.java
Public classOrder {//must not be null, size is ten@NotNull @Size (min= ten, max = 10) PrivateString orderId; //must not be empty@NotEmptyPrivateString Customer; //must be an e-mail address@EmailPrivateString Email; //must not be empty@NotEmptyPrivateString address; //must be not NULL, must be the following four strings ' created ', ' paid ', ' shipped ', ' closed ' one of them//@Status is a customized contraint@NotNull @StatusPrivateString status; //must be non-null@NotNullPrivateDate CreateDate; //Nested Validation@ValidPrivateproduct product, .... Getter and Setter}
Listing 2. Product.java
Public class Product { // must be non-empty @NotEmpty private String productName; ////@Price private float Price , ..... Getter and Setter }
Listing 3. Orderquery.java
// @QueryConstraint publicclass orderquery { Private Date from; Private Date to; .... omitted. Getter and Setter }
Customized constraint
@Price
is a custom constraint, composed of two built-in constraint.
Listing 4. The annotation part of the @Price
@Max (10000) @Min (8000) = {}) @Documented @Target ({ Elementtype.annotation_type, Elementtype.method, Elementtype.field}) @Retention (retentionpolicy.runtime) public @Interface prices { default "wrong price"; Classdefault {}; Classextendsdefault {}; }
@Status
is a newly developed constraint.
Listing 5. The annotation part of the @Status
@Constraint (Validatedby = {statusvalidator. Class}) @Documented @Target ({elementtype.annotation_type, Elementtype.method, Elementtype.field }) @Retention (retentionpolicy.runtime) public @Interface Status { default "The incorrect state should be ' created ', ' paid ', shipped ', closed ' one of them"; Classdefault {}; Classextendsdefault {}; }
Listing 6. Constraint validator part of the @Status
Public classStatusvalidatorImplementsConstraintvalidator<status, string>{ Private FinalString[] All_status = {"Created", "paid", "shipped", "closed"}; Public voidInitialize (status status) {} Public BooleanisValid (String value, Constraintvalidatorcontext context) {if(Arrays.aslist (All_status). Contains (value))return true; return false; } }
Bean Validation API uses examples to create orders
When users create an order record, they need to fill in the following information: order number, customer, email, address, status, product name, product price
Figure 3. Create an Order
To verify this information, use the Bean Validation API
Listing 7. Code Snippets
protected voidDoPost (httpservletrequest req, HttpServletResponse resp)throwsservletexception, IOException {HttpSession session=req.getsession (); //get input information from requestString orderId = (string) req.getparameter ("OrderId"); String Customer= (String) req.getparameter ("Customer"); String Email= (String) req.getparameter ("email"); String Address= (String) req.getparameter ("Address"); String Status= (String) req.getparameter ("status"); String ProductName= (String) req.getparameter ("ProductName"); String Productprice= (String) req.getparameter ("Productprice"); //put the Bean in the sessionOrder order =NewOrder (); Order.setorderid (ORDERID); Order.setcustomer (customer); Order.setemail (email); Order.setaddress (address); Order.setstatus (status); Order.setcreatedate (NewDate ()); Product Product=NewProduct (); Product.setname (ProductName); if(Productprice! =NULL&& productprice.length () > 0) Product.setprice (float.valueof (Productprice)); Order.setproduct (product); Session.setattribute ("Order", order); Validatorfactory Factory=validation.builddefaultvalidatorfactory (); Validator Validator=Factory.getvalidator (); Set<ConstraintViolation<Order>> violations =validator.validate (order); if(violations.size () = = 0) {Session.setattribute ("Order",NULL); Session.setattribute ("ErrorMsg",NULL); Resp.sendredirect ("Creatsuccessful.jsp"); } Else{stringbuffer buf=NewStringBuffer (); ResourceBundle Bundle= Resourcebundle.getbundle ("Messages"); for(constraintviolation<order>violation:violations) {Buf.append ("-" +bundle.getstring (Violation.getpropertypath (). toString ())); Buf.append (Violation.getmessage ()+ "<br>\n"); } session.setattribute ("ErrorMsg", buf.tostring ()); Resp.sendredirect ("Createorder.jsp"); } }
If the user submits the order without filling in any information, the corresponding error message will be displayed on the page
Figure 4. Error message returned after validation
In fact, you can call the JSR 303 API anywhere in the program to verify the data, and then officer the results back.
Listing 8. Call the JSR 303 API for validation
New= validation.builddefaultvalidatorfactory (); = factory.getvalidator (); Set<ConstraintViolation<Order>> violations = validator.validate (Order); ..
Conclusion
The release of JSR 303 makes it easy to automatically bind and validate data, allowing developers to define the data model without having to consider the limitations of the implementation framework. Of course, Bean Validation only provides some of the most basic constraint, in the actual development process, the user can according to their own needs to combine or develop more complex constraint
Reference Learning
- JSR 303 Specification: detailed JSR 303 specification description, where you can find detailed documentation related to the specification and download the relevant implementation code.
- The JSR 303 reference implements Hibernate Validator: Learn how to implement Bean Validator specifically through Hibernate.
Introduction to JSR 303-bean Validation and best practices