“This article has participated in the call for good writing activities, click to view: the back end, the big front end double track submission, 20,000 yuan prize pool waiting for you to challenge!”

Java provides a wealth of exception handling classes, but in some cases it is not enough to meet real needs.


At this time, we must use custom exceptions to handle errors. Using custom exception handlers is more user-friendly, and for ourselves, we can locate errors more accurately and solve them more quickly.

It is inevitable that there will be errors that are ignored in the project, which can lead to system downtime, so you need a global exception handler to catch all exceptions.


This article will teach you how to implement custom exception + global exception handling in a few simple steps.

Custom exceptions:

  • Start with a custom exception class that inherits RuntimeException and writes a constructor
/ * * *@author ChenTaWen
 * @version1.0 * /
public class MyException extends RuntimeException {

    /** * The exception constructor makes it easy to pass in error codes and information */
    public MyException(String msg) {
        super(msg); }}Copy the code
  • Write test classes to test custom exceptions
/ * * *@author admin
 */
@RestController
@RequestMapping("user")
public class UserLoginController {

    @GetMapping("test")
    public User testLogin(a) throws MyException {
        throw new MyException("Test custom exceptions"); }}Copy the code
  • Use Postman for testing

Global exception handling:

  • Add @ControllerAdvice custom global exception handlers (note: using Lombok’s @slf4J)
/** * Global exception handler **@author admin
 */
@Slf4j
@ControllerAdvice
@ResponseBody
public class GlobalExceptionHandler {

    /** * Handle custom service exceptions */
    @ExceptionHandler(value = MyException.class)
    public R<String> bizExceptionHandler(MyException e) {
        log.error("A service exception has occurred! msg: -> ", e);
        return R.failed(e.getMessage());
    }

    /** * handle null pointer exception */
    @ExceptionHandler(value = NullPointerException.class)
    public R<String> exceptionHandler(NullPointerException e) {
        log.error("Null pointer exception occurred! msg: -> ", e);
        return R.failed("Null pointer exception occurred!");
    }

    /** * Server exception */
    @ExceptionHandler(Exception.class)
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    public R<String> exception(Exception e) {
        log.error("Server exception! msg: -> ", e);
        return R.failed("Server exception!"); }}Copy the code
  • Global exception handler annotations
@ExceptionHandler(value = MyException.class)-- Annotation type@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)- error code@ResponseBody- return json@ControllerAdviceAs the name implies, this is an enhanced Controller. Using this Controller, you can achieve three functions:1.Global exception handling2.Global data binding3.Global data preprocessingCopy the code
  • Write test classes to test global exception handling
/ * * *@author admin
 */
@RestController
@RequestMapping("user")
public class UserLoginController {

    @GetMapping("test")
    public User testLogin(a) {
        throw new NullPointerException("Null pointer exception occurred!"); }}Copy the code
  • Use Postman for testing

Global parameter exception handler to implement data verification:

  • Custom global parameter exception handlers
/** * Global parameter exception handler **@author admin
 */
@ControllerAdvice
@Order(Ordered.LOWEST_PRECEDENCE - 2)
@Slf4j
public class ArgumentsValidateAdvice {
    @ResponseBody
    @ExceptionHandler(MethodArgumentNotValidException.class)
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    public R<String> methodArgumentNotValidExceptionHandler(MethodArgumentNotValidException e) {
        log.error("Parameter abnormal! msg : -> ", e);
        returnR.failed(Objects.requireNonNull(e.getBindingResult().getFieldError()).getDefaultMessage()); }}Copy the code
  • Write a user entity class
/ * * *@author admin
 */
@Data
@NoArgsConstructor
@AllArgsConstructor
public class User {

    @notnull (message = "ID cannot be empty ")
    private Integer id;

    @notblank (message=" name cannot be blank ")
    @length (min = 2, Max = 4, message = "name name must be between {min} - {Max} ")
    private String username;

    @notblank (message=" password cannot be blank ")
    @length (min = 5, Max = 10, message = "password must be between {min} - {Max} ")
    private String password;
}
Copy the code
  • Entity class annotations
@Data-- Argument get()+set() method@NoArgsConstructor-- no-parameter constructor@AllArgsConstructor-- Parameterized constructor@validated-- Used to verify data@NotNull- not fornull
@NotBlank-- only for strings, not fornullSize > trim()0
Copy the code
  • Write test classes, test parameter exception handling
/ * * *@author admin
 */
@RestController
@RequestMapping("user")
public class UserLoginController {

    @PostMapping("addUser")
    public User addUser(@RequestBody @Validated User user) {
        returnuser; }}Copy the code
  • Use Postman for testing

Normally, we define a global exception handling class to handle exceptions, but when we define multiple exception handling classes, how do we ensure that they are executed in order?

The @order annotation can be used to set the Order of the processor’s capture execution. Without this annotation, the processor uses the default value, order.lowest_precedence.

The smaller one takes precedence, so we simply add @order (order.lowest_precedence-2) to the global exception handler to ensure that it takes precedence over the global exception handler.

What doubt can comment area to ask!