首页 > 其他分享 >Tomcat 的 ErrorPage 实现原理分析

Tomcat 的 ErrorPage 实现原理分析

时间:2022-12-20 10:08:08浏览次数:74  
标签:ErrorPage Tomcat response errorPage 原理 对应 页面

 

使用Tomcat,一定见到过404,500的时候,见到过Tomcat提供的错误页面,例如请求的资源找不到的时候,响应状态码为404,这个时候的错误页面是这样的:

Tomcat 的 ErrorPage 实现原理分析_错误页面

这些错误页面是 如何生成及定位展示的 ,如果我们要 自定义一些错误页面 ,又要怎么做呢?今天我们一起来看看,Tomcat中提供的ErrorPage处理。

我们以Manager应用为例,来了解整个流程。

  1. 首先,Manager应用的web.xml中,包含如下关于ErrorPage的配置:

这些配置,在应用部署,解析web.xml文件的时候,都会生成ErrorPage对应,设置到对应Context应用的属性中。

for (ErrorPage errorPage : webxml.getErrorPages().values() ) {

context. addErrorPage (errorPage);

}

(web.xml文件解析及应用部署,可以参考前面的文章《 ​WEB应用是怎样部署的?​》)

下面的代码,就是StandardContext添加ErrorPage的内容。我们看到,按照对应配置的状态码,每个对应一个errorPage对象,保存到Map中。

Tomcat 的 ErrorPage 实现原理分析_错误页面_02

上面是context设置errorPage。在应用请求处理时,如果对应的资源不存在,或者产生异常时,此时就需要根据配置的errorPage,进行对应的展示。

例如下面的代码,是在对应用的资源树上查找,如果不存在就会直接以 SC_NOT_FOUND 响应。

Tomcat 的 ErrorPage 实现原理分析_xml_03

sendError的作用,是进行一个error标识的设置,便于后面对于该状态的使用。在其内部主要进行errorState和状态码的设置。

public boolean setError() {
boolean result = errorState .compareAndSet(0, 1 );
if (result) {
Wrapper wrapper = getRequest().getWrapper();
if (wrapper != null) {
wrapper.incrementErrorCount();
}
}
return result;
}

我们前面介绍过,整个请求处理流程中,会在Pipeline中包含一系列的Valve。在资源找不到或者异常产生时,Valve的后处理逻辑中, 在StandardHostValve中,后处理的代码有如下的逻辑

// Look for (and render if found) an application level error page
if (response. isErrorReportRequired ()) {
if (t != null) {
throwable(request, response, t);
} else {
status (request, response);
}
}

这里的response.isErrorReportRequired获取的就是上面对于error标识的设置。在这里,如果有异常产生会打印异常,如果是其它的状态标识,会走status处理。

status方法中,最主要的逻辑,就是根据状态码,获取对应配置的错误页面。

int statusCode = response.getStatus();
ErrorPage errorPage = context.findErrorPage(statusCode);
if (errorPage == null) {
// Look for a default error page
errorPage = context.findErrorPage(0);
}

status的代码,在获取对应的errorPage之后,会进行一个custom的操作,定向到对应的错误页面。代码如下:

Tomcat 的 ErrorPage 实现原理分析_xml_04

从上面的代码中,我们看到定向的方式,使用的是RequestDispatcher. forward

ServletContext servletContext =

request.getContext().getServletContext();

RequestDispatcher rd =

servletContext.getRequestDispatcher( errorPage.getLocation() );

rd.forward(request.getRequest(), response.getResponse());

上面就是整个自定义errorPage的处理流程,概括起来,就是根据指定的错误页面位置,再在对应的状态码match的时候,进行forward的处理。(重定向和转发,可以参见前面的文章《关于重定向和转发》)所以此处,我们可以进行一个个性化的404或者500的页面处理。

当然,ErrorPage的配置中,可以声明一个exceptionType,在指定的异常产生时,对应到相应的page上面,原理类似。

