Hello, brothers, this time to communicate with Lao Tie about two issues, anomaly and parameter verification. Before parameter verification, let’s talk about exception processing first, because the latter parameter verification will involve the content of exception processing.

Exception handling

Speaking of exception handling, I don’t know if you’ve ever written it or encountered it like this.

public void saveUser() {try {// All business contents}catch (Exception e) {e.printStackTrace(); }}Copy the code

If the above code, which contains a large number of business code, if you write, quickly change, not you write to find written, ridicule quickly change.

Existing problems:

  • 1. Performance bottlenecks will be encountered;
  • 2. It is difficult to locate the problem;
  • 3, try too much nesting is not readable;

Whatever the reason for the above code, it is best to change it. If you must try in business code, you should try only where exceptions can occur, not the entire business code.

Exception capture in SpringBoot

Go straight to code

@RestControllerAdvice Public Class GlobalException {@ExceptionHandler(value = exception.class) // The captured Exception type Public Object GlobalException (Exception ex) {// Ex.printStackTrace ();return "Abnormal"; }}Copy the code

So in SpringBoot we can get the Exception in the project through such a configuration, we can get the details of the Exception class in this method, so do we use Exception to handle all exceptions? Then it’s definitely not appropriate.

We emulate a BY Zero exception and then configure a handler to handle the ArithmeticException exception as follows:

@RestControllerAdvice Public Class GlobalException {@ExceptionHandler(value = exception.class) // The captured Exception type Public Object  globalException(Exception ex) { ex.printStackTrace();return "Abnormal";
    }

    @ExceptionHandler(value = ArithmeticException.class)
    public Object arithmeticException(ArithmeticException ex) {

        ex.printStackTrace();
        return "Exception by zero"; }}Copy the code

If the by Zero exception is present at this point, the reason it is ArithmeticException handling is that if there is a smaller range of exception handling classes, the smaller range of exception handlers will be used. Does not go to the larger globalException exception class.

After doing this, we don’t need to write so many trys in the project.

In addition to using these existing exceptions, we can also customize our exceptions, such as our usual user not logged in exception, parameter error exception, and so on. But considering the length of this article, I will not write this time, interested friends can directly leave a message below, more people I update as soon as possible.

Pay attention to the pit:

It is not possible to throw an exception in the Filter by throwing an exception in the Filter and then using the exception handler class, because the handler cannot catch the exception thrown by the Filter.

Parameter calibration

As usual, let’s look at a piece of code

@RequestMapping(value = "/save/user")
public Object saveUser(UserPO userPO) {

    if (userPO.getAge() == null) {
        return "Request parameter error";
    }

    if (userPO.getSex() == null) {
        return "Request parameter error";
    }
    if (userPO.getUsername() == null) {
        return "Request parameter error";
    }

    // ...

    return "SUCCESS";
}
Copy the code

I think you’ve seen this check parameter before, actually I’ve written it. The more you write, the lower you feel, so be cruel, or change it as soon as possible.

@ Validated annotations

This annotation is actually provided by Spring. If your project is not a SpringBoot project, you need to refer to the poM file you need. If it is, then forget it,SpringBoot has already introduced it for us.

Read a lot of blogs on the Internet, many of them are not very complete, most of them are about the verification of JavaBean parameters, but some of the interfaces in our project may involve a parameter, there is no need to write a JavaBean, for the verification of a single parameter many blogs are not said, so we will speak clearly this time.

Single parameter verification

Let’s just look at the code

@Validated
@RestController
public class BookController {
    
    @RequestMapping(value = "/book/info", method = RequestMethod.GET)
    public Object getBookInfo(@NotBlank(message = "Book ID cannot be empty") String bookId) {

        return "SUCCESS"; }}Copy the code

Just so you know, if it’s a single parameter validation, we have to add an @ “Validated” annotation to the class, otherwise the entire single parameter validation will not be Validated. You can see that when we validate bookId, we use @notblank so as the name implies, Even this argument cannot be null, nor can it be null after the trim() method is called.

If parameters do not meet the requirements, then throws ConstraintViolationException exception, the exception only in single parameter calibration when thrown, if your parameters are javabeans, so, it is not the exception.

Now that we know it will throw an exception, and we know what type of exception it is, it’s super simple and we can just use the exception handling class we just learned above to handle our exception.

Inside me to find a simple, if you want to write a bit complicated, it is also possible, but as a back end, I don’t think it’s necessary, because we can’t give the front tip is too obvious errors, prevent malicious attack us, others like user name password mistake, can’t clear tell users what is user name or password errors, Only the user name or password is incorrect.

If you want to print out the detailed error message, to see which parameter failed, you can also print out the specific parameter error message by using the following method. The output error result is actually the contents of the above message.

@restControllerAdvice Public class ExceptionCatch {/** * Exception handling of a single parameter ** @param ex * @return*/ @ExceptionHandler(value = ConstraintViolationException.class) public Object ConstraintViolationException (constraintViolationException ex) {/ / for the specific error information Set < ConstraintViolation <? >> violations = ex.getConstraintViolations(); // print data violations. ForEach (e -> system.out.println (LLDB etMessage()));return "Single - request parameter error"; }}Copy the code

JavaBean parameter verification (form-data)

JavaBean spelled

@Data
@NoArgsConstructor
@AllArgsConstructor
public class UserPO {

    @NotBlank(message = "User name cannot be empty")
    private String username;

    @NotNull(message = "Age cannot be empty.")
    @Min(value = 1, message = "Age minimum 1")
    @Max(value = 200, message = "Age up to 200")
    private Integer age;

    @NotBlank(message = "Gender cannot be empty.")
    private String sex;
}
Copy the code

The Controller of writing

@RequestMapping(value = "/save/user")
public Object saveUser(@Validated UserPO userPO) {

    // ...

    return "SUCCESS";
}
Copy the code

The difference with single-parameter verification is that the @ “Validated” method parameter, not the class, is used in the JavaBean verification mode. If a parameter fails, an exception, BindException, is also thrown.

/** * General parameters check binding exception handling ** @param ex * @return
 */
@ExceptionHandler(value = BindException.class)
public Object bindException(BindException ex) { BindingResult bindingResult = ex.getBindingResult(); / / get all error information List < ObjectError > allErrors = bindingResult. GetAllErrors (); ForEach (e -> system.out.println (LLDB etDefaultMessage()));return "Request parameter error";
}
Copy the code

Note: There are two types of POST requests: one is in the form data format, and the other is in the JSON format. The two types of post requests also raise different exceptions, so we need to handle the JSON-based parameter verification exception separately.

JavaBean Parameter verification (JSON)

Let’s first look at the Controller reception

@RequestMapping(value = "/save/user")
public Object saveUser(@Validated @RequestBody UserPO userPO) {

    // ...

    return "SUCCESS";
}
Copy the code

Corresponding parameter exception handling

/** * JSON parameter verification binding exception handling ** @param ex * @return*/ @ExceptionHandler(value = MethodArgumentNotValidException.class) public Object methodArgumentNotValidException(MethodArgumentNotValidException ex) { BindingResult bindingResult = ex.getBindingResult(); / / get all error information List < ObjectError > allErrors = bindingResult. GetAllErrors (); ForEach (e -> system.out.println (LLDB etDefaultMessage()));return "Request parameter error -json";
}
Copy the code

The last word

So here, we end this article, mainly introduced two parts of the content, exception processing and parameter verification. It’s simple, but I personally feel it’s a common skill. So share it with everyone, and if it helps, give it a like. If you do not understand what also welcome below the message, to exchange.

More exciting content please pay attention to wechat public number: the growth of a programmer