SpringMVC is used based on annotations: exception handling

Get into the habit of writing together! This is the 11th day of my participation in the "Nuggets Daily New Plan · April Update Challenge", click to view the details of the event .

1. Springmvc built-in exception handling parser

In the development of a J2EE project, whether it is the operation of the underlying database, the processing of the business layer, or the processing of the control layer, it is inevitable to encounter various predictable and unpredictable exceptions that need to be handled. Each process handles exceptions separately. The system has a high degree of code coupling, and the workload is large and difficult to unify, and the maintenance workload is also large.

Then, can all types of exception handling be decoupled from each processing process, which not only ensures that the functions of the related processing processes are relatively single, but also realizes the unified processing and maintenance of exception information? The answer is yes. The following will introduce the solution and implementation process of using Spring MVC to handle exceptions uniformly.

There is a very powerful exception handling mechanism in SpringMVC. SpringMVC handles exceptions through HandlerExceptionResolver, including request mapping, data binding, and exceptions that occur when the target method is executed.

image.pngAfter the container starts and enters the DispatcherServlet, it will process the HandlerExceptionResolver

Line initialization operation:

image.pngBy default, the corresponding exception handling class will be found from DispatcherServlet.properties:

#默认的处理类
org.springframework.web.servlet.HandlerExceptionResolver=
#处理@ExceptionHandler
org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver,\
#解析@ResponseStatus注释类型的异常
org.springframework.web.servlet.mvc.annotation.ResponseStatusExceptionResolver,\
#按照不同类型分别对异常进行解析
org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver
        
        
        
复制代码

AbstractHandlerMethodExceptionResolver是ExceptionHandlerExcpetionResolver父类

SimpleMappingExceptionResolver: resolves exceptions through the corresponding relationship between the configured exception class and view

1-1. Use @ExceptionHandler to operate Exception

In order to give the user a good experience, we cannot directly display the error message to the user when writing the code, we need to deal with it, such as the following:

The controller method needs to pass a parameter:

image.png

The direct browser does not pass the name parameter as follows:

image.png

1-1-1. Handling with @ExceptionHandler

image.png

Browser access can see the following page

image.png 这样我们就可以对这个error.jsp进行一些处理,比如404 500 等一些错误的页面UI处理。

小结

我们在当前控制器中添加了@ExceptionHandler,也只能处理当前控制器的错误信息,如果需要处理所有控制器的错误信息,我们还需要进行统一错误信息。

二、统一异常处理

@ControllerAdvice 是Spring3.2提供的新注解,它是对Controller的增强,可对controller中被 @RequestMapping注解的方法加一些逻辑处理:

  1. 全局异常处理

  2. 全局数据绑定

  3. 全局数据预处理

@ExceptionHandler

加在Controller中 :只处理当前控制器的异常,优先级比全局高

加在ControllerAdvice中 :处理全局异常

2-1、使用@ControllerAdvice创建全局异常处理类

image.png 通过上图可以看到,目前有两个异常处理类,分别是控制器内部的还有使用@ControllerAdvice创建的全局异常处理类,那么如果这个时候发生异常是哪个异常来处理呢?下面来测试一下

image.png

特别说明一下,如果控制器内没有使用@ExceptionHandler注解的方法,会自动使用全局的错误异常方法

2-1-1、异常会被更精准的异常类处理

如果控制器内,没有定义异常处理方法,这个时候如果在全局异常处理类内定义了更加精准的异常处理方法,则会由更精准的异常处理方法处理。

image.png

2-1-2、异常处理优先级别

1、控制器异常 优先级最高 就近原则
2、全局异常中具体异常 如果控制器中没有定义异常 精准原则
3、全局异常 当异常没有满足以上两种情况,会交给全局异常处理

就近精准异常>就近异常>全局精准异常>全局异常

在实际项目中,一般只需要定义全局异常即可。

三、根据请求端请求方式自动返回异常处理信息

The above describes the way to return to the view layer to return exception information, but now many projects use the return format of Json, so our exception handling needs to automatically determine which format of data should be returned.

3-1. How to judge the request type

3-1-1, can be judged by the request header

json request if Content-Type="application/json"

//-------------通过请求头判断是否包含application/json判断是否是json----------------begin
//如果不等于-1则代表为json请求
int accept = request.getHeader("Accept").indexOf("application/json");
//-------------通过请求头判断是否包含application/json判断是否是json----------------end
复制代码

3-1-2. Judging by annotations on classes and methods

If the annotation on the class is @RestController or the annotation on the method is @ResponseBody, it is a json request

//---------通过注解判断是否是json-----------begin
//获取类上面的注解
RestController restControllerestController = handle.getClass().getAnnotation(RestController.class);
//获取方法上的注解
ResponseBody responseBody = handle.getMethod().getAnnotation(ResponseBody.class);
//---------通过注解判断是否是json-----------end
复制代码

image.pngThe picture above is the processing code.

test

1. Use the request method of the page

image.png

2. Use Json request

image.png

Fourth, 404 exception handling

4-1. First configure error-page in web.xml

<error-page>
    <error-code>404</error-code>
    <location>/errpage/404.html</location>
</error-page>
复制代码

4-2. Create a 404 error page

image.png

4-3. Create spring-mvc static resource mapping

image.png

4-4. Test

image.png

Guess you like

Origin juejin.im/post/7085212724740751373