博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
一个简单的Web服务器-支持Servlet请求
阅读量:4979 次
发布时间:2019-06-12

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

上接 ,这个服务器可以处理静态资源的请求,那么如何处理Servlet请求的呢?

 

判断是否是Servlet请求

首先Web服务器需要判断当前请求是否是Servlet请求。

像Tomcat,通过解析HTTP报文拿到请求url后,就可以根据web.xml来查找是否有匹配的Servlet,如果有匹配则认定为是一个有效的Servlet请求,然后将request,response传给对应的servlet的service()方法。

这里既然要实现一个简单的Web服务器,就怎么简单怎么来。认定以“/servlet”为前缀的url为Servlet请求,比如http://localhost:8080/servlet/cn.edu.jxau.tomcat.PrimitiveServlet,则是一个请求cn.edu.jxau.tomcat.PrimitiveServlet的Servlet请求。判定逻辑如下

// HttpServer 类的service()方法,是整个服务器的入口        while (true) {            try (Socket socket = serverSocket.accept()) {                System.out.println("客户端建立连接:" + socket);                Request request = new Request(socket.getInputStream());                if (Objects.isNull(request.getUri())) {                    continue;                }                if (isShutdownComment(request)) { //如果是shutdown命令,则关闭服务器                    break;                }                Response response = new Response(request, socket.getOutputStream()); if (request.getUri().startsWith("/servlet/")) { // 请求Servlet资源                    new ServletProcessor().process(request, response);                } else { // 请求静态资源                    response.sendStaticResource();                    // 书上使用了StaticResourceProcessor new StaticResourceProcessor().process(request,response);                }            } catch (Exception e) {                e.printStackTrace();            }        }

 

加载Servlet

如果确实是Servlet请求,下一步就是实例化Servlet并调用service()方法。

首先需要知道请求是哪个Servlet:根据url拿到Servlet的名称

然后需要调用Servlet的service()方法:使用ClassLoader加载对应的Servlet字节码,然后实例化Servlet,调用service()方法,传入request,response。

// ServletProcessor 类的process()方法,用于处理Servlet请求public void process(Request request, Response response) throws IOException, ClassNotFoundException, IllegalAccessException, InstantiationException, ServletException {        String uri = request.getUri();        String servletName = uri.substring(uri.lastIndexOf("/") + 1);        File file = new File(Constants.WEB_ROOT);        String urlStr = new URL("file", null, file.getCanonicalPath() + File.separator).toString(); //使用File协议        URL[] urlArr = new URL[1];        urlArr[0] = new URL(urlStr);        System.out.println(Arrays.toString(urlArr));        URLClassLoader loader = new URLClassLoader(urlArr);        Class clazz = loader.loadClass(servletName); // 根据Servlet的全路径名加载Servlet字节码        Servlet servlet = (Servlet) clazz.newInstance(); // 实例化Servlet        servlet.service(request, response); //调用Servlet.service()    }

 

PrimitiveServlet的实现如下,实现了Servlet接口,service()方法的实现是重点。

public class PrimitiveServlet implements Servlet {    public void init(ServletConfig config) throws ServletException {        System.out.println("-----init");    }    public void service(ServletRequest request, ServletResponse response)            throws ServletException, IOException {        PrintWriter out = response.getWriter();        out.println("HTTP/1.1 200 Status OK\r\n");        out.println("Content-Type: text/html\r\n");        out.println("Content-Length: 36\r\n");        out.println("\r\n");        out.println("

Status OK

"); out.print("

Status OK

"); } public void destroy() { System.out.println("-------destroy"); } public String getServletInfo() { return null; } public ServletConfig getServletConfig() { return null; }}

 

参考

1.《How Tomcat Works》 - Budi Kurniawan

转载于:https://www.cnblogs.com/fudashi233/p/10995402.html

你可能感兴趣的文章
处理器管理与进程调度
查看>>
向量非零元素个数_向量范数详解+代码实现
查看>>
java if 用法详解_Java编程中的条件判断之if语句的用法详解
查看>>
matlab sin函数 fft,matlab的fft函数的使用教程
查看>>
mysql adddate()函数
查看>>
mysql sin() 函数
查看>>
单片机复位电路
查看>>
php json_decode失败,返回null
查看>>
3-day3-list-truple-map.py
查看>>
Edit控件显示多行文字
查看>>
JS第二周
查看>>
dataTable.NET的search box每輸入一個字母進行一次檢索的問題
查看>>
Python 文件处理
查看>>
邻接表详解
查看>>
迭代dict的value
查看>>
eclipse package,source folder,folder区别及相互转换
查看>>
Py 可能是最全面的 python 字符串拼接总结(带注释版)
查看>>
《Java程序设计实验》 软件工程18-1,3 OO实验2
查看>>
【Herding HDU - 4709 】【数学(利用叉乘计算三角形面积)】
查看>>
OPENSSL使用方法
查看>>