Tomcat从零开始(十五)session管理的代码

来源:互联网 发布:tcp端口重复使用 编辑:程序博客网 时间:2024/06/05 16:44

第十五节

简介

我之前好像很长时间没有把完整的代码贴上了,其实我觉得前14节都是一些基础性的东西。我们先来回忆一下,之前学了什么。 刚开始主要是想让大家先把tomcat理解成一个Connector 和 container的合体。之后我们知道connector是为了建立连接的,我们讲了tomcat4的默认连接器,虽然现在被替代了。Container是用来处理请求的,说了Container的四种类型。以及其中的pipeline, vavle。其实我觉得这些  不需要我做什么  代码来示范,而是  应该自己去读读tomcat的代码。所以,这节课  我不再写那么长的代码了,我们用tomcat已经写好的jar包。那么开始

Bootstrap

package com.vic.startup;import org.apache.catalina.Connector;import org.apache.catalina.Context;import org.apache.catalina.Lifecycle;import org.apache.catalina.LifecycleListener;import org.apache.catalina.Loader;import org.apache.catalina.Manager;import org.apache.catalina.Wrapper;import org.apache.catalina.connector.http.HttpConnector;import org.apache.catalina.core.StandardContext;import org.apache.catalina.loader.WebappLoader;import org.apache.catalina.session.StandardManager;import com.vic.core.SimpleContextConfig;import com.vic.core.SimpleWrapper;public class Bootstrap {public static void main(String[] args) {//这里以前说过了,把catalina.base设置为一个系统属性  值  为 用户的当前工作目录System.setProperty("catalina.base", System.getProperty("user.dir"));//建立一个连接器Connector connector = new HttpConnector();//这里帮大家复习一下,wrapper负责管理Servlet,所以下面的代码不言而喻Wrapper wrapper1 = new SimpleWrapper();wrapper1.setName("Session");wrapper1.setServletClass("SessionServlet");Context context = new StandardContext();//一个context包含多个wrappercontext.setPath("/myApp");context.setDocBase("myApp");context.addChild(wrapper1);context.addServletMapping("/myApp/Session", "Session");//这是生命周期的时候讲的,这次我们用自己实现的,具体原因一会讲LifecycleListener listener = new SimpleContextConfig();((Lifecycle) context).addLifecycleListener(listener);Loader loader = new WebappLoader();context.setLoader(loader);connector.setContainer(context);//添加一个Manager,这是12.13.14节的知识Manager manager = new StandardManager();context.setManager(manager);try {connector.initialize();((Lifecycle) connector).start();((Lifecycle) context).start();//当我们在Console窗口输入一个字节的时候,我们的web服务器就自动停止了System.in.read();((Lifecycle) context).stop();}catch (Exception e) {e.printStackTrace();}}}

好的,我在解释应该把 这个 bootstrap介绍的差不多了。接下来看core包的代码。

SimpleContextConfig

首先就是 实现了LifecycleListener接口的SimpleContextConfig。这个是我们自己实现的。
package com.vic.core;import org.apache.catalina.Context;import org.apache.catalina.Lifecycle;import org.apache.catalina.LifecycleEvent;import org.apache.catalina.LifecycleListener;public class SimpleContextConfig implements LifecycleListener {public void lifecycleEvent(LifecycleEvent event) {if (Lifecycle.START_EVENT.equals(event.getType())) {Context context = (Context) event.getLifecycle();context.setConfigured(true);}}}
这个没什么说的,Lifecycle我这里说过了~

SimplePipeline

这里基本就是从tomcat的StandardPipeline中copy的。
package com.vic.core;import java.io.IOException;import javax.servlet.ServletException;import org.apache.catalina.Contained;import org.apache.catalina.Container;import org.apache.catalina.Lifecycle;import org.apache.catalina.LifecycleException;import org.apache.catalina.LifecycleListener;import org.apache.catalina.Pipeline;import org.apache.catalina.Request;import org.apache.catalina.Response;import org.apache.catalina.Valve;import org.apache.catalina.ValveContext;public class SimplePipeline implements Pipeline, Lifecycle {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 Valvesprotected Valve valves[] = new Valve[0];public void setContainer(Container container) {this.container = container;}public Valve getBasic() {return basic;}public void setBasic(Valve valve) {this.basic = valve;((Contained) valve).setContainer(container);}public void addValve(Valve valve) {if (valve instanceof Contained)((Contained) valve).setContainer(this.container);synchronized (valves) {Valve results[] = new Valve[valves.length + 1];System.arraycopy(valves, 0, results, 0, valves.length);results[valves.length] = valve;valves = results;}}public Valve[] getValves() {return valves;}public void invoke(Request request, Response response) throws IOException,ServletException {// Invoke the first Valve in this pipeline for this request(new StandardPipelineValveContext()).invokeNext(request, response);}public void removeValve(Valve valve) {}// implementation of the Lifecycle interface's methodspublic void addLifecycleListener(LifecycleListener listener) {}public LifecycleListener[] findLifecycleListeners() {return null;}public void removeLifecycleListener(LifecycleListener listener) {}public synchronized void start() throws LifecycleException {}public void stop() throws LifecycleException {}// this class is copied from org.apache.catalina.core.StandardPipeline// class's// StandardPipelineValveContext inner class.protected class StandardPipelineValveContext implements ValveContext {protected int stage = 0;public String getInfo() {return null;}public void invokeNext(Request request, Response response)throws IOException, ServletException {int subscript = stage;stage = stage + 1;// Invoke the requested Valve for the current request threadif (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}

SimpleWrapper

这个同样,基本也是copy的,这里没什么重点。
package com.vic.core;import java.beans.PropertyChangeListener;import java.io.IOException;import javax.naming.directory.DirContext;import javax.servlet.Servlet;import javax.servlet.ServletException;import javax.servlet.UnavailableException;import org.apache.catalina.Cluster;import org.apache.catalina.Container;import org.apache.catalina.ContainerListener;import org.apache.catalina.InstanceListener;import org.apache.catalina.Lifecycle;import org.apache.catalina.LifecycleException;import org.apache.catalina.LifecycleListener;import org.apache.catalina.Loader;import org.apache.catalina.Logger;import org.apache.catalina.Manager;import org.apache.catalina.Mapper;import org.apache.catalina.Pipeline;import org.apache.catalina.Realm;import org.apache.catalina.Request;import org.apache.catalina.Response;import org.apache.catalina.Valve;import org.apache.catalina.Wrapper;import org.apache.catalina.util.LifecycleSupport;public class SimpleWrapper implements Wrapper, Pipeline, Lifecycle {public SimpleWrapper() {pipeline.setBasic(new SimpleWrapperValve());}// the servlet instanceprivate Servlet instance = null;private String servletClass;private Loader loader;private String name;protected LifecycleSupport lifecycle = new LifecycleSupport(this);private SimplePipeline pipeline = new SimplePipeline(this);protected Container parent = null;protected boolean started = false;public synchronized void addValve(Valve valve) {pipeline.addValve(valve);}public Servlet allocate() throws ServletException {// Load and initialize our instance if necessaryif (instance == null) {try {instance = loadServlet();} catch (ServletException e) {throw e;} catch (Throwable e) {throw new ServletException("Cannot allocate a servlet instance", e);}}return instance;}public Servlet loadServlet() throws ServletException {if (instance != null)return instance;Servlet servlet = null;String actualClass = servletClass;if (actualClass == null) {throw new ServletException("servlet class has not been specified");}Loader loader = getLoader();// Acquire an instance of the class loader to be usedif (loader == null) {throw new ServletException("No loader.");}ClassLoader classLoader = loader.getClassLoader();// Load the specified servlet class from the appropriate class loaderClass classClass = null;try {if (classLoader != null) {classClass = classLoader.loadClass(actualClass);}} catch (ClassNotFoundException e) {throw new ServletException("Servlet class not found");}// Instantiate and initialize an instance of the servlet class itselftry {servlet = (Servlet) classClass.newInstance();} catch (Throwable e) {throw new ServletException("Failed to instantiate servlet");}// Call the initialization method of this servlettry {servlet.init(null);} catch (Throwable f) {throw new ServletException("Failed initialize servlet.");}return servlet;}public String getInfo() {return null;}public Loader getLoader() {if (loader != null)return (loader);if (parent != null)return (parent.getLoader());return (null);}public void setLoader(Loader loader) {this.loader = loader;}public Logger getLogger() {return null;}public void setLogger(Logger logger) {}public Manager getManager() {return null;}public void setManager(Manager manager) {}public Cluster getCluster() {return null;}public void setCluster(Cluster cluster) {}public String getName() {return name;}public void setName(String name) {this.name = name;}public Container getParent() {return parent;}public void setParent(Container container) {parent = container;}public ClassLoader getParentClassLoader() {return null;}public void setParentClassLoader(ClassLoader parent) {}public Realm getRealm() {return null;}public void setRealm(Realm realm) {}public DirContext getResources() {return null;}public void setResources(DirContext resources) {}public long getAvailable() {return 0;}public void setAvailable(long available) {}public String getJspFile() {return null;}public void setJspFile(String jspFile) {}public int getLoadOnStartup() {return 0;}public void setLoadOnStartup(int value) {}public String getRunAs() {return null;}public void setRunAs(String runAs) {}public String getServletClass() {return null;}public void setServletClass(String servletClass) {this.servletClass = servletClass;}public void addChild(Container child) {}public void addContainerListener(ContainerListener listener) {}public void addMapper(Mapper mapper) {}public void addPropertyChangeListener(PropertyChangeListener listener) {}public Container findChild(String name) {return null;}public Container[] findChildren() {return null;}public ContainerListener[] findContainerListeners() {return null;}public void addInitParameter(String name, String value) {}public void addInstanceListener(InstanceListener listener) {}public void addSecurityReference(String name, String link) {}public void deallocate(Servlet servlet) throws ServletException {}public String findInitParameter(String name) {return null;}public String[] findInitParameters() {return null;}public String findSecurityReference(String name) {return null;}public String[] findSecurityReferences() {return null;}public Mapper findMapper(String protocol) {return null;}public Mapper[] findMappers() {return null;}public void invoke(Request request, Response response) throws IOException,ServletException {pipeline.invoke(request, response);}public boolean isUnavailable() {return false;}public void load() throws ServletException {}public Container map(Request request, boolean update) {return null;}public void removeChild(Container child) {}public void removeContainerListener(ContainerListener listener) {}public void removeMapper(Mapper mapper) {}public void removeInitParameter(String name) {}public void removeInstanceListener(InstanceListener listener) {}public void removePropertyChangeListener(PropertyChangeListener listener) {}public void removeSecurityReference(String name) {}public void unavailable(UnavailableException unavailable) {}public void unload() throws ServletException {}// method implementations of Pipelinepublic Valve getBasic() {return pipeline.getBasic();}public void setBasic(Valve valve) {pipeline.setBasic(valve);}public Valve[] getValves() {return pipeline.getValves();}public void removeValve(Valve valve) {pipeline.removeValve(valve);}// implementation of the Lifecycle interface's methodspublic void addLifecycleListener(LifecycleListener listener) {}public LifecycleListener[] findLifecycleListeners() {return null;}public void removeLifecycleListener(LifecycleListener listener) {}public synchronized void start() throws LifecycleException {System.out.println("Starting Wrapper " + name);if (started)throw new LifecycleException("Wrapper already started");// Notify our interested LifecycleListenerslifecycle.fireLifecycleEvent(BEFORE_START_EVENT, null);started = true;// Start our subordinate components, if anyif ((loader != null) && (loader instanceof Lifecycle))((Lifecycle) loader).start();// Start the Valves in our pipeline (including the basic), if anyif (pipeline instanceof Lifecycle)((Lifecycle) pipeline).start();// Notify our interested LifecycleListenerslifecycle.fireLifecycleEvent(START_EVENT, null);// Notify our interested LifecycleListenerslifecycle.fireLifecycleEvent(AFTER_START_EVENT, null);}public void stop() throws LifecycleException {System.out.println("Stopping wrapper " + name);// Shut down our servlet instance (if it has been initialized)try {instance.destroy();} catch (Throwable t) {}instance = null;if (!started)throw new LifecycleException("Wrapper " + name + " not started");// Notify our interested LifecycleListenerslifecycle.fireLifecycleEvent(BEFORE_STOP_EVENT, null);// Notify our interested LifecycleListenerslifecycle.fireLifecycleEvent(STOP_EVENT, null);started = false;// Stop the Valves in our pipeline (including the basic), if anyif (pipeline instanceof Lifecycle) {((Lifecycle) pipeline).stop();}// Stop our subordinate components, if anyif ((loader != null) && (loader instanceof Lifecycle)) {((Lifecycle) loader).stop();}// Notify our interested LifecycleListenerslifecycle.fireLifecycleEvent(AFTER_STOP_EVENT, null);}}

SimpleWrapperValve

package com.vic.core;import java.io.IOException;import javax.servlet.Servlet;import javax.servlet.ServletException;import javax.servlet.ServletRequest;import javax.servlet.ServletResponse;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import org.apache.catalina.Contained;import org.apache.catalina.Container;import org.apache.catalina.Context;import org.apache.catalina.Request;import org.apache.catalina.Response;import org.apache.catalina.Valve;import org.apache.catalina.ValveContext;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;    Context context = (Context) wrapper.getParent();    request.setContext(context);    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;}}
这个类是重点,我们能看到第38/39行,为什么要设置这个req的context,因为当我们从req想要得到一个session,我们会调用它的getSession的动作,但是getSession肯定是先去拿context,再拿context的manager,之后manager .  就完事了。   所以,我们要设置req的context,所以就在servlet生存的wrapper中设置。

原创粉丝点击