tomcat(5)servlet容器(lastest version)
public void invoke(Request request, Response response) //SimplePipeline.invoke()方法throws IOException, ServletException {// Invoke the first Valve in this pipeline for this request(new SimplePipelineValveContext()).invokeNext(request, response);}public void removeValve(Valve valve) {}// this class is copied from org.apache.catalina.core.StandardPipeline class's// StandardPipelineValveContext inner class.protected class SimplePipelineValveContext implements ValveContext {protected int stage = 0;public String getInfo() {return null;}public void invokeNext(Request request, Response response)throws IOException, ServletException {int subscript = stage; // init stage == 0.stage = stage + 1;// Invoke the requested Valve for the current request threadif (subscript < valves.length) {valves[subscript].invoke(request, response, this); // 若非基础阀是 ClientIPLoggerValve}else if ((subscript == valves.length) && (basic != null)) {basic.invoke(request, response, this); // this line, 直到基础阀才停止遍历非基础阀}else {throw new ServletException("No valve");}}} // end of inner class
public class ClientIPLoggerValve implements Valve, Contained {protected Container container;public void invoke(Request request, Response response, ValveContext valveContext)throws IOException, ServletException {// Pass this request on to the next valve in our pipelinevalveContext.invokeNext(request, response); // 继续回调 SimplePipeline.invokeNext(),直到基础阀System.out.println("Client IP Logger Valve");ServletRequest sreq = request.getRequest();System.out.println(sreq.getRemoteAddr()); // this line outputs ip addr to the console.System.out.println("------------------------------------");}
public final class Bootstrap1 {public static void main(String[] args) {/* call by using http://localhost:8080/ModernServlet,but could be invoked by any name */HttpConnector connector = new HttpConnector();Wrapper wrapper = new SimpleWrapper();wrapper.setServletClass("servlet.ModernServlet"); // 设置servlet的相对路径Loader loader = new SimpleLoader(); // 类加载器Valve valve1 = new HeaderLoggerValve(); // 把请求头信息output到 consoleValve valve2 = new ClientIPLoggerValve();// 用来将client的IP 地址输出到控制台上wrapper.setLoader(loader);((Pipeline) wrapper).addValve(valve1); // 新增阀 ,key line((Pipeline) wrapper).addValve(valve2); // 新增阀, key lineconnector.setContainer(wrapper);try {connector.initialize(); // 创建服务器套接字connector.start(); // // make the application wait until we press a key.System.in.read();}catch (Exception e) {e.printStackTrace();}}
}
public synchronized void addValve(Valve valve) { // SimpleWrapper.addValve()pipeline.addValve(valve);}
public void addValve(Valve valve) { // SimplePipeline.addValve()if (valve instanceof Contained)((Contained) valve).setContainer(this.container);synchronized (valves) {Valve results[] = new Valve[valves.length +1];System.arraycopy(valves, 0, results, 0, valves.length);results[valves.length] = valve;valves = results;}}
public interface Valve {
public String getInfo();
public void invoke(Request request, Response response,ValveContext context)throws IOException, ServletException;
}
public interface ValveContext {
public String getInfo();
public void invokeNext(Request request, Response response)throws IOException, ServletException;
}
public interface Contained {
public Container getContainer();
public void setContainer(Container container);
}
public Servlet allocate() throws ServletException { // SimpleWrapper.allocate() method.// Load and initialize our instance if necessaryif (instance==null) {try {instance = loadServlet(); // this line}catch (ServletException e) {throw e;}catch (Throwable e) {throw new ServletException("Cannot allocate a servlet instance", e);}}return instance;}private Servlet loadServlet() throws ServletException { // this line if (instance!=null)return instance;Servlet servlet = null;String actualClass = servletClass;if (actualClass == null) {throw new ServletException("servlet class has not been specified");}Loader loader = getLoader(); // this line// Acquire an instance of the class loader to be usedif (loader==null) {throw new ServletException("No loader.");}ClassLoader classLoader = loader.getClassLoader(); // this line// Load the specified servlet class from the appropriate class loaderClass classClass = null;try {if (classLoader!=null) {classClass = classLoader.loadClass(actualClass);}}catch (ClassNotFoundException e) {throw new ServletException("Servlet class not found");}// Instantiate and initialize an instance of the servlet class itselftry {servlet = (Servlet) classClass.newInstance();}catch (Throwable e) {throw new ServletException("Failed to instantiate servlet");}// Call the initialization method of this servlettry {servlet.init(null);}catch (Throwable f) {throw new ServletException("Failed initialize servlet.");}return servlet;}public Loader getLoader() { // this lineif (loader != null)return (loader);if (parent != null)return (parent.getLoader());return (null);}
public class SimpleLoader implements Loader { // return class loaderpublic static final String WEB_ROOT =System.getProperty("user.dir") + File.separator + "webroot";ClassLoader classLoader = null;Container container = null;public SimpleLoader() {try {URL[] urls = new URL[1];URLStreamHandler streamHandler = null;File classPath = new File(WEB_ROOT);String repository = (new URL("file", null, classPath.getCanonicalPath() + File.separator)).toString() ;urls[0] = new URL(null, repository, streamHandler);classLoader = new URLClassLoader(urls);}catch (IOException e) {System.out.println(e.toString() );}}public ClassLoader getClassLoader() {return classLoader;}
public class SimplePipeline implements Pipeline {public SimplePipeline(Container container) {setContainer(container);}protected Valve basic = null;protected Container container = null;protected Valve valves[] = new Valve[0];public void setContainer(Container container) {this.container = container;}public Valve getBasic() {return basic;}public void setBasic(Valve valve) {this.basic = valve;((Contained) valve).setContainer(container);}public void addValve(Valve valve) {if (valve instanceof Contained)((Contained) valve).setContainer(this.container);synchronized (valves) {Valve results[] = new Valve[valves.length +1];System.arraycopy(valves, 0, results, 0, valves.length);results[valves.length] = valve;valves = results;}} public void invoke(Request request, Response response)throws IOException, ServletException {// Invoke the first Valve in this pipeline for this request(new SimplePipelineValveContext()).invokeNext(request, response);} protected class SimplePipelineValveContext implements ValveContext {protected int stage = 0;public String getInfo() {return null;}public void invokeNext(Request request, Response response)throws IOException, ServletException {int subscript = stage; // init stage == 0.stage = stage + 1;// Invoke the requested Valve for the current request threadif (subscript < valves.length) {valves[subscript].invoke(request, response, this);}else if ((subscript == valves.length) && (basic != null)) {basic.invoke(request, response, this);}else {throw new ServletException("No valve");}}} // end of inner class
public Servlet allocate() throws ServletException {// Load and initialize our instance if necessaryif (instance==null) {try {instance = loadServlet();}catch (ServletException e) {throw e;}catch (Throwable e) {throw new ServletException("Cannot allocate a servlet instance", e);}}return instance;}private Servlet loadServlet() throws ServletException {if (instance!=null)return instance;Servlet servlet = null;String actualClass = servletClass;if (actualClass == null) {throw new ServletException("servlet class has not been specified");}Loader loader = getLoader();// Acquire an instance of the class loader to be usedif (loader==null) {throw new ServletException("No loader.");}ClassLoader classLoader = loader.getClassLoader();// Load the specified servlet class from the appropriate class loaderClass classClass = null;try {if (classLoader!=null) {classClass = classLoader.loadClass(actualClass);}}catch (ClassNotFoundException e) {throw new ServletException("Servlet class not found");}// Instantiate and initialize an instance of the servlet class itselftry {servlet = (Servlet) classClass.newInstance();}catch (Throwable e) {throw new ServletException("Failed to instantiate servlet");}// Call the initialization method of this servlettry {servlet.init(null);}catch (Throwable f) {throw new ServletException("Failed initialize servlet.");}return servlet;}
public class SimpleWrapperValve implements Valve, Contained {protected Container container;public void invoke(Request request, Response response, ValveContext valveContext)throws IOException, ServletException {SimpleWrapper wrapper = (SimpleWrapper) getContainer();ServletRequest sreq = request.getRequest();ServletResponse sres = response.getResponse();Servlet servlet = null;HttpServletRequest hreq = null;if (sreq instanceof HttpServletRequest)hreq = (HttpServletRequest) sreq;HttpServletResponse hres = null;if (sres instanceof HttpServletResponse)hres = (HttpServletResponse) sres;// Allocate a servlet instance to process this requesttry {servlet = wrapper.allocate();if (hres!=null && hreq!=null) {servlet.service(hreq, hres);}else {servlet.service(sreq, sres);}}catch (ServletException e) {} }
public final class Bootstrap1 {public static void main(String[] args) {/* call by using http://localhost:8080/ModernServlet,but could be invoked by any name */HttpConnector connector = new HttpConnector();Wrapper wrapper = new SimpleWrapper();wrapper.setServletClass("servlet.ModernServlet"); // 设置servlet的相对路径Loader loader = new SimpleLoader(); // 类加载器Valve valve1 = new HeaderLoggerValve(); // 把请求头信息output到 consoleValve valve2 = new ClientIPLoggerValve();// 用来将client的IP 地址输出到控制台上wrapper.setLoader(loader);((Pipeline) wrapper).addValve(valve1); // 新增阀((Pipeline) wrapper).addValve(valve2); // 新增阀connector.setContainer(wrapper);try {connector.initialize(); // 创建服务器套接字connector.start(); // // make the application wait until we press a key.System.in.read();}catch (Exception e) {e.printStackTrace();} }}
E:\bench-cluster\cloud-data-preprocess\HowTomcatWorks\src>java -cp .;lib/servlet.jar;lib/catalina_4_1_24.jar;E:\bench-cluster\cloud-data-preprocess\HowTomcatWorks\webroot com.tomcat.chapter5.startup/B ootstrap1
HttpConnector Opening server socket on all host IP addresses
HttpConnector[8080] Starting background thread
ModernServlet -- init
Client IP Logger Valve
127.0.0.1
------------------------------------
Header Logger Valve
host:localhost:8080
connection:keep-alive
accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
user-agent:Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.71 Safari/537.36
accept-encoding:gzip, deflate, sdch
accept-language:zh-CN,zh;q=0.8,en;q=0.6
------------------------------------
Client IP Logger Valve
127.0.0.1
------------------------------------
Header Logger Valve
host:localhost:8080
connection:keep-alive
accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
user-agent:Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.71 Safari/537.36
accept-encoding:gzip, deflate, sdch
accept-language:zh-CN,zh;q=0.8,en;q=0.6
------------------------------------
【6】Context应用程序
public interface Mapper {public Container getContainer(); // 返回与该映射器相关联的servlet容器的实例;public void setContainer(Container container); // 设置与该映射器相关联的servlet容器;public String getProtocol(); // 返回该映射器负责处理的协议public void setProtocol(String protocol); //指定该映射器负责处理哪种协议public Container map(Request request, boolean update); // 返回要处理某个特定请求的子容器的实例;
}
public void invoke(Request request, Response response)throws IOException, ServletException {// Invoke the first Valve in this pipeline for this request(new SimplePipelineValveContext()).invokeNext(request, response); // 会调用所有添加到Context 实例中的阀,然后再调用基础阀的invoke方法;}
public class SimpleContextValve implements Valve, Contained {protected Container container;public void invoke(Request request, Response response, ValveContext valveContext)throws IOException, ServletException {// Validate the request and response object typesif (!(request.getRequest() instanceof HttpServletRequest) ||!(response.getResponse() instanceof HttpServletResponse)) {return; // NOTE - Not much else we can do generically}// Disallow any direct access to resources under WEB-INF or META-INFHttpServletRequest hreq = (HttpServletRequest) request.getRequest();String contextPath = hreq.getContextPath();String requestURI = ((HttpRequest) request).getDecodedRequestURI();String relativeURI =requestURI.substring(contextPath.length()).toUpperCase();Context context = (Context) getContainer();// Select the Wrapper to be used for this RequestWrapper wrapper = null;try {wrapper = (Wrapper) context.map(request, true); // the core line, <span style="font-family: SimSun; font-size: 18px; line-height: 24px;">使用了 Context实例的映射器来查找 Wrapper容器</span>}
public Container map(Request request, boolean update) { // SimpleContextMapper.map()// Identify the context-relative URI to be mappedString contextPath =((HttpServletRequest) request.getRequest()).getContextPath();String requestURI = ((HttpRequest) request).getDecodedRequestURI();String relativeURI = requestURI.substring(contextPath.length());// Apply the standard request URI mapping rules from the specificationWrapper wrapper = null;String servletPath = relativeURI;String pathInfo = null;String name = context.findServletMapping(relativeURI); // this lineif (name != null)wrapper = (Wrapper) context.findChild(name); // and this linereturn (wrapper);}
}
public String findServletMapping(String pattern) { // SimpleContext.findServletMapping()synchronized (servletMappings) {return ((String) servletMappings.get(pattern));// protected HashMap servletMappings = new HashMap();}}
public Container findChild(String name) { // SimpleContext.findChild()if (name == null)return (null);synchronized (children) { // Required by post-start changesreturn ((Container) children.get(name));// protected HashMap children = new HashMap();}}
public class SimpleContext implements Context, Pipeline {public SimpleContext() {pipeline.setBasic(new SimpleContextValve());}protected HashMap children = new HashMap();protected Loader loader = null;protected SimplePipeline pipeline = new SimplePipeline(this);protected HashMap servletMappings = new HashMap();protected Mapper mapper = null;protected HashMap mappers = new HashMap();private Container parent = null;public void addServletMapping(String pattern, String name) {synchronized (servletMappings) {servletMappings.put(pattern, name);}}public String findServletMapping(String pattern) {synchronized (servletMappings) {return ((String) servletMappings.get(pattern));}}public Loader getLoader() {if (loader != null)return (loader);if (parent != null)return (parent.getLoader());return (null);}public void addChild(Container child) {child.setParent((Container) this);children.put(child.getName(), child);}public void addMapper(Mapper mapper) {// this method is adopted from addMapper in ContainerBase// the first mapper added becomes the default mappermapper.setContainer((Container) this); // May throw IAEthis.mapper = mapper;synchronized(mappers) {if (mappers.get(mapper.getProtocol()) != null)throw new IllegalArgumentException("addMapper: Protocol '" +mapper.getProtocol() + "' is not unique");mapper.setContainer((Container) this); // May throw IAEmappers.put(mapper.getProtocol(), mapper);if (mappers.size() == 1)this.mapper = mapper;elsethis.mapper = null;}}public Container findChild(String name) {if (name == null)return (null);synchronized (children) { // Required by post-start changesreturn ((Container) children.get(name));}}public Container[] findChildren() {synchronized (children) {Container results[] = new Container[children.size()];return ((Container[]) children.values().toArray(results));}}public ContainerListener[] findContainerListeners() {return null;}public Mapper findMapper(String protocol) {// the default mapper will always be returned, if any,// regardless the value of protocolif (mapper != null)return (mapper);elsesynchronized (mappers) {return ((Mapper) mappers.get(protocol));}}public void invoke(Request request, Response response)throws IOException, ServletException {pipeline.invoke(request, response);}public Container map(Request request, boolean update) {//this method is taken from the map method in org.apache.cataline.core.ContainerBase//the findMapper method always returns the default mapper, if any, regardless the//request's protocolMapper mapper = findMapper(request.getRequest().getProtocol());if (mapper == null)return (null);// Use this Mapper to perform this mappingreturn (mapper.map(request, update));}
public final class Bootstrap2 { public static void main(String[] args) {HttpConnector connector = new HttpConnector(); Wrapper wrapper1 = new SimpleWrapper(); // 最低级的servlet容器 Wrapper,利用加载器动态加载和封装servletwrapper1.setName("Primitive");wrapper1.setServletClass("servlet.PrimitiveServlet");Wrapper wrapper2 = new SimpleWrapper();wrapper2.setName("Modern");wrapper2.setServletClass("servlet.ModernServlet");Context context = new SimpleContext(); // 比Wrapper高一级的容器 Context,可以context.addChild(wrapper1);context.addChild(wrapper2);Valve valve1 = new HeaderLoggerValve(); // 非基础阀Valve valve2 = new ClientIPLoggerValve(); // 非基础阀((Pipeline) context).addValve(valve1);((Pipeline) context).addValve(valve2); // 添加基础阀到 ContextMapper mapper = new SimpleContextMapper(); // 映射器mapper.setProtocol("http");context.addMapper(mapper); // 将映射器添加到 contextLoader loader = new SimpleLoader(); // 类加载器context.setLoader(loader); // 将该类加载器设置到context容器中// context.addServletMapping(pattern, name);context.addServletMapping("/Primitive", "Primitive"); // 添加servlet访问路径映射(put到HashMap中)context.addServletMapping("/Modern", "Modern");connector.setContainer(context); // 设置容器到Tomcat 连接器try {connector.initialize();connector.start();// make the application wait until we press a key.System.in.read();}catch (Exception e) {e.printStackTrace();}}
}
protected HashMap children = new HashMap(); // servlet资源名称 和 具体servlet资源URI(类加载器加载路径) 的映射集合。
protected HashMap servletMappings = new HashMap();// 访问路径和servlet资源名称的映射集合protected HashMap mappers = new HashMap(); // 映射器集合(一个Context容器可以有多个映射器)
以上代码的调用steps:(client发出HTTP请求(请求资源的URI,如 http://localhost:8080/Modern )后,server的处理过程)
public final class Bootstrap2 {public static void main(String[] args) {HttpConnector connector = new HttpConnector();Wrapper wrapper1 = new SimpleWrapper(); // 最低级的servlet容器 Wrapper,利用加载器动态加载和封装servletwrapper1.setName("Primitive");wrapper1.setServletClass("servlet.PrimitiveServlet");Wrapper wrapper2 = new SimpleWrapper();wrapper2.setName("Modern");wrapper2.setServletClass("servlet.ModernServlet");Context context = new SimpleContext(); // 比Wrapper高一级的容器 Context,可以context.addChild(wrapper1);context.addChild(wrapper2);Valve valve1 = new HeaderLoggerValve(); // 非基础阀Valve valve2 = new ClientIPLoggerValve(); // 非基础阀((Pipeline) context).addValve(valve1);((Pipeline) context).addValve(valve2); // 添加非基础阀到 ContextMapper mapper = new SimpleContextMapper(); // 映射器mapper.setProtocol("http");context.addMapper(mapper); // 将映射器添加到 contextLoader loader = new SimpleLoader(); // 类加载器context.setLoader(loader); // 将该类加载器设置到context容器中// context.addServletMapping(pattern, name);context.addServletMapping("/Primitive", "Primitive"); // 添加servlet访问路径映射(put到HashMap中)context.addServletMapping("/Modern", "Modern");connector.setContainer(context); // 设置容器到Tomcat 连接器try {connector.initialize();connector.start();// make the application wait until we press a key.System.in.read();}catch (Exception e) {e.printStackTrace();}}
}
E:\bench-cluster\cloud-data-preprocess\HowTomcatWorks\src>java -cp .;lib/servlet.jar;lib/catalina_4_1_24.jar;E:\bench-cluster\cloud-data-preprocess\HowTomcatWorks\webroot com.tomcat.chapter5.startup.
Bootstrap2
HttpConnector Opening server socket on all host IP addresses
HttpConnector[8080] Starting background thread
Client IP Logger Valve
127.0.0.1
------------------------------------
Header Logger Valve
host:localhost:8080
connection:keep-alive
accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
user-agent:Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.71 Safari/537.36
accept-encoding:gzip, deflate, sdch
accept-language:zh-CN,zh;q=0.8,en;q=0.6
------------------------------------
init
from service
Client IP Logger Valve
127.0.0.1
------------------------------------
tomcat(5)servlet容器(lastest version)相关推荐
- tomcat(5)servlet容器
[0]README 0.0)本文部分文字描述转自:"深入剖析tomcat",旨在学习 tomcat(5)servlet容器 的基础知识: 0.1)intro to servlet容 ...
- SpringBoot之配置嵌入式Servlet容器
1.概述 文章目录 1.概述 2.如何修改SpringBoot的默认配置 3.定制和修改Servlet容器的相关配置 4.注册Servlet三大组件 5.替换为其他嵌入式Servlet容器 6.嵌入式 ...
- Spring Boot切换其他嵌入式的Servlet容器
Spring Boot默认支持: Tomcat(默认使用) <dependency><groupId>org.springframework.boot</groupId& ...
- Spring boot切换Servlet容器
切换Servlet容器 Spring boot默认配置Tomcat作为Servlet容器 引入web模块,默认使用嵌入式的Tomcat 可以切换Jetty.Undertow 默认配置 Pom文件,查看 ...
- servlet容器_Tomcat 容器与servlet的交互原理
点击蓝字"程序员考拉"欢迎关注! Tomcat 是Web应用服务器,是一个Servlet/JSP容器. Tomcat 作为Servlet容器,负责处理客户请求,把请求传送给Serv ...
- tomcat和servlet的关系
tomcat和servlet的关系 Tomcat 是Web应用服务器,是一个Servlet/JSP容器. Tomcat 作为Servlet容器,负责处理客户请求,把请求传送给Servlet,并将Ser ...
- spring boot没有web.xml,如何向嵌入式的servlet容器中注册servlet组件
1. Spring boot默认使用Tomcat作为嵌入式的servlet容器,只要引入spring-boot-starter-web依赖,就会默认用Tomcat作为servlet容器. 2. Spr ...
- tomcat和servlet的关系及区别
tomcat和servlet的关系及区别 Tomcat 是Web应用服务器,是一个Servlet/JSP容器. Tomcat 作为Servlet容器,负责处理客户请求,把请求传送给Servlet,并将 ...
- springboot-嵌入式Servlet容器(Tomcat)源码分析以及容器切换
目录 一.springboot的嵌入式Servlet容器(tomcat) 1.原理 2.源码 (1)ServletWebServerApplicationContext的createWebServer ...
最新文章
- HDOJ HDU 2080 夹角有多大II ACM 2080 IN HDU
- 神经网络收敛标准与准确率之间的数学关系
- Qt中qDebug()技巧初探
- 李彦宏:AI在我有生之年不会毁灭人类
- 李航第一章课后习题答案
- opencv:图像的基本变换
- 2021中国家居行业洞察白皮书
- hue集成mysql报错_hue集成hive访问报database is locked
- 我为啥要当程序员未来规划漫谈
- python面向对象——类(上)
- vmware安装报错及注册时无权输入许可证密钥的解决办法及步骤
- 自带浏览器打不开网页?
- “扣哒杯” AI世青赛公布2021-2022年度全国决赛个人获奖名单
- CSS特效--图像悬停效果
- 面试通过了,也给了Offer,不去有什么后果?
- 杭电多校联赛2017年总结
- 【深度学习】云服务器推荐及教程
- NOIP 2018 滚粗记(bushi)
- Spark 的共享变量之累加器和广播变量
- 【JAVA】计算算式
热门文章
- test120200612shu
- Vue整合SpringBoot项目实战之Vue+Element-Ui搭建前端项目
- python检查交换机端口状态_Python3 自动登录全部交换机查询MAC所在端口
- 图像处理系列05——Jetson Xavier NX平台JPEG硬解
- Android 开发 TCP协议
- java-php-python-ssm校园面包超市系统计算机毕业设计
- Unity功能—— 在VS中快速访问Unity API对应文档
- 西北农林科技大学linux实验报告,西北农林科技大学 linux考试复习提纲
- EO、DTO、ViewModel的区别
- (一)kibana使用