为何一次请求会有两次HttpServlet:service调用?

栏目: Java · 发布时间: 5年前

内容简介:今天看了下阿里出的为什么只访问了然后我去自己试了下,发现还真的是这个情况,trace日志如下:

今天看了下阿里出的 Arthas使用文档 中有问到:

为什么只访问了 http://localhost:8080/a.txt ,但Arthas的 trace 命令打印出了两个请求树?

然后我去自己试了下,发现还真的是这个情况,trace日志如下:

---ts=2019-02-24 18:05:20;thread_name=http-nio-8080-exec-1;id=15;is_daemon=true;priority=5;TCCL=org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedWebappClassLoader@6601a0f8
    `---[22.125552ms] javax.servlet.http.HttpServlet:service()
        `---[22.048005ms] javax.servlet.http.HttpServlet:service()
            `---[21.977486ms] org.springframework.web.servlet.FrameworkServlet:service()
                +---[0.015829ms] javax.servlet.http.HttpServletRequest:getMethod()
                +---[0.023379ms] org.springframework.http.HttpMethod:resolve()
                `---[21.847595ms] org.springframework.web.servlet.HttpServletBean:service()
                    `---……

`---ts=2019-02-24 18:05:20;thread_name=http-nio-8080-exec-1;id=15;is_daemon=true;priority=5;TCCL=org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedWebappClassLoader@6601a0f8
    `---[108.691709ms] javax.servlet.http.HttpServlet:service()
        `---[108.658563ms] javax.servlet.http.HttpServlet:service()
            `---[108.612929ms] org.springframework.web.servlet.FrameworkServlet:service()
                +---[0.024764ms] javax.servlet.http.HttpServletRequest:getMethod()
                +---[0.004569ms] org.springframework.http.HttpMethod:resolve()
                `---[108.540682ms] org.springframework.web.servlet.HttpServletBean:service()
                    `---……

然后,过去翻了一下代码才发现,是 org.apache.catalina.core.StandardHostValve#invoke 方法的逻辑:

//正常的处理请求(这是第一个HttpServlet:service调用)
context.getPipeline().getFirst().invoke(request, response);
// 如果response是失败的,那么再处理ErrorPage的逻辑
if (response.isErrorReportRequired()) {
if (t != null) {
throwable(request, response, t);
} else {
status(request, response);
}
}

在status方法中,获取 ErrorPage ,然后给 request 设置 javax.servlet.error.* 的属性,然后再forward到 HttpServlet:service 。这儿就会出现第二个 HttpServlet:service 请求。

那么问题来了,这个行为是规范里面有约定吗?

翻了翻 Java Servlet Specification ,第10.9.2小节有说:

To allow developers to customize the appearance of content returned to a Web client when a servlet generates an error, the deployment descriptor defines a list of error page descriptions. The syntax allows the configuration of resources to be returned by the container either when a servlet or filter calls sendError on the response for specific status codes, or if the servlet generates an exception or error that propagates to the container.
If the sendError method is called on the response, the container consults the list of error page declarations for the Web application that use the status-code syntax and attempts a match. If there is a match, the container returns the resource as indicated by the location entry.
The Web application may have declared error pages using the exception-typeelement. In this case the container matches the exception type by comparing the exception thrown with the list of error-page definitions that use the exception-typeelement. A match results in the container returning the resource indicated in the location entry. The closest match in the class hierarchy wins.

简而言之,如果通过sendError方法设置了错误,就会被对应的ErrorPage对象处理,就会转发到对应的location去处理。

其实到这儿,还有很多问题没有解决,比如:

  • ErrorPage是如何设置的?
  • war模式下,容器是如何知晓spring的入口的?

不过,慢慢来吧。

最近在写 Java 的时候,同时使用VSCode和IntelliJ IDEA,发现IDEA在很多细节做了优化,比如debug的时候,IDEA是选中了某一个线程,展示某一个线程的调用栈;而VSCode则是用一个Tree来表示,第一级是线程,更深的则是调用栈。还有,IDEA在展示Map等数据结构的时候,直接展示key、value对,而VSCode则暴露了很多内部实现,很不直观。VSCode还有很多路要走啊……


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

编程珠玑(英文版・第2版)

编程珠玑(英文版・第2版)

[美] Jon Bentley / 人民邮电出版社 / 2010-8 / 39.00元

多年以来,当程序员们推选出最心爱的计算机图书时,《编程珠玑》总是位列前列。正如自然界里珍珠出自细沙对牡蛎的磨砺,计算机科学大师Jon Bentley以其独有的洞察力和创造力,从磨砺程序员的实际问题中凝结出一篇篇不朽的编程“珠玑”。这些文章是《ACM通讯》最受欢迎的专栏文章,最终结集为两部书出版。本书为第一卷,主要讨论计算机科学中最本质的问题:如何正确选择和高效地实现算法。 在书中,作者选取许......一起来看看 《编程珠玑(英文版・第2版)》 这本书的介绍吧!

图片转BASE64编码
图片转BASE64编码

在线图片转Base64编码工具

RGB HSV 转换
RGB HSV 转换

RGB HSV 互转工具

HSV CMYK 转换工具
HSV CMYK 转换工具

HSV CMYK互换工具