Tomcat
依赖
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-core</artifactId>
<version>11.0.10</version>
</dependency>
<!-- 若用到jsp技术 -->
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
<version>11.0.10</version>
</dependency>结构介绍
Tomcat是Apache开发的开源Servlet容器其中,
WEB-INF目录是受保护的,客户端无法访问这个目录下的资源,保存应用的信息这个目录下面还有
classes/、lib/以及web.xmlclasses/存放Java程序的编译结果、lib/存放一系列第三方jar包其余应是一系列静态资源,例如
js/、css/、views/等常见的命名使用
maven管理项目的情况下,lib/不需要手动寻找、配置传统部署:指
Tomcat服务器包含开发者开发的.war包这样的Web应用,Servlet应用开发好后打包成.war包并复制到Tomcat服务器中,然后启动服务器传统部署中,
classes/与lib/由Tomcat解包.war文件得到内嵌
tomcat:指Tomcat API作为java程序的一部分而存在,若使用maven的情况下调用Tomcat实例的addWebapp()方法,实例会从指定的路径中找到WEB-INF/web.xml文件并解析,然后生成classes/与lib/等在target/下
web.xml映射
这是一种比较传统的映射方式,仅了解即可
web.xml应位于webapp/WEB-INF目录下,其中webapp为自定义的网页应用的名字,web.xml里的所有的配置会覆盖注解形式的映射声明为
webapp:xml<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" id="WebApp_ID" version="4.0"> </web-app>声明一个
Servlet:xml<servlet> <servlet-name>Servlet_name</servlet-name> <servlet-class>类路径</servlet-class> </servlet>将
Servlet映射到某个路径上:xml<servlet-mapping> <servlet-name>Servlet_name</servlet-name> <url-pattern>/路径</url-pattern> </servlet-mapping>初始化某个
Servlet或某个Filter的参数(ServletConfig):xml<init-param> <param-name>param_name</param-name> <param-value>xml文件、字符串等</param-value> </init-param>设置
ServletContext的配置:xml<context-param> <param-name>name</param-name> <param-value>value</param-value> </context-param>设置欢迎文件:
xml<welcome-file-list> <welcome-file>index.html</welcome-file> </welcome-file-list>设置
session的生效时间xml<session-config> <session-timeout>30</session-timeout> </session-config>
注解映射
@WebServlet注解:在Servlet 3.0前,需要在web.xml中配置大量信息,在WebServlet注解出现后,所有的配置被分散到各个服务类上,最重要且必要的属性是urlPatterns,是String集合,表示这些URI均映射到这个Servlet类上在传统部署时,它们的解析是全自动的
内嵌Tomcat
内嵌部署
Tomcat显得更加灵活,由开发者完全控制Tomcat的配置,但因此注解映射、静态资源需要由开发者亲自解析、引入,因此在不借用Spring boot框架的情况下,直接配置web.xml并调用addWebapp()或手动通过Tomcat对象注册服务以及配置映射是更常用的可以理解为:通过
web.xml配置的底层实现就是让addWebapp()解析该xml文件,并间接地在内部调用addServlet()、addMapping()等方法由
new Tomcat()直接构造一个Tomcat实例,调用start()启动该服务器(会抛出LifecycleException受检异常),调用getServer().await()使该服务器不断地等待请求Tomcat实例方法:setHostname(String):设置服务器地址setPort(int):设置服务器端口setBaseDir(String):设置基准目录,表示Tomcat实例工作时,临时文件等存放的根目录,这里的临时文件不是classes/与lib/等,而是运行时生成的文件,例如jsp翻译后生成的文件推荐设置为
target/下的某个目录getConnector():获取其绑定的连接器,这个方法在首次调用时会进行一系列的初始化操作,包括应用在此前设置的baseDir等参数这个方法应尽量晚些调用
Context addWebapp(String contextPath, String docBase):添加Web应用并获取它的上下文实例contextPath指上下文的根所映射的URL路径,例如传入""则该上下文会映射到"/"docBase指要引入的资源的本地路径,提供的路径下必须含有WEB-INF目录及web.xml文件等价于将整个
Web应用加载到服务器上,使用addWebapp()会自动生成并注册一个默认的Servlet服务,当客户端访问那些在用户自定义Servlet服务中找不到的服务时,会转向这个默认服务默认服务会试图在
docBase下的静态资源中查询是否有对应的资源,若找到则返回,否则返回404响应Context addContext(String contextPath, String docBase):添加一个空白的上下文实例,参数意义同上addServlet(String contextPath, String servletName, Servlet serv):登记一个名为servletName的微服务,对应到路径为contextPath的上下文有静态方法的版本,其中
contextPath应替换为Context对象同时需要使用
Context实例的addServletMappingDecoded(String pattern, String name)将微服务映射到URL的某个路径上这两步等价于在
web.xml中声明Servlet服务和映射该方法返回的
Wrapper对象可链式调用addMapping(String pattern),它等价于使用Context实例的addServletMappingDecoded()方法
上下文类
Context抽象的是整个Web容器,和ServletContext不同,一般作用于容器启动前,而后者作用于Web应用运行中处理业务,Context常用的实例方法有:addWelcomeFile(String):设置当客户端访问根路径时,返回的资源文件即将
String指向的资源文件映射到"/"addServletMappingDecoded(String pattern, String name):将微服务映射到某个URL上addFilterDef(FilterDef):登记一个Filter,由FilterDef封装其信息FilterDef常用方法:setFilter(Filter)、setFilterName(String)、addInitParameter(String, Object)分别为登记
Filter对象、登记Filter服务名、初始化Filter参数addFilterMap(FilterMap):登记从Filter到URL的映射,由FilterMap封装映射信息FilterMap常用方法:addURLPatternDecoded(String)、addServletName(String)、setFilterName(String)分别为登记其应用的
URL、登记其应用的Servlet、设置其绑定的Filter服务名
例子
基本配置:
javaTomcat tomcat = new Tomcat(); tomcat.setHostname("localhost"); tomcat.setPort(8080); tomcat.setBaseDir("/target/tomcat/"); // // ...其它配置... // tomcat.getConnector(); tomcat.init(); tomcat.start(); tomcat.getServer().await();Servlet等配置:javaString contextPath = "/api"; // String docBase = new File("/src/main/webapp").getAbsolutePath(); String docBase = Path.of("/src/main/webapp").toAbsolutePath().toString(); Context context = tomcat.addContext(contextPath, docBase); String servletName = "ServletDemo"; tomcat.addServlet(contextPath, servletName, new ServletDemo()).addMapping("/*"); // context.addServletMappingDecoded("/*", servletName); FilterDef filterDef = new FilterDef(); filterDef.setFilter((req, resp, chain) -> { // 过滤 ... // 链式处理 chain.doFilter(req, resp); }); filterDef.setFilterName("FilterDemo"); FilterMap filterMap = new FilterMap(); filterMap.addURLPatternDecoded("/*"); filterMap.addServletName(servletName); filterMap.setFilterName("FilterDemo"); context.addFilterDef(filterDef); context.addFilterMap(filterMap);上述配置与以下配置是近乎等价的,只是以下配置会有多出一个默认的
Servlet服务,用于检索静态资源javatomcat.addWebapp("/api", "src/main/webapp/");xml<!-- web.xml --> <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" id="WebApp_ID" version="4.0"> <servlet> <servlet-name>ServletDemo</servlet-name> <servlet-class>demo.servlet.ServletDemo</servlet-class> </servlet> <servlet-mapping> <servlet-name>ServletDemo</servlet-name> <url-pattern>/*</url-pattern> </servlet-mapping> <filter> <filter-name>FilterDemo</filter-name> <filter-class>无法用lambda表达式声明的接口实现</filter-class> </filter> <filter-mapping> <filter-name>FilterDemo</filter-name> <!-- 针对/*这个URL路径设置Filter --> <url-pattern>/*</url-pattern> <!-- 针对ServletDemo这个服务单独设置Filter --> <servlet-name>ServletDemo</servlet-name> </filter-mapping> </web-app>