preface
In the process of our actual project development, it is unavoidable to check the parameters. The check of general parameters can be divided into the following situations. 1. Front-end direct verification; 2. Verify separately at the Controller layer; 3. Verification through the integration verification framework; Obviously, among the three methods, we generally suggest that the combination of 1+3 is more reasonable and safe for parameter verification. In this chapter we will focus on the application of parameter validation in HTTP requests
Several ways to receive parameters for a Controller
Before introducing the validation framework, let’s look at the way parameters are received through Controller; At present, most parameters are received through annotations. The mainstream ones are as follows
Request path parameter
- @pathvariable Gets path parameters. Url /{id}.
- RequestParam retrieves query parameters. The url? Name = of the form
The code form is as follows:
GET http://localhost:8080/demo/SN20201011021211? name=hank
The corresponding receiving code is as follows:
@GetMapping("/demo/{sn}")
public void demo(@PathVariable(name = "sn") String sn, @RequestParam(name = "name") String name) {
System.out.println("sn="+sn);
System.out.println("name="+name);
}
Copy the code
Body parameters
The Body argument is typically a POST request in two main ways
- Received in JSON format, the corresponding parameters can be obtained via @requestBody
- Submitted in form form, no annotation adaptation, can be directly received by the object
JSON parameter reception
For example, to add a user interface,PostMan requests the following information
Corresponding to back-end code 1, received via Map
@PostMapping(value = "/user/map")
public ResultVO createUser(@RequestBody Map<String,Object> user){
String name=user.get("name").toString();
return RV.success(user);
}
Copy the code
Corresponding descendant code 2 receives through the defined object
@PostMapping(value = "/user")
public ResultVO createUser2(@RequestBody User user){
System.out.println("User Info:"+user.toString());
return RV.success(user);
}
Copy the code
FORM parameter receiving
In form mode, the corresponding parameters in PostMan are as follows
The corresponding back-end code is as follows:
@PostMapping(value = "/user/form")
public ResultVO createUser3(User user){
System.out.println("User Info:"+user.toString());
return RV.success(user);
}
Copy the code
Request header and Cookie parameters
- @requesTheader gets the Header parameters directly from the HttpServletRequest object
- @Cookievalue can directly retrieve parameters from the Cookies in the HttpServletRequest object
Obtained by means of annotations as follows
@GetMapping("demo3")
public void demo3(@RequestHeader(name = "myHeader") String myHeader,
@CookieValue(name = "myCookie") String myCookie) {
System.out.println("myHeader=" + myHeader);
System.out.println("myCookie=" + myCookie);
}
Copy the code
The method of obtaining by hard coding is
@GetMapping("/demo3")
public void demo3(HttpServletRequest request) {
System.out.println(request.getHeader("myHeader"));
for (Cookie cookie : request.getCookies()) {
if ("myCookie".equals(cookie.getName())) { System.out.println(cookie.getValue()); }}}Copy the code
As can be seen from the above, annotations can greatly simplify coding and make our code beautiful and elegant. It can also be obtained directly from the Request object. This mainly depends on what kind of requirements we have. Therefore, we prefer to get parameters directly through annotations in projects.
File upload
File uploads are based on @requestParam combined with MultipartFile objects; The following is an example;
Note that the incoming front-end needs to be submitted as a form and added to the content-Type of the Head with the following information
Content-Type: application/x-www-form-urlencoded
Copy the code
The corresponding back-end code is as follows
@Value("${file.upload.url}")
private String filePath;
@RequestMapping("/upload")
public ResultVO httpUpload(@RequestParam("files") MultipartFile files[]){
for(int i=0; i<files.length; i++){ String fileName = files[i].getOriginalFilename();/ / file name
File dest = new File(filePath+'/'+fileName);
if(! dest.getParentFile().exists()) { dest.getParentFile().mkdirs(); }try {
files[i].transferTo(dest);
} catch (Exception e) {
log.error("{}",e);
returnRV.result(ErrorCode.UPLOAD_FILE_ERROR,e); }}return RV.success(null);
}
Copy the code
Parameter calibration
JSR stands for Java Specification Requests, which stands for Java Specification proposals. The latest update to data Validation is JSR380, also known as Bean Validation 2.0. Bean Validation 2.0 is JSR Standard no. 380. The standard connection is as follows: www.jcp.org/en/egc/view… Bean Validation can be performed at github.com/hibernate/h…
Parameter verification at the Controller layer can be divided into two scenarios: single parameter verification and entity parameter verification
Single parameter check
Introduction of depend on
<dependency>
<groupId>jakarta.validation</groupId>
<artifactId>jakarta.validation-api</artifactId>
</dependency>
Copy the code
The back-end code is as follows
@RestController
@Validated
public class ValidateController {
@GetMapping("/getUser")
public ResultVO getUserStr(@notnull (message = "name cannot be empty ") String name,
@max (value = 99, message = "cannot be older than 99 ") Integer age) {
return RV.success("name: " + name + " ,age:"+ age); }}Copy the code
In the Postman request below, you can see that the request returns a system exception, which should be intercepted by a global exception
Let’s look at the logs printed in the background
If there are many places in our system are used to parameter calibration, so we had better be able to in the global intercept in direct interception ConstraintViolationException anomaly, and unified processing, can be in the previous section we talked about, Add the following intercepting new methods to the GlobalException class annotated with @RestControllerAdvice; Because ConstraintViolationException inherited the thrown exception classes, so we can intercept the superclass abnormal directly, directly for a number of different check exception processing
@RestControllerAdvice
public class GlobalException {
/** * Description: Form exception blocking *@param [e]
* @date 2020/11/22
* @Author Hank
**/
@ExceptionHandler(value = ValidationException.class)
public ResultVO validationException(ValidationException e){
Map map=new HashMap();
if(e instanceofConstraintViolationException){ ConstraintViolationException exs = (ConstraintViolationException) e; Set<ConstraintViolation<? >> violations = exs.getConstraintViolations();for(ConstraintViolation<? > item : violations) {// Prints the information that does not pass the verificationSystem.out.println(item.getMessage()); map.put(item.getPropertyPath(),item.getMessage()); }}returnRV.result(ErrorCode.FORM_VALIDATION_ERROR,map) ; }}Copy the code
Similarly, after a Postman request, the following result is obtained
Entity parameter check
In general, we pass in fewer parameters, we directly use the above method to verify, but if we pass in an object, it is a little ugly to directly set the properties on the method, so we generally encapsulate an object that receives parameters. To add a user interface, as provided in the example below, we set the validation rules for the variables of the user object as follows
@Data
class Person {
@notnull (message = "name cannot be empty ")
@max (value = 30, message = "name cannot exceed 30 characters ")
String name;
@max (value = 200, message = "can't be over 200 ")
@notnull (message = "Age cannot be empty ")
Integer age;
@notnull (message = "Address message cannot be empty ")
String address;
}
Copy the code
In the Controller class, we add a method to add users. Note that we just need to add the @valid annotation to the Person object corresponding to the method
/** * Description: Add a Person *@param [person]
* @date 2020/11/22
* @Author Hank
**/
@PostMapping(value = "/person")
public ResultVO<Person> addPerson(@RequestBody @Valid Person person) {
// Skip the business code here...
return RV.success(person);
}
Copy the code
In fact, you might say, well, what kind of exception should be thrown if the parameter check is different, so when we run the code like this and set the parameter out of range, we can see the exception on the back end like this
As you can see, here is thrown MethodArgumentNotValidException very different from the above abnormal; The same reason, I’m still in GlobalException class to add to the abnormal MethodArgumentNotValidException global intercept
/** * Description: Method parameter verification exception interception *@param [e]
* @date 2020/11/22
* @Author Hank
**/
@ExceptionHandler(value = MethodArgumentNotValidException.class)
public ResultVO methodArgumentNotValidException(MethodArgumentNotValidException e){
List<ObjectError> errors = e.getBindingResult().getAllErrors();
String[] errMessage=new String[errors.size()];
for (int i = 0; i < errors.size(); i++) {
ObjectError error=errors.get(i);
errMessage[i]=error.getDefaultMessage();
System.out.println(error.getCode()+":"+error.getDefaultMessage());
}
return RV.result(ErrorCode.METHOD_ARGS_VALID_ERROR,errMessage) ;
}
Copy the code
Validated is different from Valid
- @Validated: The nested verification function cannot be provided separately for method inputs. Cannot be used on member attributes (fields), nor can it prompt the framework for nested validation. Can be nested with the @valid annotation for nested validation.
- Valid: cannot provide nested validation on method input arguments alone. Can be used on member attributes (fields) to prompt the validation framework for nested validation. Can be nested with the @valid annotation for nested validation.
If there is another object inside the Person object, such as Person, and you need this nested validation during the submission process, you need to use Valid nested validation to modify the code as follows:
@Data
class Person {
@notnull (message = "name cannot be empty ")
@size (min = 2, Max = 30, message = "name length is limited between 2 and 30 ")
String name;
@max (value = 200, message = "can't be over 200 ")
@notnull (message = "Age cannot be empty ")
Integer age;
@notnull (message = "Address message cannot be empty ")
String address;
@Valid
Person p;
}
Copy the code
Annotations for checking common parameters
Here we mainly introduce several parameter verification methods in Springboot. Common comments for parameter verification are as follows:
- The element annotated by @AssertFalse must be of Boolean type and value false
- The annotated element @assertTrue must be of Boolean type and have a value of true
- The annotated element @decimalmax must be a number with a value less than or equal to the given value
- The annotated element @decimalmin must be a number with a value greater than or equal to the given value
- The annotated element at @digits must be a number, and the value must be the specified number of Digits
- The annotated element @future must be a Future date
- The element annotated by @max must be a number with a value less than or equal to the given value
- The element annotated by @min must be a number with a value less than or equal to the given value
- The annotated element at @range must be within the specified Range
- @notnull the annotated element value cannot be null
- The annotated element value @notblank has content
- @null The annotated element value is Null
- The annotated element @past must be a date in the Past
- The annotated element @pastorpresent must be a PastOrPresent date
- The element annotated by @pattern must satisfy the given regular expression
- The element annotated by @size must be a String, collection, or array, and the Size must be within a given range
- @email annotated elements must meet the Email format
summary
This chapter mainly focuses on two aspects of the content of a detailed introduction
- Parameter receiving mode of Controller
- Request path parameter
- Body arguments (JSON\FORM\ request header and Cookie arguments)
- File upload
- Verification of parameters
- Single parameter check
- Entity parameter check
- Verification of nested parameters and the difference between Validated and Valid
The above examples are described in detail, hoping to be helpful to your later development work; If you have different experience in this field, feel free to leave a comment in the comments section.
Refer to the article
Blog.csdn.net/w57685321/a…
JSR specification reference blog.csdn.net/choushi9178…