理解与模拟一个简单servlet容器

servlet接口

  使用servlet编程需要实现或者继承实现了javax.servlet.Servlet接口的类,其中定义了5个签名方法:

1 public void init(ServletConfig config) throws ServletException
2 public void service(ServletRequest req,ServletResponse res) throws ServletException,java.io.IOException
3 public void destroy()
4 public ServletConfig getServletConfig()
5 public java.lang.String getServletInfo()

init(),service(),destroy对应着servlet的生命周期,init只在加载该servlet时执行且只此一次,容器根据用户请求调用对应servlet的service执行方法,当实例销毁移除前容器调用destroy处理后续操作。

模拟容器主要工作流程:

  • 等待http请求
  • 根据请求创建对应Request与Response对象
  • 如果请求的是静态资源,则调用StaticResourceProcessor发送对应资源
  • 如果请求是servlet,则加载该类并执行其service方法
简单servlet容器

 主要类信息如下:

  1. HttpServer  与web服务器类似,不同的是加入了servlet请求判断,并调用ServletProcessor处理对应servlet
  2. Request   与上一篇web服务器类似,但是实现了ServletRequest接口
  3. Response   与上一篇web服务器类似,但是实现了ServletResponse接口
  4. StaticResourceProcessor  用于处理请求静态资源时调用
  5. ServletProcessor 用于当请求是servlet时调用
  6. Constant 定义一些常量
  7. MyLogger 自己定义在控制台打印日志信息,可以忽略
  8. PrimitiveServlet 实现servlet接口,自定义servlet程序用于请求调用

说明:部分接口只是实现了需要用到的方法,并没有完全实现所有方法,使用默认即可,代码里面没有贴出来

(一)HttpServer 

 

 1 public class HttpServer {
 2     MyLogger logger = new MyLogger<>(HttpServer.class);
 3     private static final String SHUTDOWN_COMMAND = "/SHUTDOWN";
 4     private boolean  shutdown = false;
 5     
 6     public void await() {
 7         ServerSocket serverSocket = null;
 8         int port = 8080;
 9         try {
10             serverSocket = new ServerSocket(port, 1, InetAddress.getByName("127.0.0.1"));
11             logger.log("server started......." + "at " + serverSocket.toString());
12         } catch (IOException e) {
13             // TODO Auto-generated catch block
14             e.printStackTrace();
15             System.exit(1);
16         }
17         while (!shutdown){
18             Socket socket = null;
19             InputStream inputStream = null;
20             OutputStream outputStream = null;
21             try {
22                 socket = serverSocket.accept();
23                 logger.log("accepted new request...");
24                 inputStream = socket.getInputStream();
25                 outputStream = socket.getOutputStream();
26                 Request request = new Request(inputStream);
27                 request.Parse();
28                 Response response = new Response(outputStream);
29                 response.setRequest(request);
30                 logger.log("inition done,begin process.......");
31                 if(request.getUri() == null){
32                     logger.log("request uri is null...close socket");
33                     socket.close();
34                     continue;
35                 }
36                 else if(request.getUri().startsWith("/servlet/")){
37                     logger.log("execute servlet...");
38                     ServletProcessor servletProcessor = new ServletProcessor();
39                     servletProcessor.process(request, response);
40                 }
41                 else {
42                     logger.log("send staticResource...");
43                     StaticResourceProcessor staticResourceProcessor = new StaticResourceProcessor();
44                     staticResourceProcessor.process(request, response);
45                 }
46                 socket.close();
47                 shutdown = request.getUri().equals(SHUTDOWN_COMMAND);
48             } catch (IOException e) {
49                 // TODO Auto-generated catch block
50                 e.printStackTrace();
51             }
52         }
53     }
54 }
(二)Request 

 

 1 public class Request implements ServletRequest{
 2     
 3     MyLogger logger = new MyLogger(ServletRequest.class);
 4     private String uri;
 5     private InputStream in;
 6     
 7     public Request(InputStream in){
 8         this.in = in;
 9     }
10     
11     public String parseUri(String request){
12         int index1,index2;
13         index1 = request.indexOf(" ");
14         if (index1 != -1){
15             index2 = request.indexOf(" ", index1+ 1);
16             if (index1 < index2)
17                 return request.substring(index1 + 1, index2);
18         }
19         return null;
20     }
21     
22     public void Parse(){
23         StringBuffer request = new StringBuffer(2048);
24         byte[] bs = new byte[2048];
25         int i;
26         try {
27             i = in.read(bs);
28         } catch (IOException e) {
29             e.printStackTrace();
30             i = -1;
31         }
32         
33         for(int j=0; j<i; j++){
34             request.append((char)bs[j]);
35         }
36         
37         logger.log(request.toString());
38         uri = parseUri(request.toString());
39         if(uri != null)
40         logger.log("uri is " + uri);
41     }
42     
43     public String getUri() {
44         return uri;
45     }
46 }

 

