一个简单的Servlet容器(二)

二.一个简单的Servlet容器

一.运行机制

1.Servlet容器Servlet规范定义了一个API标准,基于这个标准,程序员只需要实现业务逻辑,而无须关心核心逻辑,从而达到任务分工,简化工作量,服务至上的目的

2.     所有的Servlet都实现了一个统一的接口,Servlet接口申明了5个签名方法:

Init(ServletConfig config)

Service(ServletRequest request,ServletResponse response)

Destory( )

getServeltConfig()

getServletInfo()

3. 流程:

  • 等待http请求
  • 对应的servletRequest对象和servletResponse对象,
  • 判断请求的类型,如果是请求静态资源,则找到静态资源的文件,返回给客户端
  • 如果是Servlet请求,载入servlet类,调用service()方法,传入servletRequest对象和servletResponse对象

4.      流程图:

5.      这样设计便存在了一个严重的安全问题,容器中Sevice方法中的Sevletrequest参数ServletResponse参数,可以取到里面所有方法,这样一来,所有的参数暴露出来了,很明显,这样是不合适的,所以这里提供了一个解决方案-使用门面模式对Servletrequest和ServletResponse进行传递,这样一来,程序员只能访问固定的方法了,保障程序的健壮性。

6.      流程图:

 

二.实战代码

1.       Constans

package JayKing.ASimpleServlet;

import java.io.File;

public class Constans {
	public static final String SHUTDOWN_COMMAND = "/SHUTDOWN";
	public static final String WEB_ROOT = System.getProperty("user.dir") + File.separator + "webroot";
	public static final String errorMessage = "HTTP/1.1 404 File Not Found\r\n" + "Content-Type: text/html\r\n"
			+ "Content-Length: 23\r\n" + "\r\n" + "<h1>File Not Found</h1>";

}

2.       HttpServer

package JayKing.ASimpleServlet;

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 HttpServer {
	public static Boolean shutdown = false;

	public static void main(String[] args) {
		HttpServer server = new HttpServer();
		server.await();
	}

	private void await() {
		int port = 8080;
		ServerSocket serversocket = null;
		try {
			serversocket = new ServerSocket(port, 100, InetAddress.getByName("localhost"));
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		while (!shutdown) {
			Socket socket = null;
			InputStream in = null;
			OutputStream out = null;
			try {
				socket = serversocket.accept();
				in = socket.getInputStream();
				out = socket.getOutputStream();
				Request request = new Request(in);
				request.parse();
				Response response = new Response(out);
				response.setRequset(request);
				if (request.getUri().startsWith("/servlet/")) {
					
					ServletProcessor processor = new ServletProcessor();
					processor.process(request, response);
				} else {
					System.out.println("Uri:"+request.getUri());
					StaticResourceProcessor processor = new StaticResourceProcessor();
			        processor.process(request, response);
				}
				socket.close();
		        shutdown = request.getUri().equals(Constans.SHUTDOWN_COMMAND);
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			
		}
		

	}

}

3.       Requset

package JayKing.ASimpleServlet;

import java.io.IOException;
import java.io.InputStream;

public class Request implements ServletRequest{
	public InputStream in;
	public String uri;

	public Request(InputStream in) {
		this.in = in;
	}

	public String getUri() {
		return uri;
	}

	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 void parse() {
		StringBuffer request = new StringBuffer(2048);
		int i;
		byte[] buffer = new byte[2048];
		try {
			i = in.read(buffer);

		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			i = -1;
		}
		for (int j = 0; j < i; j++) {
			request.append((char) buffer[j]);
		}
		uri = parseUri(request.toString());
	}

}

4.       RequestFacade

package JayKing.ASimpleServlet;

public class RequestFacade implements ServletRequest {
	private ServletRequest resquest;

	public RequestFacade(Request request) {
		this.resquest = resquest;
	}

}

5.       Rseponse

package JayKing.ASimpleServlet;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.OutputStream;

public class Response implements ServletResponse{
	public static final int BUFFER_SIZE = 1024;
	Request request;
	OutputStream out;

	public Response(OutputStream out) {
		this.out = out;
	}

	public void setRequset(Request request) {
		this.request = request;
	}

	public void sendStaticRescourse() throws IOException {
		byte[] bytes = new byte[BUFFER_SIZE];
		FileInputStream fis = null;
		File file = new File(Constans.WEB_ROOT, request.getUri());
		try {
			fis = new FileInputStream(file);
			int ch = fis.read(bytes, 0, BUFFER_SIZE);
			while(ch!=-1){
				out.write(bytes,0,BUFFER_SIZE);
				ch=fis.read(bytes,0,BUFFER_SIZE);
			}

		} catch (FileNotFoundException e) {
			out.write(Constans.errorMessage.getBytes());
		} catch (IOException e) {		
			e.printStackTrace();
		} finally {
			if (fis!= null) {
				fis.close();
			}
		}

	}
}

6.       ResponseFacade

package JayKing.ASimpleServlet;

public class ResponseFacade implements ServletResponse {
	private ServletResponse response;

	public ResponseFacade(Response response) {
		this.response = response;
	}

}

7.       Servlet

package JayKing.ASimpleServlet;

public interface Servlet {
   public void init();
   public void service(ServletRequest servletrequest,ServletResponse servletresposne);
   public void destory();
}

8.       ServletProcessor

package JayKing.ASimpleServlet;

import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.net.URLStreamHandler;

public class ServletProcessor {

	public void process(Request request, Response response) {
		String uri = request.getUri();
		String ServletName = uri.substring(uri.lastIndexOf("/") + 1);
		ClassLoader classloader = null;
		Class myClass = null;
		String repository = null;
		URLClassLoader loader = null;
		URL[] urls = new URL[1];
		URLStreamHandler streamhandler = null;
		File classPath = new File(Constans.WEB_ROOT);
		try {
			repository = (new URL("file", null, classPath.getCanonicalPath() + File.separator)).toString();
			urls[0] = new URL(null, repository, streamhandler);
			loader = new URLClassLoader(urls);
			myClass = loader.loadClass(ServletName);
		} catch (MalformedURLException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		} catch (IOException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		Servlet servlet = null;
		RequestFacade requestFacade = new RequestFacade(request);
		ResponseFacade responseFacade = new ResponseFacade(response);
		try {
			servlet = (Servlet) myClass.newInstance();
			servlet.service((ServletRequest) requestFacade, (ServletResponse) responseFacade);
		} catch (InstantiationException | IllegalAccessException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}
}

9.       ServletRequest

package JayKing.ASimpleServlet;

public interface ServletRequest {

}

10.   ServletResponse

package JayKing.ASimpleServlet;

public interface ServletResponse {

}

11.   StaticResponseProcessor

package JayKing.ASimpleServlet;

import java.io.IOException;

public class StaticResourceProcessor {
	public void process(Request request,Response response){
		try {
			response.sendStaticRescourse();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

}

 

三.运行程序

静态资源:打开浏览器在地址栏中输入URL:Http://localhost:8080/index.html

Servlet资源:打开浏览器在地址栏中输入URL:Http://localhost:8080/Servlet/MyServlet




猜你喜欢

转载自blog.csdn.net/qq_32951553/article/details/80270609