springboot异常处理之404

简介: springboot异常处理之404

ps: 推荐一下本人的通用后台管理项目crowd-admin

源码分析

在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()方法返回结果如下:

image.png

接着程序会执行到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自己处理。
目录
相关文章
|
机器学习/深度学习 人工智能 算法
AI技术如何提升视频画质
在现代科技的飞速发展下,人工智能(AI)技术已经成为人们生活中不可或缺的一部分。尤其是在视频处理领域,AI技术的作用愈发凸显。AI技术的出现不仅仅简化了视频处理的流程,而且提高了视频画质的表现力和感知度。 本文将讲述AI技术提升视频画质的基本特点与方法。
|
7月前
|
人工智能 Java API
MCP客户端调用看这一篇就够了(Java版)
本文详细介绍了MCP(Model Context Protocol)客户端的开发方法,包括在没有MCP时的痛点、MCP的作用以及如何通过Spring-AI框架和原生SDK调用MCP服务。文章首先分析了MCP协议的必要性,接着分别讲解了Spring-AI框架和自研SDK的使用方式,涵盖配置LLM接口、工具注入、动态封装工具等步骤,并提供了代码示例。此外,还记录了开发过程中遇到的问题及解决办法,如版本冲突、服务连接超时等。最后,文章探讨了框架与原生SDK的选择,认为框架适合快速构建应用,而原生SDK更适合平台级开发,强调了两者结合使用的价值。
10960 33
MCP客户端调用看这一篇就够了(Java版)
|
JSON 安全 Java
Spring Boot之全局异常处理:404异常为何捕获不到?
Spring Boot之全局异常处理:404异常为何捕获不到?
2366 0
Spring Boot之全局异常处理:404异常为何捕获不到?
|
XML Java 应用服务中间件
【Spring】运行Spring Boot项目,请求响应流程分析以及404和500报错
【Spring】运行Spring Boot项目,请求响应流程分析以及404和500报错
1430 2
|
存储 IDE Java
Java“NoClassDefFoundError”解决
Java中的“NoClassDefFoundError”错误通常发生在尝试访问某个类时,该类在编译时可用但在运行时找不到。解决方法包括:确保所有依赖库已正确添加到类路径中,检查类名和包名是否正确,以及清理并重新构建项目。
3672 3
|
前端开发 网络协议
Nest.js 实战 (十四):如何获取客户端真实 IP
这篇文章介绍了在Nest.js应用中获取客户端真实IP地址的问题及解决方法。问题出现在使用本地代理时,请求的IP地址总是返回::1或::ffff:127.0.0.1。为解决这个问题,需要确保代理服务器正确设置转发头如X-Forwarded-For或X-Real-IP,后端服务能够读取这些头信息来确定客户端的IP地址。文章以作者自己的OpenResty应用为例,展示了如何通过配置反向代理和设置X-Forwarded-For头来获取真实IP地址,并提供了相关的代码示例。最后,文章提到了使用这个解决方案后的实际效果,例如在操作日志中记录真实IP地址。
484 0
|
前端开发 Java 程序员
Spring Boot (十五): 优雅的使用 API 文档工具 Swagger2
Spring Boot (十五): 优雅的使用 API 文档工具 Swagger2
|
XML JavaScript 前端开发
【一种关于flowable 的工作流设计器】workflow-bpmn-modeler-antdv的使用
【一种关于flowable 的工作流设计器】workflow-bpmn-modeler-antdv的使用
3644 0
|
Java
SpringBoot自定义错误页面与原理讲解
SpringBoot自定义错误页面与原理讲解
739 0

热门文章

最新文章