瀏覽代碼

11-17 完善手写tomcat

Demi 6 月之前
父節點
當前提交
43218ce4f3

+ 1 - 0
xml-demo/pom.xml

@@ -21,6 +21,7 @@
       <version>2.11.0</version>
     </dependency>
 
+    <!--  这里主要使用dom4j来解析web.xml  -->
     <dependency>
       <groupId>org.dom4j</groupId>
       <artifactId>dom4j</artifactId>

+ 1 - 1
xml-demo/src/main/java/com/sf/properties/Test.java

@@ -36,7 +36,7 @@ public class Test {
     public static void read1() throws Exception{
         // ClassLoader是类加载器
         // getSystemResourceAsStream 获取系统资源 可以直接找到resources目录下 参数是文件名称
-        InputStream inputStream = ClassLoader.getSystemResourceAsStream("jdbc.properties");
+        InputStream inputStream = ClassLoader.getSystemResourceAsStream("xml/jdbc.properties");
         // 另一种加载输入流的数据
         ResourceBundle resourceBundle = new PropertyResourceBundle(inputStream);
         // 快捷方式 .var 接收方法的返回结果

+ 69 - 0
xml-demo/src/main/java/com/sf/tomcat/MyRequestHandler.java

@@ -0,0 +1,69 @@
+package com.sf.tomcat;
+
+import com.sf.tomcat.my.MyHttpServlet;
+import com.sf.tomcat.my.MyServlet;
+import com.sf.tomcat.servlet.HelloServlet;
+import com.sf.tomcat.servlet.LoginServlet;
+
+import java.net.Socket;
+
+public class MyRequestHandler implements Runnable {
+
+    private Socket socket;
+    public MyRequestHandler(Socket socket) {
+        this.socket = socket;
+    }
+
+    // 先让 /hello请求对应的处理逻辑 就是HelloServlet
+    // 以后是通过配置来找到的
+//    Map<String,String> map = new HashMap<String, String>();
+//    {
+//        map.put("/hello","HelloServlet");
+//    }
+
+    @Override
+    public void run() {
+        try {
+            // 封装请求与响应
+            Request request = new Request(socket.getInputStream());
+            Response response = new Response(socket.getOutputStream());
+            // 先让 /hello请求对应的处理逻辑 就是HelloServlet
+            String uri = request.getUri();
+            String serlvetName = MyTomcat.urlMapping.get(uri);
+            MyHttpServlet myHttpServlet = MyTomcat.servletMapping.get(serlvetName);
+//            System.out.println(uri);
+//            System.out.println(serlvetName);
+//            System.out.println(myHttpServlet);
+            if(myHttpServlet != null) {
+                myHttpServlet.service(request, response);
+            }else{
+                String resp = Response.body + "can not find servlet";
+                response.getOutputStream().write(resp.getBytes());
+                response.getOutputStream().flush();
+            }
+
+//            MyServlet servlet = null;
+//            // 确定使用的是哪个Servlet逻辑
+//            if("/hello".equals(request.getUri())){
+//                servlet = new HelloServlet();
+//                // 确定使用哪个Servlet时 给它调用整个生命周期
+////                servlet.init();
+////                servlet.service(request, response);
+////                servlet.destroy();
+//            }else if("/login".equals(request.getUri())){
+//                servlet = new LoginServlet();
+////                servlet.service(request, response);
+//            }
+//            if(servlet == null){
+//                System.out.println("没有找到合适的Servlet");
+//                return;
+//            }
+//            servlet.init();
+//            servlet.service(request, response);
+//            servlet.destroy();
+
+        }catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+}

+ 63 - 0
xml-demo/src/main/java/com/sf/tomcat/MyTomcat.java

@@ -0,0 +1,63 @@
+package com.sf.tomcat;
+
+import com.sf.tomcat.my.MyHttpServlet;
+import org.dom4j.Document;
+import org.dom4j.Element;
+import org.dom4j.io.SAXReader;
+
+import java.io.File;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.util.HashMap;
+import java.util.List;
+
+public class MyTomcat {
+
+    public static void main(String[] args) throws Exception {
+        // 数据初始化
+        init();
+
+        ServerSocket serverSocket = new ServerSocket(8080);
+        // 检测服务是否关闭
+        while (!serverSocket.isClosed()) {
+            Socket socket = serverSocket.accept();
+            MyRequestHandler handler = new MyRequestHandler(socket);
+            new Thread(handler).start();
+        }
+    }
+
+    // 记录servlet名字和servlet具体对象的映射关系
+    public static HashMap<String, MyHttpServlet> servletMapping = new HashMap<>();
+    // 记录servlet名字和路径的映射关系
+    public static HashMap<String,String> urlMapping = new HashMap<>();
+
+    private static void init() throws Exception {
+        // 先获取类路径
+        String path = MyTomcat.class.getResource("/").getPath();
+        SAXReader reader = new SAXReader();
+        Document document = reader.read(new File(path + "web.xml"));
+        // 获取根标签
+        Element root = document.getRootElement();
+        // 获取servlet配置
+        List<Element> elements = root.elements();
+        // 所有元素 要么是servlet 要么是servlet-mapping
+        for (Element element : elements) {
+            if("servlet".equalsIgnoreCase(element.getName())) {
+                // 获取指定名字的元素
+                Element servletName = element.element("servlet-name");
+                Element servletCls = element.element("servlet-class");
+                String clsName = servletCls.getText();
+                MyHttpServlet myHttpServlet = (MyHttpServlet)Class.forName(clsName).newInstance();
+                servletMapping.put(servletName.getText(),myHttpServlet);
+            }else if("servlet-mapping".equalsIgnoreCase(element.getName())) {
+                Element servletName = element.element("servlet-name");
+                Element urlPattern = element.element("url-pattern");
+                urlMapping.put(urlPattern.getText(),servletName.getText());
+            }
+        }
+
+        // 打印一下初始化的结果
+        System.out.println(servletMapping);
+        System.out.println(urlMapping);
+    }
+}

+ 35 - 0
xml-demo/src/main/java/com/sf/tomcat/Request.java

@@ -0,0 +1,35 @@
+package com.sf.tomcat;
+
+import java.io.BufferedReader;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+
+// 请求实体类
+public class Request {
+
+    // 请求方式 get post
+    private String method;
+    // 资源路径 /hello /login
+    private String uri;
+
+    public Request(InputStream inputStream){
+        // 从请求流中解析出想要的部分
+        try {
+            BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
+            // GET /hello HTTP/1.1
+            String[] split = reader.readLine().split(" ");
+            method = split[0];
+            uri = split[1];
+        }catch (Exception e){
+            e.printStackTrace();
+        }
+    }
+
+    public String getMethod() {
+        return method;
+    }
+
+    public String getUri() {
+        return uri;
+    }
+}

+ 21 - 0
xml-demo/src/main/java/com/sf/tomcat/Response.java

@@ -0,0 +1,21 @@
+package com.sf.tomcat;
+
+import java.io.OutputStream;
+
+// 响应实体类
+public class Response {
+
+    private OutputStream outputStream;
+
+    public Response(OutputStream outputStream) {
+        this.outputStream = outputStream;
+    }
+
+    public static final String body = "HTTP/1.1 200 OK\r\n"
+            + "Content-Type: text/html; charset=utf-8\r\n"
+            + "\r\n";
+
+    public OutputStream getOutputStream() {
+        return outputStream;
+    }
+}

+ 29 - 0
xml-demo/src/main/java/com/sf/tomcat/my/MyHttpServlet.java

@@ -0,0 +1,29 @@
+package com.sf.tomcat.my;
+
+import com.sf.tomcat.Request;
+import com.sf.tomcat.Response;
+
+// 接口是规范
+// 抽象类 来实现接口的一部分
+// 所有Http请求用MyHttpServlet处理
+public abstract class MyHttpServlet implements MyServlet {
+
+    // 因为当前的核心处理是 get 和 post
+    //  针对get做get处理 针对post做post处理
+    @Override
+    public void service(Request request, Response response) {
+        // 如果在比较变量和字面量是否相等时  往往把字面量放前 避免空指针问题
+        if("get".equalsIgnoreCase(request.getMethod())){
+            // 可以用GET  也可以用不区分大小写的比较 equalsIgnoreCase
+            doGet(request, response);
+        }else{
+            doPost(request, response);
+        }
+    }
+
+    // 拆成不同的方法 处理不同的请求方式
+    // 用浏览器能发送的只有get请求
+    public abstract void doGet(Request request, Response response);
+    public abstract void doPost(Request request, Response response);
+
+}

+ 15 - 0
xml-demo/src/main/java/com/sf/tomcat/my/MyServlet.java

@@ -0,0 +1,15 @@
+package com.sf.tomcat.my;
+
+import com.sf.tomcat.Request;
+import com.sf.tomcat.Response;
+
+// 所有请求都用MyServlet处理
+public interface MyServlet {
+    // 一个处理逻辑的 生命周期
+    // 计算机中生命周期的概念: 指的是事物从出生到死亡的过程
+    void init();
+    // 接收请求 和 返回响应
+    void service(Request request, Response response);
+    // 销毁
+    void destroy();
+}

+ 41 - 0
xml-demo/src/main/java/com/sf/tomcat/servlet/HelloServlet.java

@@ -0,0 +1,41 @@
+package com.sf.tomcat.servlet;
+
+import com.sf.tomcat.my.MyHttpServlet;
+import com.sf.tomcat.Request;
+import com.sf.tomcat.Response;
+
+import java.io.OutputStream;
+
+// 将所有为实现的方法实现
+// http://localhost:8080/hello
+public class HelloServlet extends MyHttpServlet {
+
+    @Override
+    public void doGet(Request request, Response response) {
+        doPost(request, response);
+    }
+
+    @Override
+    public void doPost(Request request, Response response) {
+        try {
+            String resp = Response.body + "Hello Servlet";
+            OutputStream outputStream = response.getOutputStream();
+            outputStream.write(resp.getBytes());
+            outputStream.flush();
+            outputStream.close();
+
+        }catch(Exception e){
+            e.printStackTrace();
+        }
+    }
+
+    @Override
+    public void init() {
+        System.out.println("HelloServlet init");
+    }
+
+    @Override
+    public void destroy() {
+        System.out.println("HelloServlet destroy");
+    }
+}

+ 39 - 0
xml-demo/src/main/java/com/sf/tomcat/servlet/LoginServlet.java

@@ -0,0 +1,39 @@
+package com.sf.tomcat.servlet;
+
+import com.sf.tomcat.my.MyHttpServlet;
+import com.sf.tomcat.Request;
+import com.sf.tomcat.Response;
+
+import java.io.OutputStream;
+
+public class LoginServlet extends MyHttpServlet {
+
+    @Override
+    public void doGet(Request request, Response response) {
+        doPost(request, response);
+    }
+
+    @Override
+    public void doPost(Request request, Response response) {
+        try {
+            String resp = Response.body + "Login Servlet";
+            OutputStream outputStream = response.getOutputStream();
+            outputStream.write(resp.getBytes());
+            outputStream.flush();
+            outputStream.close();
+
+        }catch(Exception e){
+            e.printStackTrace();
+        }
+    }
+
+    @Override
+    public void init() {
+
+    }
+
+    @Override
+    public void destroy() {
+
+    }
+}

+ 2 - 2
xml-demo/src/main/java/com/sf/xml/TestDom4j.java

@@ -16,7 +16,7 @@ public class TestDom4j {
 //        read();
 
         SAXReader reader = new SAXReader();
-        InputStream inputStream = ClassLoader.getSystemResourceAsStream("test.xml");
+        InputStream inputStream = ClassLoader.getSystemResourceAsStream("xml/test.xml");
         Document document = reader.read(inputStream);
         Element rootElement = document.getRootElement();
         traverse(rootElement, 0);
@@ -26,7 +26,7 @@ public class TestDom4j {
         // 提供了一个阅读器
         SAXReader reader = new SAXReader();
         // 找到xml文件 读取出输入流
-        InputStream inputStream = ClassLoader.getSystemResourceAsStream("test.xml");
+        InputStream inputStream = ClassLoader.getSystemResourceAsStream("xml/test.xml");
         // 将输入流 加载成 文档对象
         Document document = reader.read(inputStream);
         // 获取文档中的根标签

+ 2 - 2
xml-demo/src/main/java/com/sf/xml/TestJsoup.java

@@ -33,7 +33,7 @@ public class TestJsoup {
 
     public static Document getDocument() throws Exception {
         // 获取文件路径
-        String path = TestJsoup.class.getClassLoader().getResource("user.xml").getPath();
+        String path = TestJsoup.class.getClassLoader().getResource("xml/user.xml").getPath();
         // String path = "src/main/resources/user.xml";
         // 将xml文件 转为Document对象
         Document document = Jsoup.parse(new File(path), "UTF-8");
@@ -42,7 +42,7 @@ public class TestJsoup {
 
     public static void read() throws Exception {
         // 获取文件路径
-        String path = TestJsoup.class.getClassLoader().getResource("user.xml").getPath();
+        String path = TestJsoup.class.getClassLoader().getResource("xml/user.xml").getPath();
         // String path = "src/main/resources/user.xml";
         // 将xml文件 转为Document对象
         Document document = Jsoup.parse(new File(path), "UTF-8");

+ 1 - 1
xml-demo/src/main/java/com/sf/xml/sax/TestSax.java

@@ -22,7 +22,7 @@ public class TestSax {
         MyHandler handler = new MyHandler();
         xmlReader.setContentHandler(handler);
         // 解析xml  通过当前类获取类加载器  然后获取资源 传入文件本身
-        xmlReader.parse(TestSax.class.getClassLoader().getResource("book.xml").getFile());
+        xmlReader.parse(TestSax.class.getClassLoader().getResource("xml/book.xml").getFile());
         System.out.println(handler.getBookList());
     }
 }

+ 11 - 0
xml-demo/src/main/resources/web.xml

@@ -0,0 +1,11 @@
+<!-- 自己写一个web.xml -->
+<web-app>
+    <servlet>
+        <servlet-name>helloServlet</servlet-name>
+        <servlet-class>com.sf.tomcat.servlet.HelloServlet</servlet-class>
+    </servlet>
+    <servlet-mapping>
+        <servlet-name>helloServlet</servlet-name>
+        <url-pattern>/hello</url-pattern>
+    </servlet-mapping>
+</web-app>

+ 0 - 0
xml-demo/src/main/resources/book.xml → xml-demo/src/main/resources/xml/book.xml


+ 0 - 0
xml-demo/src/main/resources/jdbc.properties → xml-demo/src/main/resources/xml/jdbc.properties


+ 0 - 0
xml-demo/src/main/resources/sth.properties → xml-demo/src/main/resources/xml/sth.properties


+ 0 - 0
xml-demo/src/main/resources/student.dtd → xml-demo/src/main/resources/xml/student.dtd


+ 1 - 1
xml-demo/src/main/resources/student.xml → xml-demo/src/main/resources/xml/student.xml

@@ -2,7 +2,7 @@
 <!-- 声明这是一个xml文件 声明版本号和编码格式 -->
 <!-- XML语法 + HTML约束 = HTML语法 -->
 <!-- 使用dtd文件来约束 xml -->
-<!DOCTYPE students SYSTEM "student.dtd">
+<!DOCTYPE students SYSTEM "D:\Projects\IdeaProjects\Java0715\xml-demo\src\main\resources\xml\student.dtd">
 
 <!-- 还有一种约束 Schema  比dtd更加详细-->
 <students>

+ 0 - 0
xml-demo/src/main/resources/test.xml → xml-demo/src/main/resources/xml/test.xml


+ 0 - 0
xml-demo/src/main/resources/testA.html → xml-demo/src/main/resources/xml/testA.html


+ 0 - 0
xml-demo/src/main/resources/user.xml → xml-demo/src/main/resources/xml/user.xml