Code for Tomcat session management from scratch (15th)

Source: Internet
Author: User

I haven't pasted the complete code for a long time before the introduction in section 15th. In fact, I think the first 14 sections are basic things. Let's first recall what we learned. At the beginning, I mainly wanted to let everyone understand tomcat as a combination of ctor and container. Later, we know that ctor Ctor is used to establish a connection. We talked about tomcat4's default connector, although it is replaced now. The Container is used to process requests. It describes four types of Container. And pipeline and vavle. In fact, I don't think I need to demonstrate any code, but I should read the tomcat code myself. Therefore, I will not write so long code in this lesson. We will use the jar package that has been written by tomcat. Then start 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) {// As mentioned previously. base is set to the current working directory of the user as a System property value. setProperty ("catalina. base ", System. getProperty ("user. dir "); // create a Connector connector conne= new HttpConnector (); // Let's review it here. wrapper is responsible for Servlet management, the following code is self-evident: Wrapper wrapper1 = new SimpleWrapper (); wrapper1.setName ("Session"); wrapper1.setServletClass ("SessionServlet"); Context context = new StandardContext (); // one context contains multiple wrappercontext. setPath ("/myApp"); context. setDocBase ("myApp"); context. addChild (wrapper1); context. addServletMapping ("/myApp/Session", "Session"); // This is what we will talk about in the lifecycle. This time we will implement it by ourselves, for more information, see LifecycleListener listener = new SimpleContextConfig (); (Lifecycle) context ). addLifecycleListener (listener); Loader loader = new WebappLoader (); context. setLoader (loader); connector. setContainer (context); // Add a Manager. This is the knowledge Manager manager = new StandardManager (); context in section 12.13.14. setManager (manager); try {connector. initialize (); (Lifecycle) connector ). start (); (Lifecycle) context ). start (); // when we input a byte in the Console window, our web server automatically stops System. in. read (); (Lifecycle) context ). stop ();} catch (Exception e) {e. printStackTrace ();}}}

Okay, I should explain the bootstrap introduction. Next, let's look at the core package code. The first step is to implement SimpleContextConfig of the LifecycleListener interface. This is implemented by ourselves.
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);}}}
There is nothing to say about this. Lifecycle I mentioned here ~ SimplePipeline
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}
Similarly, SimpleWrapper is similar to copy, so there is no point here.
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;}}
This class is important. We can see why the req context should be set in row 38/39, because when we want to get a session from req, we will call its getSession action, however, getSession must first get the context, then the context manager, and then the manager. it's done. Therefore, we need to set the req context, so we can set it in the wrapper of the servlet.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.