Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

How to use JSR303 to realize Parameter Verification in Spring Boot

2025-01-16 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Internet Technology >

Share

Shulou(Shulou.com)06/02 Report--

Today, I will talk to you about how to use JSR303 to achieve parameter verification in Spring Boot, many people may not know much about it. In order to make you understand better, the editor has summarized the following content for you. I hope you can get something according to this article.

Constraint annotations embedded in Bean Validation Specification

Basic application of an example

Introduce dependency

Org.springframework.boot spring-boot-starter-validation

Add a check comment to a parameter object

@ Datapublic class User {private Integer id; @ NotBlank (message = "user name cannot be empty") private String username; @ Pattern (regexp = "^ (?! [0-9] + $) (?! [a-zA-Z] + $) [0-9A-Za-z] {8pime16} $", message = "password must be a combination of 816 letters and numbers") private String password; @ Email private String email; private Integer gender;}

Add @ Valid before the parameter Bean to be verified in Controller to enable the verification function, and add a BindingResult,BindingResult immediately after the verified Bean to encapsulate the verification result of the previous Bean.

@ RestController@RequestMapping ("/ user") public class UserController {@ PostMapping (") public Result save (@ Valid User user, BindingResult bindingResult) {if (bindingResult.hasErrors ()) {Map map = new HashMap (); bindingResult.getFieldErrors () .forEach ((item)-> {String message = item.getDefaultMessage (); String field = item.getField () Map.put (field, message);}); return Result.build (400, "illegal parameters!", map);} return Result.ok ();}}

The tests are as follows:

Unified handling of exceptions

When the parameter verification fails, a BingBindException exception is thrown, which can be handled uniformly in the unified exception handling, so that you do not have to use BindingResult to obtain the verification result in every place where parameter verification is needed.

@ Slf4j@RestControllerAdvice (basePackages = "com.itwolfed.controller") public class GlobalExceptionControllerAdvice {@ ExceptionHandler (value= {MethodArgumentNotValidException.class, BindException.class}) public Result handleVaildException (Exception e) {BindingResult bindingResult = null; if (e instanceof MethodArgumentNotValidException) {bindingResult = ((MethodArgumentNotValidException) e). GetBindingResult ();} else if (e instanceof BindException) {bindingResult = ((BindException) e). GetBindingResult () } Map errorMap = new HashMap (16); bindingResult.getFieldErrors (). ForEach ((fieldError)-> errorMap.put (fieldError.getField (), fieldError.getDefaultMessage (); return Result.build (400, "illegal parameters!", errorMap);}} packet resolution check

New and modified verification rules are different for entities. For example, when id is self-increasing, id must be empty when added, and modification must not be empty. If new and modified entities happen to be the same entity, grouping verification is required.

Verification annotations all have a groups attribute, which can be grouped. Let's take a look at the source code of @ NotNull:

@ Target ({METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE}) @ Retention (RUNTIME) @ Repeatable (List.class) @ Documented@Constraint (validatedBy = {}) public @ interface NotNull {String message () default "{javax.validation.constraints.NotNull.message}"; Class [] groups () default {}; an array of Class type, then you can create a Groups.

Public class Groups {public interface Add {} public interface Update {}}

Add groups to the check annotations of parameter objects

@ Datapublic class User {@ Null (message = "New does not need to specify id", groups = Groups.Add.class) @ NotNull (message = "need to specify id for modification", groups = Groups.Update.class) private Integer id; @ NotBlank (message = "user name cannot be empty") @ NotNull private String username @ Pattern (regexp = "^ (?! [0-9] + $) (?! [a-zA-Z] + $) [0-9A-Za-z] {8jue 16} $", message = "password must be a combination of 816 letters and numbers") private String password; @ Email private String email; private Integer gender;}

The original @ Valid in Controller cannot specify a grouping and needs to be replaced with @ Validated

RestController@RequestMapping ("/ user") public class UserController {@ PostMapping (") public Result save (@ Validated (Groups.Add.class) User user) {return Result.ok ();}}

The tests are as follows:

Custom check comment

Although JSR303 and springboot-validator have provided a lot of verification annotations, when faced with complex parameter verification, it still can not meet our requirements, so we need to customize the verification annotations.

For example, gender in User uses 1 for male and 2 for female. We customize a check annotation @ ListValue and specify that values can only be 1 and 2.

Create a constraint rule @ Documented@Constraint (validatedBy = {ListValueConstraintValidator.class}) @ Target ({METHOD, FIELD, ANNOTATION_TYPE}) @ Retention (RUNTIME) public @ interface ListValue {String message () default "; Class [] groups () default {}; an array of Class types.

The payload property, which allows consumers of Bean Validation API to specify a severity level for a constraint. This property is not used by API itself.

In addition to these three mandatory properties (message, groups and payload), we also add

An attribute has been added to specify the required value. The name vals of this property is special in the definition of annotation.

If only this property is assigned, then the attribute name can be ignored when using this annotation.

In addition, we also marked some meta-annotations (meta) for this annotation

Annotatioins):

@ Target ({METHOD, FIELD, ANNOTATION_TYPE}): indicates that this annotation can be used in a method, field, or

On the annotation statement.

Retention (RUNTIME): indicates that this annotation information is read by reflection at run time.

Constraint (validatedBy = ListValueConstraintValidator.class): indicates which validator (class) to use to validate elements that use this annotation.

Documented: indicates that when you javadoc a class that uses the annotation, the annotation will be added to the

In javadoc.

Create constraint verifier import javax.validation.ConstraintValidator;import javax.validation.ConstraintValidatorContext;import java.util.HashSet;import java.util.Set;public class ListValueConstraintValidator implements ConstraintValidator {private Set set = new HashSet (); / * * initialization method * / @ Override public void initialize (ListValue constraintAnnotation) {int [] vals = constraintAnnotation.vals (); for (int val: vals) {set.add (val) }} / * determine whether the param value is successfully verified * @ param context * @ return * / @ Override public boolean isValid (Integer value, ConstraintValidatorContext context) {return set.contains (value);}}

ListValueConstraintValidator defines two generic parameters, the first of which the validator serves to the annotation type (in our case, ListValue), and the second that the validator supports to the type of the validated element (that is, Integer).

If a constraint dimension supports multiple types of validated elements, you need to define a ConstraintValidator for each supported type and register it in the constraint dimension.

The implementation of this validator is common. The initialize () method passes in an instance of the type of annotation to be verified, in this

In this example, we use this instance to get the value of its vals property and save it as a Set collection for the next step

Use it.

IsValid () is the place where real check logic is implemented, judging a given int for the @ ListValue constraint

Whether it's legal.

Use the @ ListValue annotation in the parameter object.

@ Datapublic class User {@ Null (message = "New does not need to specify id", groups = Groups.Add.class) @ NotNull (message = "need to specify id for modification", groups = Groups.Update.class) private Integer id; @ NotBlank (message = "user name cannot be empty") @ NotNull private String username @ Pattern (regexp = "^ (?! [0-9] + $) (?! [a-zA-Z] + $) [0-9A-Za-z] {8jue 16} $", message = "password must be a combination of 816 letters and numbers") private String password; @ Email private String email; @ ListValue (message = "gender should specify the appropriate value", vals = {1pm 2}, groups = {Groups.Add.class, Groups.Update.class}) private Integer gender;}

The tests are as follows:

After reading the above, do you have any further understanding of how to use JSR303 to implement parameter verification in Spring Boot? If you want to know more knowledge or related content, please follow the industry information channel, thank you for your support.

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Internet Technology

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report