深入刨析tomcat 之---第9篇 how tomcat works 第9章,Session的实现 关于request.setContext(context)
阅读原文时间:2022年01月28日阅读:1

writedby 张艳涛,在学第9章session的时候,做了个实验在给的demo代码中添加了

package com.zyt.tomcat.ex09.core;

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;

    //-- new addition -----------------------------------  
    Context context = (Context) wrapper.getParent();  
    request.setContext(context);  
    //-------------------------------------  
    // 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 String getInfo() {  
    return null;  
}

public Container getContainer() {  
    return container;  
}

public void setContainer(Container container) {  
    this.container = container;  
}  

}

当看看11章的时候,使用 StandardWrapper,再次调用

    System.setProperty("catalina.base", System.getProperty("user.dir"));  
    HttpConnector connector = new HttpConnector();  
    StandardWrapper wrapper1 = new StandardWrapper();  
    wrapper1.setName("Primitive");  
    wrapper1.setServletClass("PrimitiveServlet");  
    wrapper1.setDebug(2);

    StandardWrapper wrapper2 = new StandardWrapper();  
    wrapper2.setName("Modern");  
    wrapper2.setServletClass("ModernServlet");  
    wrapper2.setDebug(2);

    Wrapper wrapper3 = new StandardWrapper();  
    wrapper3.setName("SessionZYT");  
    wrapper3.setServletClass("SessionServletZYT");  
    //wrapper3.setDebug(2);

    Context context= new StandardContext();  
    context.setPath("/myApp");  
    context.setDocBase("myApp");

    LifecycleListener listener = new SimpleContextConfig();  
    ((Lifecycle) context).addLifecycleListener(listener);

    context.addChild(wrapper1);  
    context.addChild(wrapper2);  
    context.addChild(wrapper3);  
    context.addServletMapping("/myApp/SessionZYT","SessionZYT");

这是如果你调用/myApp/SessionZYT  会报错,追随代码的时候发现了request对象没有context成员变量,所以

SessionServletZYT 类编译了,放在app目录下

import javax.servlet.ServletException;
import javax.servlet.SingleThreadModel;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.io.PrintWriter;

public class SessionServletZYT extends HttpServlet implements SingleThreadModel {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
System.out.println("SessionServlet -- service");
response.setContentType("text/html");
PrintWriter out = response.getWriter();
out.println(""); out.println("SessionServlet"); out.println(""); String value = request.getParameter("value"); HttpSession session = request.getSession(true); out.println("
the previous value is " + (String) session.getAttribute("value")); out.println("
the current value is " + value); session.setAttribute("value", value); out.println("


"); out.println("
"); out.println("New Value: "); out.println(""); out.println("
"); out.println(""); out.println("");
}
}

这句报错,要通过request.getContext() -->再次context.getManager(),查了半天也没答案,所以看到13章host就找到了设置的地方了

StandardHostMapper类中
public Container map(Request request, boolean update) {
// Has this request already been mapped?
if (update && (request.getContext() != null))
return (request.getContext());

    // Perform mapping on our request URI  
    String uri = ((HttpRequest) request).getDecodedRequestURI();  
    Context context = host.map(uri);

    // Update the request (if requested) and return the selected Context  
    if (update) {  
        request.setContext(context);  
        if (context != null)  
            ((HttpRequest) request).setContextPath(context.getPath());  
        else  
            ((HttpRequest) request).setContextPath(null);  
    }  
    return (context);

}

标记的就是 给request 设置了context的了