In SpringMVC, developers are allowed to customize methods to handle exceptions uniformly, so that some exceptions can occur in multiple requests, but only once in code!

The core of this mechanism is that there are ways to handle requests where exceptions can occur without code explicitly handling exceptions! The equivalent is that the methods that handle the request will throw exceptions, and the SpringMVC framework will catch these exceptions when it calls the methods that handle the request. In this case, if the developer defines the methods that handle the exception, SpringMVC will call the methods that handle the exception after it catches the exception.

Regarding the unified approach to handling exceptions, its stated principles are:

  • Access rights: Should be usedpublicPermissions;
  • Return value type: The same return value design principles as for methods that process requests;
  • Method name: custom;
  • Parameter list: 1 parameter of exception type must be added to represent the exception object to be handled; It can also be added on demandHttpServletRequest,HttpServletResponseObject, however, can not arbitrarily add parameters;
  • Note: must be added@ExceptionHandlerAnnotation.

For example, it could be designed as:

@ExceptionHandler
public JsonResult<Void> aaaaa(Throwable e) {
    JsonResult<Void> jsonResult = new JsonResult<>();

    if (e instanceof UsernameDuplicateException) {
        jsonResult.setState(2);
        jsonResult.setMessage("Registration failed! The username is already in use!");
    } else if (e instanceof InsertException) {
        jsonResult.setState(3);
        jsonResult.setMessage("Registration failed! Error inserting user data!");
    } else {
        jsonResult.setState(998);
        jsonResult.setMessage("Operation failed! An unrecognized problem has occurred, please contact your system administrator!");
    }

    return jsonResult;
}
Copy the code

Note: When the exception handler code is inside a controller class, it can only apply to exceptions thrown in the current controller class!

If the code that needs to handle exceptions uniformly can handle exceptions in all controller classes, alternative solutions are:

  • Create a base class for the controller class (the common parent of all controller classes) and put code that handles exceptions uniformly in the base class;
  • Customize a class to place code that handles exceptions uniformly in it and add to it@ControllerAdviceComments or@RestControllerAdviceAnnotations;

For example, a code example for doing the second option above:

package cn.tedu.store.controller;

@RestControllerAdvice
public class GlobalExceptionHandler {
	
	@ExceptionHandler
	public JsonResult<Void> handleException(Throwable e) {
		JsonResult<Void> jsonResult = new JsonResult<>();
		
		if (e instanceof UsernameDuplicateException) {
			jsonResult.setState(2);
			jsonResult.setMessage("Registration failed! The username is already in use!");
		} else if (e instanceof InsertException) {
			jsonResult.setState(3);
			jsonResult.setMessage("Registration failed! Error inserting user data!");
		} else {
			jsonResult.setState(998);
			jsonResult.setMessage("Operation failed! An unrecognized problem has occurred, please contact your system administrator!");
		}
		
		returnjsonResult; }}Copy the code

The source code for the @ExceptionHandler annotation used above:

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface ExceptionHandler {

	/** * Exceptions handled by the annotated method. If empty, will default to any * exceptions listed in the method argument list. */
	Class<? extends Throwable>[] value() default {};

}
Copy the code

The value attribute in the annotation is an array of the types of exceptions handled by the annotated method. If the value is empty, all exceptions in the parameter list of the method that handled the exception will be counted.

That is, if the code is:

@ExceptionHandler
public JsonResult<Void> handleException(Throwable e) {
	// Handle exception code
}
Copy the code

HandleException () will handle Throwable exceptions!

If the code is:

@ExceptionHandler
public JsonResult<Void> handleException(RuntimeException e) {
	// Handle exception code
}
Copy the code

HandleException () will handle exceptions of type RuntimeException, while other types, such as IOException, will not be handled by this method!

If there are different ways to handle different exceptions in a project, you can create more than one method to handle exceptions and specify the kind of exception to be handled by specifying the parameters of the method or by configuring the @ExceptionHandler annotation.

In general, it is recommended to specify the type of exception to be handled with an annotation parameter, for example:

@ExceptionHandler({UsernameDuplicateException.class, InsertException.class})
public JsonResult<Void> handleException(Throwable e) {
	// Handle exception code
}
Copy the code

Or:

@ExceptionHandler({ServiceException.class})
public JsonResult<Void> handleException(Throwable e) {
	// Handle exception code
}
Copy the code