博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
深入剖析tomcat之一个简单的servlet容器
阅读量:6838 次
发布时间:2019-06-26

本文共 6846 字,大约阅读时间需要 22 分钟。

上一篇,我们讲解了如果开发一个简单的Http服务器,这一篇,我们扩展一下,让我们的服务器具备servlet的解析功能。

简单介绍下Servlet接口

如果我们想要自定义一个Servlet,那么我们必须继承Servlet,并且实现下面几个重要的方法

public void init(ServletConfig config) throws ServletExceptionpublic void service(ServletRequest request,ServletResponse response) throws ServletException,java.io.IOExceptionpublic void destroy()public ServletConfig getServletConfig()public String getServletInfo()

五个方法中,init,destroy,service都是和servlet的生命周期相关的方法。当实例化某个servlet类之后,servlet会调用init进行初始化,当servlet的请求到达之后,就会调用service方法,并将servletRequest和servletResponse对象作为参数传入,前者包含客户端的Http请求的信息,后者包含服务器的响应信息。

这个简单的Servlet容器的流程如下

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

涉及到的主要的类

  • SimpleServletContainerServer
  • Request
  • Response
  • Servlet
  • PrimitiveServlet
  • StaticProcessor
  • ServletProcessor

关于Request和Response的定义在上一篇幅有定义,这里我们稍微扩展了一下,碍于篇幅,不在这里展示。

PrimitiveServlet类,继承自Servlet,Servlet请求的处理类

类定义:

package servletContainer;import java.io.IOException;import base.Request;import base.Response;import base.ServletConfig;import interf.Servlet;public class PrimitiveServlet implements Servlet {    @Override    public void init(ServletConfig config) {        System.out.println("PrimitiveServlet init");    }    @Override    public void service(Request request, Response response) throws IOException {        response.getOutput().write("Primitive Servlet".getBytes());    }    @Override    public void destroy() {            }    @Override    public ServletConfig getServletConfig() {        return null;    }    @Override    public String getServletInfo() {        return null;    }}

SimpleServletContainerServer 类

功能:程序入口,监听Http请求,并且负责创建Request和Response
类定义

package servletContainer;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 base.Request;import base.Response;import servletContainer.processor.ServletProcessor;import servletContainer.processor.StaticProcessor;public class SimpleServletContainerServer {    private static final String SHUT_DOWN = "/SHUTDOWN";        private boolean shutdown = false;        private ServletProcessor servletProcessor = new ServletProcessor();        private StaticProcessor staticProcessor = new StaticProcessor();        public static void main(String args[]){        SimpleServletContainerServer server = new SimpleServletContainerServer();        server.init();        server.await();    }        public void init(){        servletProcessor.init();        staticProcessor.init();    }        public void await(){                ServerSocket serverSocket = null;        int port = 8080;                try{            serverSocket = new ServerSocket(port, 1, InetAddress.getByName("127.0.0.1"));        }        catch (IOException e){            e.printStackTrace();            System.exit(-1);        }                while(!shutdown){            Socket socket = null;            InputStream input = null;            OutputStream output = null;                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            try{                                socket = serverSocket.accept();                input = socket.getInputStream();                output = socket.getOutputStream();                                Request request = new Request(input);                request.parse();                                Response response = new Response(output);                response.setRequest(request);                                if(request.getUri().startsWith("/servlet/")){                    servletProcessor.process(request, response);                }                else{                    staticProcessor.process(request, response);                }                                socket.close();                shutdown = request.getUri().equals(SHUT_DOWN);                            }            catch (Exception e){                e.printStackTrace();                System.exit(1);            }        }            }    }

我们引入了StaticProcessor和ServletProcessor进行逻辑的处理,我们看下这两个类的定义

首先这两个类都继承自IProcessor接口

package servletContainer.processor;import base.Request;import base.Response;public interface IProcessor {        public void init();        public void process(Request request,            Response response);}

StaticProcessor类主要是处理静态资源请求

类定义

package servletContainer.processor;import base.Request;import base.Response;public class StaticProcessor implements IProcessor {    @Override    public void process(Request request, Response response) {        try{            response.sendStaticResource();        }        catch (Exception e){            e.printStackTrace();        }    }    @Override    public void init() {            }    }

ServeletProcessor主要负责处理Servlet请求,初始化的时候,初始化所有的Servlet子类,接收到servlet的http请求之后,根据请求名称,调用对应的service函数。

类定义

package servletContainer.processor;import java.util.HashMap;import java.util.Map;import base.Request;import base.Response;import interf.Servlet;import servletContainer.PrimitiveServlet;public class ServletProcessor implements IProcessor {        private Map
map = new HashMap
(); public ServletProcessor() { } public void init(){ PrimitiveServlet servlet = new PrimitiveServlet(); servlet.init(null); map.put("PrimitiveServlet", servlet); } @Override public void process(Request request, Response response) { String uri = request.getUri(); String servletName = uri.substring(uri.lastIndexOf("/") + 1); Servlet servlet = map.get(servletName); try{ if(servlet != null){ servlet.service(request, response); } else{ String errorMessage = "HTTP/1.1 404 File Not Found\r\n" + "Content-Type: text/html\r\n" + "Content-Length:23\r\n" + "\r\n" + "

File Not Found

"; response.getWriter().print(errorMessage.getBytes()); } } catch (Exception e){ e.printStackTrace(); } catch (Throwable e){ e.printStackTrace(); } } }

结果

我们在eclipse里运行结果

运行结果1

运行结果2

转载于:https://www.cnblogs.com/archy_yu/p/5380592.html

你可能感兴趣的文章
java实现遍历树形菜单方法——service层
查看>>
ios appIcon配置
查看>>
首款移动社交购物平台“商宝”上线发布
查看>>
Solr配置与简单Demo[转]
查看>>
Go语言转义字符
查看>>
spring boot的热加载(hotswap)
查看>>
iis重启的几种方法
查看>>
HDU 2196 Computer 树形DP经典题
查看>>
HDU 3466 01背包变形
查看>>
用鼠标滚轮做事件
查看>>
python - paramiko模块 修改logging提示为静默
查看>>
浅谈Linux的内存管理机制
查看>>
Linux中断概述
查看>>
ubuntu 安装RPM软件包
查看>>
controller的frame
查看>>
c++实现队列
查看>>
Linux系统介绍(二)文件系统结构
查看>>
面试题目(1)
查看>>
描述一下Spring框架的作用和优点?
查看>>
二十五:设计模式的总结
查看>>