easyhaohao 发表于 2013-1-14 07:15:03

TOMCAT4 简单Context

Context 代表一个WEB应用
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 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 mapper    mapper.setContainer((Container) this);      // May throw IAE    this.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 IAE      mappers.put(mapper.getProtocol(), mapper);      if (mappers.size() == 1)      this.mapper = mapper;      else      this.mapper = null;    }}public Container findChild(String name) {    if (name == null)      return (null);    synchronized (children) {       // Required by post-start changes      return ((Container) children.get(name));    }}public Container[] findChildren() {    synchronized (children) {      Container results[] = new Container;      return ((Container[]) children.values().toArray(results));    }}public Mapper findMapper(String protocol) {    // the default mapper will always be returned, if any,    // regardless the value of protocol    if (mapper != null)      return (mapper);    else      synchronized (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 protocol    Mapper mapper = findMapper(request.getRequest().getProtocol());    if (mapper == null)      return (null);    // Use this Mapper to perform this mapping    return (mapper.map(request, update));}}


Mapper用于定位到相应的Wrapper
public class SimpleContextMapper implements Mapper {private SimpleContext context = null;public Container getContainer() {    return (context)}public void setContainer(Container container) {    if (!(container instanceof SimpleContext))      throw new IllegalArgumentException      ("Illegal type of container");    context = (SimpleContext) container;}public String getProtocol() {    return null;}public void setProtocol(String protocol) {}/**   * Return the child Container that should be used to process this Request,   * based upon its characteristics.If no such child Container can be   * identified, return <code>null</code> instead.   *   * @param request Request being processed   * @param update Update the Request to reflect the mapping selection?   *   * @exception IllegalArgumentException if the relative portion of the   *path cannot be URL decoded   */public Container map(Request request, boolean update) {    // Identify the context-relative URI to be mapped    String 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 specification    Wrapper wrapper = null;    String servletPath = relativeURI;    String pathInfo = null;    String name = context.findServletMapping(relativeURI);    if (name != null)      wrapper = (Wrapper) context.findChild(name);    return (wrapper);}}

BasicValve 的任务是调用指定Wrapper的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 types    if (!(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-INF    HttpServletRequest 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 Request    Wrapper wrapper = null;    try {      wrapper = (Wrapper) context.map(request, true);    }    catch (IllegalArgumentException e) {      badRequest(requestURI, (HttpServletResponse) response.getResponse());      return;    }    if (wrapper == null) {      notFound(requestURI, (HttpServletResponse) response.getResponse());      return;    }    // Ask this Wrapper to process this Request    response.setContext(context);    wrapper.invoke(request, response);}    public Container getContainer() {    return container;}public void setContainer(Container container) {    this.container = container;}private void badRequest(String requestURI, HttpServletResponse response) {    try {      response.sendError(HttpServletResponse.SC_BAD_REQUEST, requestURI);    }    catch (IllegalStateException e) {      ;    }    catch (IOException e) {      ;    }}private void notFound(String requestURI, HttpServletResponse response) {    try {      response.sendError(HttpServletResponse.SC_NOT_FOUND, requestURI);    }    catch (IllegalStateException e) {      ;    }    catch (IOException e) {      ;    }}}

启动类:
public final class Bootstrap2 {public static void main(String[] args) {    HttpConnector connector = new HttpConnector();    Wrapper wrapper1 = new SimpleWrapper();    wrapper1.setName("Primitive");    wrapper1.setServletClass("PrimitiveServlet");    Wrapper wrapper2 = new SimpleWrapper();    wrapper2.setName("Modern");    wrapper2.setServletClass("ModernServlet");    Context context = new SimpleContext();    context.addChild(wrapper1);    context.addChild(wrapper2);    Valve valve1 = new HeaderLoggerValve();    Valve valve2 = new ClientIPLoggerValve();    ((Pipeline) context).addValve(valve1);    ((Pipeline) context).addValve(valve2);    Mapper mapper = new SimpleContextMapper();    mapper.setProtocol("http");    context.addMapper(mapper);    Loader loader = new SimpleLoader();    context.setLoader(loader);    // context.addServletMapping(pattern, name);    context.addServletMapping("/Primitive", "Primitive");    context.addServletMapping("/Modern", "Modern");    connector.setContainer(context);    try {      connector.initialize();      connector.start();      // make the application wait until we press a key.      System.in.read();    }    catch (Exception e) {      e.printStackTrace();    }}}
页: [1]
查看完整版本: TOMCAT4 简单Context