深入刨析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的了