To upgrade an HTTP server to a servlet container

Source: Internet
Author: User
Tags locale

The last blog post tells you how to write a simple HTTP server, but only requests static resources, so in this blog post, you upgrade a simple HTTP server to a servlet container.

You can handle both static resources and simple servlets.

Now, looking at the development of the Servlet program from the perspective of a servlet container, it is simple to say that for each HTTP request to a servlet, a fully functional servlet container has several things to do:

* When a servlet is called for the first time, it is loaded into the servlet class and called, its init () method.

* Create one Javax.servlet.ServletRequest instance and one Javax.servlet.ServletResponse instance per request.

* Call the Servlet's service method, passing the ServletRequest object and the Servletresponse object as parameters.

* When the servlet class is closed, its destroy () method is called and the servlet is unloaded.

Of course, the servlet container written in this post does not have such a full range of functions and can only perform some of these functions.

This servlet container is done on top of the HTTP server, so it just adds a few classes and enhances the functionality. Where the servlet container consists of the following classes.

*httpserver

*request

*response

*staticresourceprocessor

*servletprocessor

The source code for the above five classes is:

Httpserver:

Package Cn.com.servletserver;import Java.io.file;import Java.io.inputstream;import java.io.outputstream;import Java.net.inetaddress;import Java.net.serversocket;import Java.net.socket;public class HttpServer {/** * WEB_ROOT is the directory where our HTML and other files reside. * Package,web_root is the "Webroot" directory under the * working directory. * The working directory is the location of the file system * from where the Java command was invoke. */public static final String web_root=system.getproperty ("User.dir") +file.separator+ "Webroot";p rivate static final String shutdown_command= "/shutdown";p rivate boolean shutdown=false;public static void Main (string[] args) {Httpserver Server=new httpserver (); server.await ();} public void await () {ServerSocket serversocket=null;int port=8080;try {serversocket=new serversocket (port,1, Inetaddress.getbyname ("127.0.0.1"));} catch (Exception e) {e.printstacktrace (); System.exit (0);} 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 Parserequest request=new request (input); Request.parse ();// Create Response objectresponse response=new Response (output); Response.setrequest (request);//check If this is a request For a servlet or//a static resource//a request for a servlet begins with '/servlet ' if (Request.geturi (). StartsWith ("/servle t/")) {servletprocessor processor=new servletprocessor ();p rocessor.process (request, response);} Else{staticresourceprocessor processor=new staticresourceprocessor ();p rocessor.process (request, response);} Close the socket Socket.close ();//check if the previous URI is a shutdown commandshutdown=request.geturi (). Equals (Shutd Own_command);} catch (Exception e) {e.printstacktrace (); System.exit (1);}}}
This httpserver class is similar to the previous Httpserver class, but the Httpserver class in the application can be either a static resource request or a servlet resource request.

The await () method in this class waits for an HTTP request until a close command is received, and this method can distribute the HTTP request to the Staticresourceprocessor object

or Servletprocesor object to handle, when the URL contains the string "/servlet/", the request will be forwarded to the Servletprocessor object processing, otherwise, the HTTP request is passed to the

Staticresourceprocessor object processing.

Request:

Package Cn.com.servletserver;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.asynccontext;import Javax.servlet.dispatchertype;import Javax.servlet.requestdispatcher;import Javax.servlet.servletcontext;import Javax.servlet.ServletInputStream; Import Javax.servlet.servletrequest;import Javax.servlet.servletresponse;public class Request implements ServletRequest {private InputStream input;private String uri;public Request (InputStream input) {this.input=input;} public void Parse () {//read A set of characters from the Socketstringbuffer request=new StringBuffer (2048); int i;byte[] Buf Fer=new byte[2048];try {i=input.read (buffer);} catch (Exception 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 ());} Public String Parseuri(String requeststring) {int Index1,index2;index1=requeststring.indexof (""), if (index1!=-1) {Index2=requeststring.indexof ("", index1+1); (INDEX2&GT;INDEX1) {return requeststring.substring (INDEX1+1,INDEX2);}} return null;} Public String GetURI () {return this.uri;} @Overridepublic Asynccontext Getasynccontext () {//TODO auto-generated method Stubreturn null;} @Overridepublic Object getattribute (String arg0) {//TODO auto-generated method Stubreturn null;} @Overridepublic enumeration<string> Getattributenames () {//TODO auto-generated method Stubreturn null;} @Overridepublic String getcharacterencoding () {//TODO auto-generated method Stubreturn null;} @Overridepublic int Getcontentlength () {//TODO auto-generated method Stubreturn 0;} @Overridepublic long Getcontentlengthlong () {//TODO auto-generated method Stubreturn 0;} @Overridepublic String getContentType () {//TODO auto-generated method Stubreturn null;} @Overridepublic Dispatchertype Getdispatchertype () {//TODO auto-generated method stubreturn null;} @Overridepublic ServletInputStream getInputStream () throws IOException {//TODO auto-generated method Stubreturn null;} @Overridepublic String getlocaladdr () {//TODO auto-generated method Stubreturn null;} @Overridepublic String Getlocalname () {//TODO auto-generated method Stubreturn null;} @Overridepublic int Getlocalport () {//TODO auto-generated method Stubreturn 0;} @Overridepublic Locale GetLocale () {//TODO auto-generated method Stubreturn null;} @Overridepublic enumeration<locale> Getlocales () {//TODO auto-generated method Stubreturn null;} @Overridepublic string GetParameter (String arg0) {//TODO auto-generated method Stubreturn null;} @Overridepublic map<string, string[]> getparametermap () {//TODO auto-generated method Stubreturn null;} @Overridepublic enumeration<string> Getparameternames () {//TODO auto-generated method Stubreturn null;} @Overridepublic string[] Getparametervalues (String arg0) {//TODO auto-generated method Stubreturn null;} @OverridEpublic String Getprotocol () {//TODO auto-generated method Stubreturn null;} @Overridepublic BufferedReader Getreader () throws IOException {//TODO auto-generated method Stubreturn null;} @Overridepublic string Getrealpath (String arg0) {//TODO auto-generated method Stubreturn null;} @Overridepublic String getremoteaddr () {//TODO auto-generated method Stubreturn null;} @Overridepublic String Getremotehost () {//TODO auto-generated method Stubreturn null;} @Overridepublic int Getremoteport () {//TODO auto-generated method Stubreturn 0;} @Overridepublic requestdispatcher getrequestdispatcher (String arg0) {//TODO auto-generated method Stubreturn null;} @Overridepublic String Getscheme () {//TODO auto-generated method Stubreturn null;} @Overridepublic String getServerName () {//TODO auto-generated method Stubreturn null;} @Overridepublic int Getserverport () {//TODO auto-generated method Stubreturn 0;} @Overridepublic ServletContext Getservletcontext () {//TODO auto-generated method Stubreturn null;} @Overridepublic Boolean isasyncstarted () {//TODO auto-generated method Stubreturn false;} @Overridepublic Boolean isasyncsupported () {//TODO auto-generated method Stubreturn false;} @Overridepublic Boolean issecure () {//TODO auto-generated method Stubreturn false;} @Overridepublic void RemoveAttribute (String arg0) {//TODO auto-generated method stub} @Overridepublic void SetAttribute ( String arg0, Object arg1) {//TODO auto-generated method stub} @Overridepublic void Setcharacterencoding (String arg0) throw s unsupportedencodingexception {//TODO auto-generated method stub} @Overridepublic asynccontext Startasync () throws illegalstateexception {//TODO auto-generated method Stubreturn null;} @Overridepublic asynccontext Startasync (servletrequest arg0, Servletresponse arg1) throws IllegalStateException {// TODO auto-generated method Stubreturn null;}}
The request class handles the servlet and therefore implements the javax. All the methods declared in the Servlet.servletrequest interface, but only the simple servlet is handled here, so only the

A small number of methods, mostly left blank, are left to be implemented later.

Response:

Package Cn.com.servletserver;import Java.io.file;import Java.io.fileinputstream;import java.io.IOException;import Java.io.outputstream;import Java.io.printwriter;import Java.util.locale;import Javax.servlet.ServletOutputStream; Import javax.servlet.servletresponse;/** * HTTP Response = status-line * * ((General-header | response-header | entity-hea der) CRLF) * CRLF * [message-body] * status-line=http-version sp status-code sp reason-phrase CRLF * */public class Resp Onse implements servletresponse{private static final int buffer_size=1024; Request Request;outputstream output; PrintWriter writer;public Response (outputstream output) {this.output=output;} public void Setrequest (Request request) {This.request=request;} public void Sendstaticresource () throws ioexception{byte[] Bytes=new byte[buffer_size]; FileInputStream fis=null;try {file File=new file (Httpserver.web_root,request.geturi ()); if (File.exists ()) {Fis=new FileInputStream (file); int ch=fis.read (bytes,0,buffer_size); while (ch!=-1) {OUTPUT.WRIte (bytes, 0, buffer_size); ch=fis.read (bytes, 0, buffer_size);}} Else{//file not foundstring errormessage= "http/1.1 404 File Not found\r\n" + "content-type:text/html\r\n" + " content-length:23\r\n "+" \ r \ n "+" The response class implements the Javax.servlet.ServletRequest interface, which provides implementations of all the methods declared in the Servletresponse interface, similar to the request class, except

Except for the Getwriter () method, the implementation of most methods is left blank.

In the Getwriter () method, the constructor of the PrintWriter class The second argument is a Boolean value that indicates whether AutoFlush is enabled. True for the second argument indicates any call to the println () method

Refreshes the output, but does not flush the output when the print () method is called, so a small bug is left here that will be resolved later.

Staticresourceprocessor:

Package Cn.com.servletserver;public class Staticresourceprocessor {public void process (Request request,response Response) {try {Response.sendstaticresource ()} catch (Exception e) {e.printstacktrace ()}}}
The class has only one method, the process () method, and only one use, that is, to handle static resources.

Servletprocessor:

Package Cn.com.servletserver;import Java.io.file;import Java.net.url;import java.net.urlclassloader;import Java.net.urlstreamhandler;import Javax.servlet.servlet;import Javax.servlet.servletrequest;import javax.servlet.servletresponse;/** * This class is used to process requests for servlet resources * @author Administrator * */public class Servletprocessor { public void process (Request request,response Response) {String Uri=request.geturi (); String servletname=uri.substring (Uri.lastindexof ("/") +1); URLClassLoader loader=null;try {url[] urls=new url[1]; URLStreamHandler Streamhandle=null; File Classpath=new file (httpserver.web_root);//the forming of repository is taken from//the Createclassloader method in// Org.apache.catalina.startup.ClassLoaderFactoryString repository= (New URL ("File", Null,classpath.getcanonicalpath ( ). +file.separator). toString ();//the code for forming the URL is taken from//the Addrepository method in//org.apache.catal Ina.loader.standardclassloaderurls[0]=new URL (null,repository,streamhandle); Loader=new URLClassLOader (URLs);} catch (Exception e) {System.out.println (e.tostring ());} Class myclass=null;try {myclass=loader.loadclass ("cn.com.client.") +servletname);} catch (ClassNotFoundException e) {System.out.println (e.tostring ());} Servlet servlet=null;try {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 ());}}}
This class is also relatively simple, with only one method: the process () method, which handles requests to the servlet resource,

However, this class has a certain problem, the original servlet resource is simply put into Webroot, but here it can not request Webroot in the servlet resources, can only put the servlet into the

SRC in a package in order to request to resources, so God knows please give me a hint.

The servlet used for testing is relatively simple and the source code is as follows:

Package Cn.com.client;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 {@Overridepublic void Destroy () {}@ Overridepublic ServletConfig Getservletconfig () {return null;} @Overridepublic String Getservletinfo () {return null;} @Overridepublic void init (ServletConfig arg0) throws servletexception {} @Overridepublic void service (ServletRequest Request, Servletresponse response) throws Servletexception, IOException {System.out.print ("from service"); PrintWriter out=response.getwriter (); Out.println ("Hello. Roses is red. "); O Ut.print ("Violets is Blue");}
Now, let's do the testing.

page :

So, a simple servlet container is complete, but there are a lot of problems to be solved one after the other.

To upgrade an HTTP server to a servlet container

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.