springboot异常处理之404

wayn111 2021-01-14 16:18:37
java SpringBoot 异常 博客园 处理


ps: 推荐一下本人的通用后台管理项目crowd-admin 以及newbee-mall增强版,喜欢的话给个star就好

源码分析

在springboot中默认有一个异常处理器接口ErrorContorller,该接口提供了getErrorPath()方法,此接口的BasicErrorController实现类实现了getErrorPath()方法,如下:


/*
* AbstractErrorController是ErrorContoller的实现类
*/
@Controller
@RequestMapping("${server.error.path:${error.path:/error}}")
public class BasicErrorController extends AbstractErrorController {
private final ErrorProperties errorProperties;
...
@Override
public String getErrorPath() {
return this.errorProperties.getPath();
}
@RequestMapping(produces = MediaType.TEXT_HTML_VALUE)
public ModelAndView errorHtml(HttpServletRequest request, HttpServletResponse response) {
HttpStatus status = getStatus(request);
Map<String, Object> model = Collections
.unmodifiableMap(getErrorAttributes(request, isIncludeStackTrace(request, MediaType.TEXT_HTML)));
response.setStatus(status.value());
ModelAndView modelAndView = resolveErrorView(request, response, status, model);
return (modelAndView != null) ? modelAndView : new ModelAndView("error", model);
}
@RequestMapping
public ResponseEntity<Map<String, Object>> error(HttpServletRequest request) {
HttpStatus status = getStatus(request);
if (status == HttpStatus.NO_CONTENT) {
return new ResponseEntity<>(status);
}
Map<String, Object> body = getErrorAttributes(request, isIncludeStackTrace(request, MediaType.ALL));
return new ResponseEntity<>(body, status);
}
....
}

errorProperties类定义如下:

public class ErrorProperties {
/**
* Path of the error controller.
*/
@Value("${error.path:/error}")
private String path = "/error";
...
}

由此可见,springboot中默认有一个处理/error映射的控制器,有errorerrorHtml两个方法的存在,它可以处理来自浏览器页面和来自机器客户端(app应用)的请求。

当用户请求不存在的url时,dispatcherServlet会交由ResourceHttpRequestHandler映射处理器来处理该请求,并在handlerRequest方法中,重定向至/error映射,代码如下:

 @Override
public void handleRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// For very general mappings (e.g. "/") we need to check 404 first
Resource resource = getResource(request);
if (resource == null) {
logger.debug("Resource not found");
response.sendError(HttpServletResponse.SC_NOT_FOUND); // 404
return;
}
...
}

getResource(request)会调用this.resolverChain.resolveResource(request, path, getLocations())方法,getLocations()方法返回结果如下:

接着程序会执行到getResource(pathToUse, location)方法如下:

 @Nullable
protected Resource getResource(String resourcePath, Resource location) throws IOException {
// 新建一个resource对象,url为 location + resourcePath,判断此对象(文件)是否存在
Resource resource = location.createRelative(resourcePath);
if (resource.isReadable()) {
if (checkResource(resource, location)) {
return resource;
}
else if (logger.isWarnEnabled()) {
Resource[] allowedLocations = getAllowedLocations();
logger.warn("Resource path \"" + resourcePath + "\" was successfully resolved " +
"but resource \"" + resource.getURL() + "\" is neither under the " +
"current location \"" + location.getURL() + "\" nor under any of the " +
"allowed locations " + (allowedLocations != null ? Arrays.asList(allowedLocations) : "[]"));
}
}
return null;
}

在resource.isReadable()中,程序会在locations目录中寻找path目录下文件,由于不存在,返回null。

最终也就导致程序重定向至/error映射,如果是来自浏览器的请求,也就会返回/template/error/404.html页面,所以对于404请求,只需要在template目录下新建error目录,放入404页面即可。

使用注意

  1. 在springboot4.x中我们可以自定义ControllerAdvice注解 + ExceptionHandler注解来处理不同错误类型的异常,但在springboot中404异常和拦截器异常由spring自己处理。