除上之外,需要说明的一点是,有些应用中,我们并没有显示的指定errorPage,但是在应用的请求中,依然可以看到熟悉的Tomcat错误页面。这个是因为,在Pipeline中,还有一个Vavle, ErrorReportValve

依然走前面的错误处理流程时,在根据错误码获取errorPage的时候,因为没有对应的配置,custom处理就跳过了。整个错误展示留给后面的ErrorReportValve。

在它的report方法中,对于状态码小于400的不做处理,其他的就会生成我们熟悉的错误页面,同时,加上对应的状态码,提示信息,如果有相应的stackTrace,会遍历显示到 页面上。 

所以,这个其实是Tomcat代码里硬编码的一个。内容基本是这个样子:

Tomcat 的 ErrorPage 实现原理分析_Tomcat   ErrorPage_05

所以,对于未指定errorPage的应用,看到的是相同样式的错误页面的,就是因为上面的原因。

​​​http://www.tuicool.com/articles/UfEnqie​​​


标签:ErrorPage,Tomcat,response,errorPage,原理,对应,页面
From: https://blog.51cto.com/u_15147537/5954127

相关文章

  • 使用Tomcat基于redis的session共享机制集群部署
    常见的session集群方案:session复制和session共享Session复制:指session信息会在集群节点之间复制,每个节点服务上都会有相同的session信息;主要是实现后端多个节点的冗余功......
  • docker-部署tomcat
    dockerpulltomcat:8#拉取镜像dockerrun-d-p8080:8080tomcat:8#创建容器dockerps-a#可以查看容器iddockerexec-ittomcat的容器id/bin/bash#进入容器do......
  • MySQL索引背后的数据结构及算法原理
    摘要:看到的一篇关于MySql索引的介绍,感觉比较经典,直接转了。 摘要本文以MySQL数据库为研究对象,讨论与数据库索引相关的一些话题。特别需要说明的是,MySQL支持诸......
  • Git 基本原理与使用指南
    1、创建新仓库:创建新文件夹,打开,然后执行​​​gitinit​​以创建新的git仓库。2、检出仓库:执行如下命令以创建一个本地仓库的克隆版本:​​​gitclone/path/to/reposi......
  • 【通知】《生成对抗网络GAN原理与实践》代码开源,勘误汇总!
    有三上个月出版了新书《生成对抗网络GAN:原理与实践》,GenerativeAdversarialNetworks(中文名生成对抗网络,简称GAN)自从被提出来后,其发展就非常迅猛,几乎已经被应用于所有CNN可......
  • C++ Assert()断言机制原理以及使用
    机器学习以及人工智能的学习需要扎实的数学功底才能走的更远,爬的更高,所以打好数学基础是关键,但无论工作学习都没有充足的时间去拿着书本一个字一个字的去学习了,这里我建议大......
  • js防抖和节流的实现原理及应用场景
    概念:函数防抖(debounce):触发高频事件后n秒内函数只会执行一次,如果n秒内高频事件再次被触发,则重新计算时间。函数节流(throttle):高频事件触发,但在n秒内只会执行一次,所以节......
  • 【深入浅出Spring原理及实战】「源码原理实战」从底层角度去分析研究PropertySourcesP
    Spring提供配置解析功能主要有一下xml文件占位符解析和Java的属性@Value的占位符解析配置这两种场景进行分析和实现解析,如下面两种案例。xml文件的占位符解析配置<beanid="......
  • MVCC原理
    MVCC原理1.版本链对于使用InnoDB存储引擎的表来说,它的聚簇索引记录中有3个隐藏列,其中一个就是roll_pointer,每次对某条聚簇索引记录进行改动时,都会把旧的版本写入到un......
  • ETCD相关介绍--整体概念及原理方面
    etcd作为一个受到ZooKeeper与doozer启发而催生的项目,除了拥有与之类似的功能外,更专注于以下四点。简单:基于HTTP+JSON的API让你用curl就可以轻松使用。安全:可选SSL客户认证机......