tomcat-模仿-手写实现

模仿tomcat,简单实现一个类似的servlet容器

配置文件(类似web.xml)

web.properties

serlvet.one.url=/firstServlet.do
serlvet.one.className=com.aiso.design.demo.tomcat.servlet.FirstServlet

#serlvet.two.url=/firstServlet.do
#servlet.two.className=com.aiso.design.demo.tomcat.servlet.SecServlet

核心服务类

package com.aiso.design.demo.tomcat.catalina;

import com.aiso.design.demo.tomcat.http.MyRequest;
import com.aiso.design.demo.tomcat.http.MyResponse;
import com.aiso.design.demo.tomcat.http.MyServlet;
import com.aiso.design.demo.tomcat.servlet.FirstServlet;
import org.apache.catalina.servlet4preview.http.ServletMapping;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import java.util.regex.Pattern;

public class MyTomcat {

    private int port = 8080;

    ServerSocket serverSocket;

    private Map<Pattern, Class<?>> servletMapping = new HashMap<Pattern, Class<?>>();

    private Properties webxml = new Properties();

    private String WEB_INF = this.getClass().getResource("/").getPath();


    public MyTomcat() {

        start();

    }

    public MyTomcat(int port) {
        this.port = port;
    }

    //容器启动之前 加载所有的 配置文件
    private void init() {

        FileInputStream fis = null;

        try {

            fis = new FileInputStream(WEB_INF + "web.properties");

            webxml.load(fis);

            for (Object k :
                    webxml.keySet()) {
                String key = k.toString();
                if (key.endsWith(".url")) {
                    String servletName = key.replaceAll("\\.url$", "");
                    String url = webxml.getProperty(key);

                    Pattern pattern = Pattern.compile(url);

                    String className = webxml.getProperty(servletName + ".className");

                    Class<?> servletClass = Class.forName(className);

                    servletMapping.put(pattern, servletClass);
                }
            }


        } catch (Exception e) {

        }

    }


    //等待用户请求
    private void process(Socket client) throws Exception {

        InputStream is = null;
        OutputStream out = null;

        MyRequest request = new MyRequest(is);

        MyResponse response = new MyResponse(out);

        try {
            is = client.getInputStream();
            out = client.getOutputStream();

            //读取web.xml 获取servlet
            //利用反射new

            String url = request.getUrl();

            boolean isPattern = false;
            for (Map.Entry<Pattern, Class<?>> entry :
                    servletMapping.entrySet()) {

                if (entry.getKey().matcher(url).matches()) {

                    MyServlet servlet = (MyServlet) entry.getValue().newInstance();
                    servlet.serivce(request, response);

                    isPattern = true;
                }
            }

            if (!isPattern) {
                response.write("404 - Not Found ");
            }


            System.out.println("-----------------------");

        } catch (Exception e) {

            response.write("500," + e.getMessage());

        } finally {
            if (null != is) {
                is.close();
            }
            if (null != is) {
                out.close();
            }

            if (null != is) {
                client.close();
            }
        }


    }

    public void start() {
        init();

        try {
            serverSocket = new ServerSocket(this.port);

            System.out.println("mytomcat 已启动,监听端口是" + port);

        } catch (IOException e) {
            e.printStackTrace();
            System.out.println("mytomcat 启动失败," + e.getMessage());
            return;
        }

        while (true) {

            try {
                Socket client = serverSocket.accept();

                process(client);

            } catch (Exception e) {
                e.printStackTrace();
            }

        }

    }

}

http 请求封装

package com.aiso.design.demo.tomcat.http;

import java.io.IOException;
import java.io.InputStream;
import java.util.Map;

public class MyRequest {

    private String method;

    public String url;

    public void setUrl(String url) {
        this.url = url;
    }

    public void setMethod(String method) {
        this.method = method;
    }

    public MyRequest(InputStream inputStream) {

        try {
            //从http协议中解析客户端带过来的信息
            String content = "";
            byte[] buff = new byte[1024];
            int len = 0;

            if ((len = inputStream.read(buff)) > 0) {
                content = new String(buff, 0, len);
            }
            System.out.println(content);

            String line = content.split("\\n")[0];

            String[] arr = line.split("\\s");

            this.method = arr[0];

            this.url = arr[1].split("\\?")[0];


        } catch (IOException e) {
            e.printStackTrace();
        }
    }


    public String getMethod() {

        return null;
    }

    public String getUrl() {

        return null;
    }

    public Map<String, String> getParameter() {

        return null;
    }
}

http 响应封装

package com.aiso.design.demo.tomcat.http;

import java.io.OutputStream;

public class MyResponse {

    private OutputStream os;

    public MyResponse(OutputStream outputStream) {
        this.os = os;
    }

    public void write(String outStr) throws Exception {
        os.write(outStr.getBytes());
        os.flush();
    }

}

servlet

package com.aiso.design.demo.tomcat.http;

public abstract class MyServlet {

    public void serivce(MyRequest request, MyResponse response) throws Exception {

        if ("GET".equalsIgnoreCase(request.getMethod())) {
            doGet(request, response);
        } else {
            doPost(request,response);
        }


    }

    public abstract void doGet(MyRequest request, MyResponse response) throws Exception;

    public abstract void doPost(MyRequest request, MyResponse response) throws Exception;
}

测试servlet

public class FirstServlet extends MyServlet {
    @Override
    public void doGet(MyRequest request, MyResponse response) throws Exception {
        this.doPost(request, response);
        response.write("hello  world " + ", is" + request.getMethod());
    }

    @Override
    public void doPost(MyRequest request, MyResponse response) throws Exception {

        //处理逻辑

        response.write("hello world");
    }
}

猜你喜欢

转载自blog.csdn.net/qq_16038125/article/details/80193484