版权声明
本文为[wayn111]所创,转载请带上原文链接,感谢
https://www.cnblogs.com/wayn111/p/14277865.html

  1. Centos7 one click installation of JDK1.8 shell script
  2. Mounting of file system in Linux (centos7)
  3. How does serverless deal with the resource supply demand of k8s in the offline scenario
  4. Detailed explanation of HBase basic principle
  5. Spring security oauth2.0 authentication and authorization 4: distributed system authentication and authorization
  6. Redis performance Part 5 redis buffer
  7. JavaScript this keyword
  8. Summary of Java multithreading (3)
  9. Sentry(v20.12.1) K8S 云原生架构探索, SENTRY FOR JAVASCRIPT 手动捕获事件基本用法
  10. Sentry(v20.12.1) K8S 云原生架构探索, SENTRY FOR JAVASCRIPT 手动捕获事件基本用法
  11. (10) Spring from the beginning to the end
  12. Summary of Java multithreading (2)
  13. Spring source notes! From the introduction to the source code, let you really understand the source code
  14. A stormy sunny day
  15. Zookeeper (curator), the implementation of distributed lock
  16. Show the sky! Tencent T4's core Java Dictionary (framework + principle + Notes + map)
  17. Spring boot project, how to gracefully replace the blank value in the interface parameter with null value?
  18. Spring boot project, how to gracefully replace the blank value in the interface parameter with null value?
  19. docker+mysql集群+读写分离+mycat管理+垂直分库+负载均衡
  20. docker+mysql集群+读写分离+mycat管理+垂直分库+负载均衡
  21. To what extent can I go out to work?
  22. Java 使用拦截器无限转发/重定向无限循环/重定向次数过多报错(StackOverflowError) 解决方案
  23. Implementation of rocketmq message sending based on JMeter
  24. How to choose the ticket grabbing app in the Spring Festival? We have measured
  25. Implementation of rocketmq message sending based on JMeter
  26. My programmer's Road: self study java
  27. My programmer's Road: self study java
  28. All in one, one article talks about the use of virtual machine VirtualBox and Linux
  29. All in one, one article talks about the use of virtual machine VirtualBox and Linux
  30. Java 使用拦截器无限转发/重定向无限循环/重定向次数过多报错(StackOverflowError) 解决方案
  31. [Java training project] Java ID number recognition system
  32. How does serverless deal with the resource supply demand of k8s in the offline scenario
  33. Detailed explanation of HBase basic principle
  34. Explain the function of thread pool and how to use it in Java
  35. Kubernetes official java client 8: fluent style
  36. 010_MySQL
  37. Vibrant special purchases for the Spring Festival tiktok section, hundreds of good things to make the year more rich flavor.
  38. 010_MySQL
  39. Of the 4 million docker images, 51% have high-risk vulnerabilities
  40. Rocketmq CPP client visual studio 2019 compilation
  41. Rocketmq CPP client visual studio 2019 compilation
  42. Usage of data custom attribute in jquery
  43. Common decompression in Linux
  44. Upload large files in Java
  45. Sentry (v20.12.1) k8s cloud native architecture exploration, sentry for JavaScript manual capture event basic usage
  46. Sentry (v20.12.1) k8s cloud native architecture exploration, sentry for JavaScript manual capture event basic usage
  47. Docker + MySQL Cluster + read / write separation + MYCAT Management + vertical sub database + load balancing
  48. Docker + MySQL Cluster + read / write separation + MYCAT Management + vertical sub database + load balancing
  49. Java use interceptor infinite forwarding / redirection infinite loop / redirection times too many error (stack overflow error) solution
  50. Java use interceptor infinite forwarding / redirection infinite loop / redirection times too many error (stack overflow error) solution
  51. 010_ MySQL
  52. 010_ MySQL
  53. Fast integration of imsdk and Huawei offline push
  54. 消息队列之RabbitMQ
  55. Rabbitmq of message queue
  56. 初学java进制转换方面补充学习
  57. Learn java base conversion supplementary learning
  58. 了解一下RPC,为何诞生RPC,和HTTP有什么不同?
  59. 了解一下RPC,为何诞生RPC,和HTTP有什么不同?
  60. 初学java进制转换方面补充学习