将http服务器升级为servlet容器

上一篇博文讲了如何编写一个简单的http服务器,但只能请求静态的资源,因此,在这一篇博文中,将简单的http服务器升级为servlet容器,

既可处理静态资源,也能请求简单的servlet。

现在呢,从servlet容器的角度审视servlet程序的开发,简单来说,对一个servlet的每个http请求,一个功能齐全的servlet容器有以下几件事要做:

*当第一次调用某个servlet时,要载入该servlet类,并调用,其init()方法。

*针对每个request请求,创建一个javax.servlet.ServletRequest实例和一个javax.servlet.ServletResponse实例。

*调用该servlet的service方法,将ServletRequest对象和ServletResponse对象作为参数传入。

*当关闭该servlet类,调用其destroy()方法,并卸载该servlet。

当然呢,本篇博文写的servlet容器并没有这么齐全的功能,只能完成其中的部分功能。

这个servlet容器是在http服务器的基础上完成,因此只是增加了几个类,并对其中的功能进行了增强。其中,该servlet容器包括以下几个类。

*HttpServer

*Request

*Response

*StaticResourceProcessor

*ServletProcessor

上面五个类的源码为:

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. * For this package,WEB_ROOT is the "webroot" directory under the * working directory. * the working directory is the location in the file system * from where the java command was invoke. */public static final String WEB_ROOT=System.getProperty("user.dir")+File.separator+"webroot";private static final String SHUTDOWN_COMMAND="/SHUTDOWN";private 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("/servlet/")){ServletProcessor processor=new ServletProcessor();processor.process(request, response);}else{StaticResourceProcessor processor=new StaticResourceProcessor();processor.process(request, response);}//close the socketsocket.close();//check if the previous URI is a shutdown commandshutdown=request.getUri().equals(SHUTDOWN_COMMAND);} catch (Exception e) {e.printStackTrace();System.exit(1);}}}}这个HttpServer类与上一个HttpServer类相似,但是该应用程序中的HttpServer类既可对静态资源请求,也可以对于servlet资源请求。

这个类中的await()方法会一直等待HTTP请求,直到接收到一条关闭命令,并且这个方法可以将http请求分发给StaticResourceProcessor对象

或ServletProcesor对象来处理,当url包含字符串"/servlet/"时,会把请求转发给ServletProcessor对象处理,否则的话,把http请求传递给

StaticResourceProcessor对象处理。

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[] buffer=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);if(index2>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)throws 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;}}Request类要处理servlet,因此实现了javax.Servlet.ServletRequest接口中声明的所有方法,但在此只需处理简单的servlet,因此,只实现了

少量的方法,大部分留空,留待以后再来实现。

Response:

但要相信真诚的爱情,对爱情永远怀有单纯的向往。

将http服务器升级为servlet容器

相关文章:

你感兴趣的文章:

标签云: