yzddMr6's Blog

脚本小子


  • 首页

  • 分类

  • 标签

  • 归档

  • 知识星球

  • 关于

  • 搜索

关于Tomcat中的三个Context的理解

发表于 2021-03-16 更新于 2021-03-15 分类于 技术文章 阅读次数:
关于Tomcat中的三个Context的理解

p牛在知识星球里问了一个问题:Tomcat中这三个StandardContext、ApplicationContext、ServletContext都是干什么的

image.png

skay师傅给出了自己的理解:https://mp.weixin.qq.com/s/BrbkTiCuX4lNEir3y24lew

这里来讲一讲我的理解,说的不一定对,仅供参考。

Context

context是上下文的意思,在java中经常能看到这个东西。那么到底是什么意思呢?

根据我的理解,如果把某次请求比作电影中的事件,那么context就相当于事件发生的背景。例如一部电影中的某个镜头中,张三大喊“奥利给”,但是只看这一个镜头我们不知道到底发生了什么,张三是谁,为什么要喊“奥利给”。所以就需要交代当时事情发生的背景。张三是吃饭前喊的奥利给?还是吃饭后喊的奥利给?因为对于同一件事情:张三喊奥利给这件事,发生的背景不同意义可能是不同的。吃饭前喊奥利给可能是饿了的意思,吃饭后喊奥利给可能是说吃饱了的意思。在WEB请求中也如此,在一次request请求发生时,背景,也就是context会记录当时的情形:当前WEB容器中有几个filter,有什么servlet,有什么listener,请求的参数,请求的路径,有没有什么全局的参数等等。

ServletContext

ServletContext是Servlet规范中规定的ServletContext接口,一般servlet都要实现这个接口。大概就是规定了如果要实现一个WEB容器,他的Context里面要有这些东西:获取路径,获取参数,获取当前的filter,获取当前的servlet等

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
package javax.servlet;

...

public interface ServletContext {
String TEMPDIR = "javax.servlet.context.tempdir";
String ORDERED_LIBS = "javax.servlet.context.orderedLibs";

String getContextPath();

ServletContext getContext(String var1);

...

/** @deprecated */
@Deprecated
Servlet getServlet(String var1) throws ServletException;

/** @deprecated */
@Deprecated
Enumeration<Servlet> getServlets();

/** @deprecated */
@Deprecated
Enumeration<String> getServletNames();

void log(String var1);

/** @deprecated */
@Deprecated
void log(Exception var1, String var2);

void log(String var1, Throwable var2);

String getRealPath(String var1);

String getServerInfo();

String getInitParameter(String var1);

Enumeration<String> getInitParameterNames();

boolean setInitParameter(String var1, String var2);

Object getAttribute(String var1);

Enumeration<String> getAttributeNames();

void setAttribute(String var1, Object var2);

void removeAttribute(String var1);

String getServletContextName();

Dynamic addServlet(String var1, String var2);

Dynamic addServlet(String var1, Servlet var2);

Dynamic addServlet(String var1, Class<? extends Servlet> var2);

Dynamic addJspFile(String var1, String var2);

<T extends Servlet> T createServlet(Class<T> var1) throws ServletException;

ServletRegistration getServletRegistration(String var1);

Map<String, ? extends ServletRegistration> getServletRegistrations();

javax.servlet.FilterRegistration.Dynamic addFilter(String var1, String var2);

javax.servlet.FilterRegistration.Dynamic addFilter(String var1, Filter var2);

javax.servlet.FilterRegistration.Dynamic addFilter(String var1, Class<? extends Filter> var2);

<T extends Filter> T createFilter(Class<T> var1) throws ServletException;

FilterRegistration getFilterRegistration(String var1);

Map<String, ? extends FilterRegistration> getFilterRegistrations();

SessionCookieConfig getSessionCookieConfig();

void setSessionTrackingModes(Set<SessionTrackingMode> var1);

Set<SessionTrackingMode> getDefaultSessionTrackingModes();

Set<SessionTrackingMode> getEffectiveSessionTrackingModes();

void addListener(String var1);

<T extends EventListener> void addListener(T var1);

void addListener(Class<? extends EventListener> var1);

<T extends EventListener> T createListener(Class<T> var1) throws ServletException;

JspConfigDescriptor getJspConfigDescriptor();

ClassLoader getClassLoader();

void declareRoles(String... var1);

String getVirtualServerName();

int getSessionTimeout();

void setSessionTimeout(int var1);

String getRequestCharacterEncoding();

void setRequestCharacterEncoding(String var1);

String getResponseCharacterEncoding();

void setResponseCharacterEncoding(String var1);
}

ApplicationContext

在Tomcat中,ServletContext规范的实现是ApplicationContext,因为门面模式的原因,实际套了一层ApplicationContextFacade。关于什么是门面模式具体可以看这篇文章,简单来讲就是加一层包装。

其中ApplicationContext实现了ServletContext规范定义的一些方法,例如addServlet,addFilter等

StandardContext

StandardContext存在于org.apache.catalina.core.StandardContext。

实际上研究ApplicationContext的代码会发现,ApplicationContext所实现的方法其实都是调用的this.context中的方法

image.png

image.png

image.png

而这个this.context就是一个实例化的StandardContext对象。

image.png

所以在我看来,StandardContext是Tomcat中真正起作用的Context,负责跟Tomcat的底层交互,ApplicationContext其实更像对StandardContext的一种封装。

用下面这张图来展示一下其中的关系

image

回过头看内存马。以添加filter为例,从上面的分析我们可以知道ApplicationContext跟Standerdcontext这两个东西都有addFilter的方法。那么实际选用哪一个呢?其实两种办法都可以。三梦师傅在基于tomcat的内存 Webshell 无文件攻击技术这篇文章里是利用反射修改了Tomcat的LifecycleState,绕过限制条件调用的ApplicationContext中的addFilter方法。

image.png

image.png

但是因为实际上最终调用的还是StandardContext的addFilter方法,所以我们就可以直接调用StandardContext的addFilter方法进行绕过,从而省去了绕过一堆判断的过程。这种实现具体可以看这个师傅的公众号文章。

本文标题:关于Tomcat中的三个Context的理解

文章作者:yzddMr6

发布时间:2021年03月16日 - 08:31

最后更新:2021年03月15日 - 16:34

原始链接:https://yzddmr6.com/posts/tomcat-context/

许可协议: 转载请保留原文链接及作者。

yzddMr6 wechat
欢迎加入我的知识星球
你的支持将是我更新的动力!
yzddMr6 微信支付

微信支付

金士顿 DTSE9G2 128G U盘量产踩坑记
As-Exploits内存马兼容Spring
  • 文章目录
  • 站点概览
yzddMr6

yzddMr6

慢就是快,少就是多。
61 日志
3 分类
12 标签
RSS
GitHub E-Mail 简书
友情链接
  • NaiveKun
  • Fi9coder
  • Sardinefish
  • Panda
  • 九世
  • LFY
  • EarthC
  • Ablustrund
  1. 1. Context
  2. 2. ServletContext
  3. 3. ApplicationContext
  4. 4. StandardContext
© 2022 yzddMr6
|