0
点赞
收藏
分享

微信扫一扫

101 向一个不存在的路径发送请求, get 得到 404, post 得到 405


前言

 

这是 最近碰到的一个问题, 大概是在 2022.05.30

前端这边 发送了一个业务请求过来, 这个请求路径是服务端这边不存在的

但是 奇怪的一点就是, 如果是以 get 请求发送过来, 服务端响应的是正确的 404 "Not Found", 但是 如果是以 post 请求发送过来, 服务端这边响应的是 405 "Method Not Allowed"

因此 之后 花了一些时间 来看一下 这个问题

 

 

测试用例

这是一个测试的 notFound 的手动处理的服务 

@RestController
@RequestMapping("/HelloWorld")
public class HelloWorldController {

    @GetMapping("/notFound")
    public List<JSONObject> notFound() {
        List<JSONObject> result = new ArrayList<>();
        result.add(wrapEntity("404", "not-found"));
        return result;
    }
}

 

这是 mvcConfigure, 这里向容器中注册了一些错误页面的处理方式 

比如 这里的 404, 直接 转发到 "/HelloWorld/notFound", 具体的这个转发步骤是在 tomcat 中处理的

/**
 * MyWebMvcConfigurer
 *
 * @author Jerry.X.He 
 * @version 1.0
 * @date 2022-06-12 11:39
 */
@Configuration
public class MyWebMvcConfigurer implements WebMvcConfigurer {

    @Bean
    public WebServerFactoryCustomizer containerCustomizer() {
        return new WebServerFactoryCustomizer<ConfigurableWebServerFactory>() {
            @Override
            public void customize(ConfigurableWebServerFactory factory) {
                ErrorPage errorPage = new ErrorPage(HttpStatus.NOT_FOUND, "/HelloWorld/notFound");
                Set<ErrorPage> errorPageSet = new LinkedHashSet<>();
                errorPageSet.add(errorPage);
                factory.setErrorPages(errorPageSet);
            }
        };
    }


}

 

 

post 为什么响应的是 405?

如果是发送 post 请求响应结果如下, 服务端响应的是 405 

101 向一个不存在的路径发送请求, get 得到 404, post 得到 405_http

 

 

首先需要注意的是 errorPage 的这部分处理 在 tomcat 中是找到 errorCode 对应的 errorPage 

然后再通过 servletContext.getRequestDispatcher(errorPage.path).forward(req, resp)

101 向一个不存在的路径发送请求, get 得到 404, post 得到 405_405_02

 

然后因为我配置的 "/HelloWorld/notFound" 仅仅支持 GET

我这里原请求是 POST, dispatch 之后依然是 POST, 因此 服务端校验 method 的时候, 响应了 405 

101 向一个不存在的路径发送请求, get 得到 404, post 得到 405_tomcat_03

 

如果是 get 请求

服务器发现 没有匹配的资源, 根据 errorCode 寻找 errorPage 

然后 dispatch 到 “/HelloWorld/notFound”, 然后 响应了相关的结果返回给客户端

比如 这里的 { name -> 404, age -> not-found } 

101 向一个不存在的路径发送请求, get 得到 404, post 得到 405_405_04

 

ErrorPage 的相关处理流程

首先是 服务器使用这边, 根据 statusCode 查询 errorPage, 这个映射来自于 tomcat 的 StandardContext 

然后 走后面的 servletContext.getRequestDispatcher(errorPage.path).forward(req, resp) 的流程 

101 向一个不存在的路径发送请求, get 得到 404, post 得到 405_405_05

 

然后 我们代码中注册的 404 的 errorPage 被添加是在 WebServerFactory 初始化 StandardContext 的时候

101 向一个不存在的路径发送请求, get 得到 404, post 得到 405_405_06

 

我们的注册 errorPage 的地方是在 WebServerFactoryCustomizerBeanPostProcessor 中处理的, 当 WebServerFactory 实例初始化之后, init之前, 调用 Customizer 

这样 这一整个流程就串联起来了 

101 向一个不存在的路径发送请求, get 得到 404, post 得到 405_http_07

 

 

 

 

 

举报

相关推荐

0 条评论