Self simulation of a simple tomcat

Source: Internet
Author: User
Tags int size locale
responsibilities of the servlet container in general, a fully functional servlet container does some of the following for each HTTP request of the servlet:
1, when the first time the servlet is invoked, load the servlet class and invoke the Servlet's Init method, only once,
2, for each request, you need to create a request and response corresponding instance,
3, call the Servlet's service method while passing the ServletRequest and Servletresponse objects,
4, when the Servlet class is closed, the destroy method of invoking the servlet is written in the Servlet class.


Now I've modeled myself on the simplest tomcat, with the exception of the 1th and 4th, the basic functionality is implemented, and the code is as follows:

Package linkin;
Import java.io.IOException;
Import Java.io.InputStream;
Import Java.io.OutputStream;
Import java.net.InetAddress;
Import Java.net.ServerSocket;

Import Java.net.Socket; public class HttpServer1 {/** * web_root is the directory where we HTML and other files reside.
	 For this * package, Web_root is the "Webroot" directory under the working directory.
	 * The working directory is the "location in" file system from where the Java command was invoked.
	*///shutdown command private static final String Shutdown_command = "/shutdown";

	The shutdown command received private Boolean shutdown = false;
		public static void Main (string[] args) {HttpServer1 server = new HttpServer1 ();
	Server.await ();
		public void await () {ServerSocket serversocket = null;
		int port = 8080;
		try {serversocket = new ServerSocket (port, 1, Inetaddress.getbyname ("127.0.0.1"));
			catch (IOException e) {e.printstacktrace ();
		System.exit (1); }//LoOp waiting for a request while (!shutdown) {socket socket = NULL;
			InputStream input = null;
			OutputStream output = null;
				try {socket = serversocket.accept ();
				input = Socket.getinputstream ();
				Output = Socket.getoutputstream ();
				Create request object and parse request = new request (input);
				Request.parse ();
				Create Response object Response Response = new Response (output);
				Response.setrequest (Request); Check if this are a request for a servlet or/a static resource//a request for a servlet begins with "/SERVL
					et/"If" (Request.geturi (). StartsWith ("/servlet/")) {ServletProcessor1 processor = new ServletProcessor1 ();
				Processor.process (request, response);
					else {Staticresourceprocessor processor = new Staticresourceprocessor ();
				Processor.process (request, response);
				}//Close the socket Socket.close (); Check if the previous URI is a shutdown command
				shutdown = Request.geturi (). Equals (Shutdown_command);
				catch (Exception e) {e.printstacktrace ();
			System.exit (1); }
		}
	}
}

Package linkin;
Import Java.io.BufferedReader;
Import java.io.IOException;
Import Java.io.InputStream;
Import java.io.UnsupportedEncodingException;
Import java.util.Enumeration;
Import Java.util.Locale;

Import Java.util.Map;
Import Javax.servlet.RequestDispatcher;
Import Javax.servlet.ServletInputStream;

Import Javax.servlet.ServletRequest;
	public class Request implements ServletRequest {private InputStream input;

	Private String URI;
	Public Request (InputStream input) {this.input = input;
	Public String GetURI () {return URI;
		private string Parseuri (string requeststring) {int index1, index2;
		Index1 = Requeststring.indexof (");
			if (index1!=-1) {index2 = Requeststring.indexof (', index1 + 1);
		if (Index2 > Index1) return requeststring.substring (index1 + 1, index2);
	return null;
		public void Parse () {//Read a set of characters from the socket stringbuffer request = new StringBuffer (2048);
		int i; byte[] buffer = new BYTE[2048];
		try {i = input.read (buffer);
			catch (IOException e) {e.printstacktrace ();
		i =-1;
		for (int j = 0; J < i; J + +) {request.append ((char) buffer[j]);
		} System.out.print (Request.tostring ());
	URI = Parseuri (request.tostring ());
	}/* Implementation of ServletRequest */public Object getattribute (String attribute) {return null;
	Public enumeration Getattributenames () {return null;
	public string Getrealpath (string path) {return null;
	Public RequestDispatcher Getrequestdispatcher (String path) {return null;
	public Boolean issecure () {return false;
	Public String getcharacterencoding () {return null;
	public int getcontentlength () {return 0;
	Public String getContentType () {return null;
	Public ServletInputStream getInputStream () throws IOException {return null;
	Public Locale GetLocale () {return null;
	Public enumeration Getlocales () {return null; } publiC string GetParameter (string name) {return null;
	Public Map Getparametermap () {return null;
	Public enumeration Getparameternames () {return null;
	String[] Getparametervalues (String parameter) {return null;
	Public String Getprotocol () {return null;
	Public BufferedReader Getreader () throws IOException {return null;
	Public String getremoteaddr () {return null;
	Public String Getremotehost () {return null;
	Public String Getscheme () {return null;
	Public String getServerName () {return null;
	public int Getserverport () {return 0; The public void RemoveAttribute (string attribute) {} is public void setattribute (string key, Object value) {} Publi c void setcharacterencoding (String encoding) throws Unsupportedencodingexception {} @Override public String getlocal
	Addr () {return null;
	@Override public String Getlocalname () {return null;
@Override public int Getlocalport ()	{return 0;
	@Override public int Getremoteport () {return 0; }
}

Package linkin;
Import Java.io.File;
Import Java.io.FileInputStream;
Import java.io.FileNotFoundException;
Import java.io.IOException;
Import Java.io.OutputStream;
Import Java.io.PrintWriter;

Import Java.util.Locale;
Import Javax.servlet.ServletOutputStream;

Import Javax.servlet.ServletResponse;
	public class Response implements Servletresponse {private static final int buffer_size = 1024;
	public static final String web_root = System.getproperty ("User.dir") + File.separator + "Webroot";
	Request request;
	OutputStream output;

	PrintWriter writer;
	Public Response (OutputStream output) {this.output = output;
	public void Setrequest (Request request) {this.request = Request;  }/* This are used to serve static pages */public void Sendstaticresource () throws IOException {byte[] bytes
		= new Byte[buffer_size];
		FileInputStream FIS = null; try {/* Request.geturi has been replaced by Request.getrequesturi/file File = new file (Web_root, Request.getuRI ());
			FIS = new FileInputStream (file);
			 /* HTTP Response = status-line (General-header | response-header | 
			* entity-header) CRLF) CRLF [message-body] status-line = * Http-version sp status-code SP reason-phrase CRLF * *
			int ch = fis.read (bytes, 0, buffer_size);
				while (Ch!=-1) {output.write (bytes, 0, ch);
			ch = fis.read (bytes, 0, buffer_size); The catch (FileNotFoundException e) {String errormessage = "http/1.1 404 File Not found\r\n" + "Content-type:te
			xt/html\r\n "+" content-length:23\r\n "+" \ r \ n "+"  

Package linkin;

Import java.io.IOException;

public class Staticresourceprocessor
{public
	void process (Request request, Response Response)
	{
		try
		{
			response.sendstaticresource ();
		}
		catch (IOException e)
		{
			e.printstacktrace ();
		}
	}
}

Package linkin;
Import Java.io.File;
Import java.io.IOException;
Import Java.net.URL;
Import Java.net.URLClassLoader;
Import Java.net.URLStreamHandler;
Import Javax.servlet.Servlet;
Import Javax.servlet.ServletRequest;

Import Javax.servlet.ServletResponse; public class ServletProcessor1 {public void process (Request request, Response Response) {String URI = Request.geturi
		();
		String servletname = uri.substring (Uri.lastindexof ("/") + 1);
		URLClassLoader loader = null;
			try {//Create a urlclassloader url[] urls = new url[1];
			URLStreamHandler streamhandler = null;
			File ClassPath = new file (response.web_root); The forming of repository is taken to//Createclassloader method in//Org.apache.catalina.startup.ClassLo
			Aderfactory String repository = (new URL ("file", NULL, Classpath.getcanonicalpath () + file.separator)). ToString (); The code for forming the URL was taken from//the Addrepository method in//ORG.APACHE.CATALINA.LOADER.STandardclassloader.
			Urls[0] = new URL (null, Repository, streamhandler);
		Loader = new URLClassLoader (URLs);
		catch (IOException e) {System.out.println (e.tostring ());
		Class myClass = null;
			try {System.out.println (servletname);
		MyClass = Loader.loadclass (servletname);
		catch (ClassNotFoundException e) {System.out.println (e.tostring ());
		The servlet servlet = null;
			try {//Run reflection, initialize an instance, and then call the Servlet's service method.
			servlet = (servlet) myclass.newinstance ();
		Servlet.service (ServletRequest) request, (Servletresponse) response);
		catch (Exception e) {System.out.println (e.tostring ());
		catch (Throwable e) {System.out.println (e.tostring ()); }
	}
}

Package linkin;
Import java.io.IOException;

Import Java.io.PrintWriter;
Import Javax.servlet.Servlet;
Import Javax.servlet.ServletConfig;
Import javax.servlet.ServletException;
Import Javax.servlet.ServletRequest;

Import Javax.servlet.ServletResponse; public class Primitiveservlet implements Servlet {@Override public void init (ServletConfig config) throws Servletexcept
	Ion {System.out.println ("init");
	@Override public void Service (ServletRequest request, servletresponse response) throws Servletexception, IOException
		{System.out.println ("from service");
		PrintWriter out = Response.getwriter (); Out.println (" 




Supplementary Note:

First look at the above Servlet's processor to invoke the Servlet's service Method 2 lines of code:

try {
servlet = (servlet) myclass.newinstance ();
Servlet.service ((servletrequest) request, (Servletresponse) response);
}

Here's the problem: the processor we're writing is not meant to accept only servlet requests, so the parameters we're passing in here are the request and response types, but we're now calling the servlet, The ServletRequest and Servletresponse type parameters are also passed in, where it is dangerous to turn downward, in case the request and the corresponding is not a servlet type, right, So we just have to achieve an effect is to say: the 2 pieces of code that I posted on this request and response can only be used in our own classes, under my own package, and not in other places, so I'm just going to go down there and make sure there's no mistake. And also can ensure that the 2 classes inside the method is also safe, for example, the external class must not call the request Parseuri method, how to do it. There are 2 ways to achieve this:

1, the above request class and the response class have the default access rights, which means they can only be accessed in their own packages, so it's safe.

2, the use of façade design mode, the specific explanation please see my design mode inside of that article. The general meaning is in the above request and response outside again to encapsulate a façade, the request and response privatization, all the methods in fact still use this request and response class to invoke, In this case, there is no direct access to the request and response these 2 classes. The code is as follows:


Package linkin;

Import Java.io.BufferedReader;
Import java.io.IOException;
Import java.io.UnsupportedEncodingException;
Import java.util.Enumeration;
Import Java.util.Locale;
Import Java.util.Map;

Import Javax.servlet.RequestDispatcher;
Import Javax.servlet.ServletInputStream;
Import Javax.servlet.ServletRequest;

public class Requestfacade implements ServletRequest
{
	private servletrequest request = null;

	Public Requestfacade (Request request)
	{
		this.request = Request;
	}

	/* Implementation of the ServletRequest *
	/Public Object getattribute (String attribute)
	{return
		Request.getattribute (attribute);
	}

	Public enumeration Getattributenames ()
	{return
		request.getattributenames ();
	}

	......................
}




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.