1. 程式人生 > 其它 >深入刨析tomcat 之---第9篇 how tomcat works 第9章,Session的實現 關於request.setContext(context)

深入刨析tomcat 之---第9篇 how tomcat works 第9章,Session的實現 關於request.setContext(context)

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("<html>");
    out.println("<head><title>SessionServlet</title></head>");
    out.println("<body>");
    String value = request.getParameter("value");
    HttpSession session = request.getSession(true);
    out.println("<br>the previous value is " + 
      (String) session.getAttribute("value"));
    out.println("<br>the current value is " + value);
    session.setAttribute("value", value);
    out.println("<br><hr>");
    out.println("<form>");
    out.println("New Value: <input name=value>");
    out.println("<input type=submit>");
    out.println("</form>");
    out.println("</body>");
    out.println("</html>");
  }
}

這句報錯,要通過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的了