前面的话
server.xml可以看作tomcat结构的缩影,读懂了它对tomcat的设计模型及处理机制也就了解了个大概。总之,读懂server.xml大有裨益。
文件结构预览
解读
-
Server元素
- 它表示整个tomcat容器,是tomcat的顶层元素,对应org.apache.catalina.Server接口,默认值为org.apache.catalina.core.StandardServer
- 一个Server表示一个完整的JVM独立组件 ,可以包含一个或多个Service元
- Server表示的是tomcat的整体抽象
-
Service元素
- 对应org.apache.catalina.Service接口,默认为org.apahce.catalina.core.StandardService
- 一个Service包含一个Engine元素和一个或多个Connector元素
-
Connector元素
- 表示与客户端实际交互的组件,负责接收客户端请求及返回响应结果
- AJP连接器:用于将Apache与Tomcat集成在一起,当Apache接收到动态内容请求时,通过在配置中指定的端口号将请求发送给在此端口号上监听的AJP连接器组件
-
Engine元素
- tomcat的标准独立引擎,分析请求中的HTTP头信息,并将请求转发到适当主机或虚拟主机上
- 默认虚拟主机是localhost
-
Host元素
- 一个Engine元素可以包括一个或多个Host元素
- Host元素定义了一个虚拟主机,包含一个或多个Web应用
-
Context元素
- 一个Context元素代表了一个运行在虚拟主机上的单个web应用
tomcat请求处理流程
假设请求为:http://localhost:8080/hxysea/index.jsp
- 请求发送到Tomcat上,被监听在8080端口的Connector获得
- Conncetor将请求交给它所在Service的Engine处理,并等待Engine响应
- Engine获取请求localhost/hxysea/index.jsp,匹配到主机名为locaohost虚拟主机Host,将请求交给此Host
- localhost这个Host获得请求hxysea/index.jsp,匹配到Conext名为hxysea的Context(如果匹配不到就把该请求交给路径名为""的Context去处理)
- path="/hxysea"的Context获得请求/index.jsp,在它的mapping table中寻找对应的servlet
- Context匹配到URL PATTERN为*.jsp的servlet,对应于JspServlet类
- 构造HttpServletRequest对象和HttpServletResponse对象,作为参数调用JspServlet的doGet或doPost方法
- Context把执行完的HttpServletResponse对象返回给Host
- Host把HttpServletResponse对象返回给Engine
- Engine把HttpServletResponse对象返回给Connector
- Connector把HttpServletResponse对象返回给客户端
一个完整的server.xml
<?xml version='1.0' encoding='utf-8'?>
<Server port="8005" shutdown="SHUTDOWN">
<Listener className="org.apache.catalina.startup.VersionLoggerListener" />
<Listener className="org.apache.catalina.core.AprLifecycleListener"
SSLEngine="on" />
<Listener className="org.apache.catalina.core.JasperListener" />
<Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener" />
<Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" />
<Listener className="org.apache.catalina.core.ThreadLocalLeakPreventionListener" />
<GlobalNamingResources>
<!-- 读取可编辑的conf/tomcat-users.xml文件,用于tomcat授权用户 -->
<Resource name="UserDatabase" auth="Container"
type="org.apache.catalina.UserDatabase" description="User database that can be updated and saved"
factory="org.apache.catalina.users.MemoryUserDatabaseFactory"
pathname="conf/tomcat-users.xml" />
</GlobalNamingResources>
<!-- Service是众多Connector的集合,这些Connector共享一个容器,但是Service不是一个容器,故不能定义Valves这样的子元素 -->
<Service name="Catalina">
<!-- 一个连接器 Connector表示请求和响应的接入端点,如:HTTP Connector、AJP Connector(配合Apache
HTTP Server,作后端处理) -->
<Connector port="8080" protocol="HTTP/1.1"
connectionTimeout="20000" redirectPort="8443" />
<Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />
<!-- Engine处理请求,分析HTTP请求头,将请求传递给合适的主机处理 -->
<Engine name="Catalina" defaultHost="localhost">
<!-- 账号锁定作用域 -->
<Realm className="org.apache.catalina.realm.LockOutRealm">
<Realm className="org.apache.catalina.realm.UserDatabaseRealm"
resourceName="UserDatabase" />
</Realm>
<Host name="localhost" appBase="webapps" unpackWARs="true"
autoDeploy="true">
<!-- 日志配置 -->
<Valve className="org.apache.catalina.valves.AccessLogValve"
directory="logs" prefix="localhost_access_log." suffix=".txt"
pattern="%h %l %u %t "%r" %s %b" />
</Host>
</Engine>
</Service>
</Server>
部署问题
- tomcat接收get请求,解决中文乱码问题,增加useBodyEndingForURI=true配置
<Connector connectionTimeout="20000" port="8080" protocol="HTTP/1.1" redirectPort="8443" useBodyEncodingForURI="true"/>