(三)Response 

 

 1 public class Response implements ServletResponse{
 2     
 3     MyLogger logger = new MyLogger(Response.class);
 4     private static final int BUFFER_SIZE = 1024;
 5     private Request request;
 6     private OutputStream out;
 7     private PrintWriter writer;
 8     
 9     public  Response(OutputStream out) {
10         this.out = out;
11     }
12     
13     public  void setRequest(Request request) {
14         this.request = request;
15     }
16     //假设请求的是图片资源
17     public void sendStaticResource() throws IOException{
18         byte[] buffer = new byte[BUFFER_SIZE];
19         FileInputStream fis = null;
20         File file = new File(Constant.WEB_ROOT, request.getUri());
21         try {
22             logger.log("Begin read file + " + file.toString());
23             fis = new FileInputStream(file);
24             String headerMsg = "HTTP/1.1 200 OK\r\n" + 
25                     "Content-Type: image/jpg\r\n" + 
26                     "Content-Length: " + file.length() + "\r\n" +
27                     "\r\n" ;
28             logger.log("headerMsg->\r\n" + headerMsg);
29             out.write(headerMsg.getBytes());
30             int ch = fis.read(buffer, 0, BUFFER_SIZE);
31             while (ch != -1){
32                 out.write(buffer, 0, BUFFER_SIZE);
33                 ch = fis.read(buffer, 0, BUFFER_SIZE);
34             }
35         } catch (FileNotFoundException e) {
36             String html = "<h1>file not found</h1>";
37             logger.log("FileNotFoundException");
38             String errorMsg = "HTTP/1.1 404 file not found\r\n" + 
39                     "Content-Type: text/html\r\n" + 
40                     "Content-Length: " + html.getBytes().length + "\r\n" +
41                     "\r\n" +
42                     html;
43             out.write(errorMsg.getBytes());
44             logger.log("errorMsg->" + errorMsg);
45         }
46         finally {
47             if(fis != null){
48                 fis.close();
49             }
50         }
51     }
52 }

 

(四)StaticResourceProcessor 

 

1 public class StaticResourceProcessor {
2     public void process(Request request,Response response) {
3         try {
4             response.sendStaticResource();
5         } catch (IOException e) {
6             e.printStackTrace();
7         }
8     }
9 }

 

(五)ServletProcessor 

 

 1 public class ServletProcessor {
 2     public void process(Request request,Response response){
 3         String uri = request.getUri();
 4         String servletName = uri.substring(uri.lastIndexOf("/") + 1);
 5         URLClassLoader loader = null;
 6         
 7         URL[] urls = new URL[1];
 8         URLStreamHandler urlStreamHandler = null;
 9         File classPath = new File(Constant.WEB_ROOT);
10         try {
11             String repository = (new URL("file",null,classPath.getCanonicalPath() + 
12                     File.separator)).toString();
13             urls[0] = new URL(null,repository,urlStreamHandler);
14             loader = new URLClassLoader(urls);
15         } catch (IOException e) {
16             // TODO Auto-generated catch block
17             e.printStackTrace();
18         }
19         Class myClass = null;
20         try {
21             myClass = loader.loadClass(servletName);
22         } catch (ClassNotFoundException e) {
23             e.printStackTrace();
24         }
25         
26         Servlet servlet = null;
27         try {
28             servlet = (Servlet) myClass.newInstance();
29             servlet.service((ServletRequest)request, (ServletResponse) response);
30         
31         } catch (InstantiationException | IllegalAccessException e) {
32             // TODO Auto-generated catch block
33             e.printStackTrace();
34         } catch (ServletException e) {
35             // TODO Auto-generated catch block
36             e.printStackTrace();
37         } catch (IOException e) {
38             // TODO Auto-generated catch block
39             e.printStackTrace();
40         }
41         
42     }
43 }

 

(六)MyLogger 

 

 1 public  class MyLogger<T> {
 2     private String classStr = "";
 3     
 4     public  void log(T msg){
 5         System.out.println(classStr + "(" + 
 6                 (new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")).format(new Date()) + ")" + ": " + msg);
 7     }
 8     public MyLogger(Class classz){
 9         classStr = classz.getName();
10     }
11 }

 

(七)PrimitiveServlet 

 

 1 public class PrimitiveServlet implements Servlet{
 2     MyLogger Logger = new MyLogger<>(PrimitiveServlet.class);
 3     @Override
 4     public void destroy() {
 5         // TODO Auto-generated method stub
 6         
 7     }
 8 
 9     @Override
10     public ServletConfig getServletConfig() {
11         // TODO Auto-generated method stub
12         return null;
13     }
14 
15     @Override
16     public String getServletInfo() {
17         // TODO Auto-generated method stub
18         return null;
19     }
20 
21     @Override
22     public void init(ServletConfig arg0) throws ServletException {
23         // TODO Auto-generated method stub
24         
25     }
26 
27     @Override
28     public void service(ServletRequest request, ServletResponse response) throws ServletException, IOException {
29         Logger.log("service execute.....");
30         PrintWriter writer = response.getWriter();
31         writer.println("Hey,welcome on board!");
32         writer.println("lets rock!");
33     }
34 
35 }
(八)Constant 

 

public class Constant {
    public static final String WEB_ROOT = 
            System.getProperty("user.dir") + File.separator + "bin";
}
View Code

 

posted @ 2016-11-22 14:00  music180  阅读(255)  评论(0编辑  收藏  举报