论坛首页 Java企业应用论坛

How Tomcat Works 读书笔记(第二章)

浏览 1716 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2009-11-15   最后修改:2010-03-06
第二章就实现了一个很简单的servletContainer,不但能出来静态资源,还能处理简单的servlet, 首先我们先看一下类图:
       其实很简单,比前一个没有什么多的增加,前面的HttpServer,这个类也是拦截请求,不过做了一下判断,如果是以/servlet/开头的,就动态的加载这个servlet,并调用它的service方法,这里并没有完全按照servlet的生命周期去处理,只是说明了一下而已,估计以后会有这方面的实现吧。在后面稍微提到了Facade设计模式。
       那个PrimitiveServlet实现了Servlet接口,它的service接口会接受一个ServletRequest和ServletResponse对象,所以在代码中会将我们的Request和Response向上转换成ServletRequest和ServletResponse传入,但是有个问题,如果我们知道容器内部是这么实现的,那在service方法里面就可以再给它强制转换过来,那么我们就可以调用Request和Response里面的公有方法了。那么我们可以讲这个接口的访问权限可以变换一下,但是只是治标不治本的办法,估计以后还会变的。反思一下问题主要是只提供给我们内部使用,对外部系统不进行暴露相应的接口,设计模式里面Facade模式很好的解决了这个问题。
      就是我们在实现一个RequestFacade和ResponseFacade类,这个类的构造方法会接受一个Reqeust和Response,我们只向外暴露ServletRequest和ServletResponse的方法,同样在这个问题里面,程序员也可以将其转化成RequestFacade和ResponseFacade对象,但是它向外暴露的接口是和ServletRequest和ServletResponse是一样的,所以这样就很好了。
package ex02.pyrmont;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.UnknownHostException;

public class HttpServer1 {
	public static void main(String[] args) {
		HttpServer1 httpServer = new HttpServer1();
		httpServer.await();
	}
	
	public void await(){
		int port = 8080;
		ServerSocket serverSocket = null;
		
		try {
			serverSocket = new ServerSocket(port,1,InetAddress.getByName("127.0.0.1"));
		} catch (UnknownHostException e) {
			e.printStackTrace();
			System.exit(1);
		} catch (IOException e) {
			e.printStackTrace();
			System.exit(1);
		}
		
		Socket socket = null;
		InputStream input = null;
		OutputStream out = null;
		
		try {
			socket = serverSocket.accept();
			input = socket.getInputStream();
			out = socket.getOutputStream();
			Request request = new Request(input);
			request.parse();
			
			Response response = new Response(out);
			String uri = request.getUri();
			if(uri.startsWith("/servlet/")){
				ServletProcessor servletProcessor = new ServletProcessor();
				servletProcessor.process(request, response);
			} else {
				StaticResourceProcessor staticProcessor = new StaticResourceProcessor();
				staticProcessor.process(request, response);
			}
			
			input.close();
			out.close();
			socket.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
		
	}
}


下面是处理servlet的方法。
package ex02.pyrmont;

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

import javax.servlet.Servlet;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

public class ServletProcessor {
	public void process(Request request,Response response){
		String uri = request.getUri();
		int lastSlash = uri.lastIndexOf("/");
		String servletName = uri.substring(lastSlash + 1);

		URLClassLoader loader = null;
		try {
			URL[] urls = new URL[1];
			URLStreamHandler streamHandler = null;
			File classpath = new File(Contants.WEB_ROOT);
			String repository = new URL("file",null,classpath.getCanonicalPath() + File.separator + servletName).toString();
			
			urls[0] = new URL(null,repository,streamHandler);
			loader = new URLClassLoader(urls);
		} catch (MalformedURLException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		
		Class clazz =  null;
		try {
			clazz = loader.loadClass(servletName);
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
		
		Servlet servlet = null;
		
		try {
			servlet = (Servlet)clazz.newInstance();
			servlet.service((ServletRequest)request, (ServletResponse)response);
		} catch (InstantiationException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (ServletException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}


  • 大小: 8.9 KB
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics