SpringBoot解决异常不能被捕获的问题-针对404



先了解一下springboot 正常情况下捕获异常的方式

1、添加以下配置

spring.resources.add-mappings=false

spring.mvc.throw-exception-if-no-handler-found=true

2、使用@RestControllerAdvice+@ExceptionHandler的方式捕获异常

 *@RestControllerAdvice =@ResponseBody+@ControllerAdvice

@ExceptionHandler(value = { NoHandlerFoundException.class })

public ResponseData noHandlerFoundException(NoHandlerFoundException ex) {

ResponseData responseData = new ResponseData();

responseData.setApiCode(ApiErrorCodeEnum.CODE20000.getCode());

return responseData;

}

一、调试过程>发现问题>解决问题

产生异常的原因有

A、URL错误,controller中没有对应的路径(statuCode:400)

B、在controller内出现异常(statuCode:500)

AB两种方法很好区别 ,肉眼可见的区别,实在不行debug一下观察接口有没有到达Controller内即可

主要对A进行阐述,排查原因debug调试>直接进入DispatchServlet.class 如何进入 Ctrl+shift+N 搜索


一个不存在的URL会被SimpleUrlHandlerMapping /** 匹配到 

匹配到会有什么影响呢?下图可见,程序进入不了noHandlerFound()方法里面

所以这个地方我们需要添加一个配置就是 spring.resources.add-mappings=false 关闭资源映射

这个时候问题出现了就是该配置没有生效,还是被SimpleUrlHandlerMapping /** 匹配到了


接下来仔细看了项目配置发现:

在mvc配置中添加了/**的mapping 所以我们将该处内容注释掉

接下来程序顺利的进入到了noHandlerFound方法里面  内容如下:

红框内的是重点 可以看到一个通过一个判定条件就会抛出异常,这个判定东西就是我们在配置中设置的一个东西:spring.mvc.throw-exception-if-no-handler-found=true

我在测试的时候发现这个配置没有生效:原因待查  初步估计是版本问题 

所以在这个地方默认是false,抛不出异常,也就导致我们的异常捕捉不到

这个地方怎么处理呢?那就是重写noHandlerFound方法

import org.springframework.http.HttpHeaders;

import org.springframework.web.servlet.DispatcherServlet;

import org.springframework.web.servlet.NoHandlerFoundException;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

public class CustomizeDispatcherServlet extends DispatcherServlet {

@Override

protected void noHandlerFound(HttpServletRequest request, HttpServletResponse response) throws Exception {

throw new NoHandlerFoundException(request.getMethod(), request.getRequestURL().toString(), new HttpHeaders());

}

}

很简单就是直接创建一个类继承DispatcherServlet  重写他的noHandlerFound方法直接抛出异常

然后将新写的CustomizeDispatcherServlet 配置到mvc中

@Bean

public ServletRegistrationBean apiMvc() {

CustomizeDispatcherServlet dispatcherServlet = new CustomizeDispatcherServlet();

AnnotationConfigWebApplicationContext applicationContext = new AnnotationConfigWebApplicationContext();

applicationContext.register(ApiConfig.class);

dispatcherServlet.setApplicationContext(applicationContext);

ServletRegistrationBean servletRegistrationBean = new ServletRegistrationBean(dispatcherServlet, "/api/*");

servletRegistrationBean.setName("apiMvc");

return servletRegistrationBean;

}

再来启动项目调试 成功解决400白页


©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容