首先我们看看时序图(第一次画 可能在时序图规则上有些问题)
public class SimpleWrapper implements Wrapper, Pipeline { // the servlet instance private Servlet instance = null; private String servletClass; private Loader loader; private String name; private SimplePipeline pipeline = new SimplePipeline(this); protected Container parent = null; ... } public class SimplePipeline implements Pipeline { public SimplePipeline(Container container) { setContainer(container); } // The basic Valve (if any) associated with this Pipeline. protected Valve basic = null; // The Container with which this Pipeline is associated. protected Container container = null; // the array of Valves protected Valve valves[] = new Valve[0]; //所有的阀 }
invokeNext是StandardPipelineValveContext类中的方法(StandardPipelineValveContext是管道的一个内部类,因此可以访问管道的所有成员) public void invokeNext(Request request, Response response) throws IOException, ServletException { int subscript = stage; stage = stage + 1; // Invoke the requested Valve for the current request thread if (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
ok?如水般流过。下面这行代码值得我们仔细看看
valves[subscript].invoke(request, response, this);
也可参阅拙作
<<说说struts2中拦截器的请求流程一(模拟大致流程)>>public class HeaderLoggerValve 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 pipeline valveContext.invokeNext(request, response); System.out.println("Header Logger Valve"); ServletRequest sreq = request.getRequest(); if (sreq instanceof HttpServletRequest) { HttpServletRequest hreq = (HttpServletRequest) sreq; Enumeration<?> headerNames = hreq.getHeaderNames(); while (headerNames.hasMoreElements()) { String headerName = headerNames.nextElement().toString(); String headerValue = hreq.getHeader(headerName); System.out.println(headerName + ":" + headerValue); } } else System.out.println("Not an HTTP Request"); System.out.println("------------------------------------"); } }
public interface Pipeline { public Valve getBasic(); public void setBasic(Valve valve); public void addValve(Valve valve); public Valve[] getValves(); public void invoke(Request request, Response response) throws IOException, ServletException; public void removeValve(Valve valve); }Pipeline里面有个基础阀,是最后调用的,负责处理request对象鱼response对象。因而这里有getset方法
public interface Valve { public String getInfo(); public void invoke(Request request, Response response,ValveContext context) throws IOException, ServletException; }
public interface Contained { public Container getContainer(); public void setContainer(Container container); }
类图如下:
public class SimpleLoader implements Loader { public 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 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 request try { servlet = wrapper.allocate(); if (hres!=null && hreq!=null) { servlet.service(hreq, hres); } else { servlet.service(sreq, sres); } } catch (ServletException e) { } }
public final class Bootstrap1 { @SuppressWarnings("deprecation") 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("ModernServlet"); Loader loader = new SimpleLoader(); Valve valve1 = new HeaderLoggerValve(); Valve valve2 = new ClientIPLoggerValve(); 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(); } } }
how tomcat works 五 servlet容器 上
原文地址:http://blog.csdn.net/dlf123321/article/details/40110315