美文网首页
使用bio手写tomcat

使用bio手写tomcat

作者: 剑道_7ffc | 来源:发表于2020-03-23 18:00 被阅读0次

    业务功能

    浏览器发送请求给服务器,服务器根据请求的分给不同的Servlet的doGet或doPost的方法,并把响应结果返回给页面。

    实体类

    请求类:SelfHttpRequest
    响应类:SelfHttpResponse
    抽象共用的Servlet:SelfHttpServlet
    远程服务器:SelfTomcat

    代码实现

    SelfHttpRequest

    public class SelfHttpRequest {
        private String requestUrl;
        private String requestMethod;
        public SelfHttpRequest(InputStream inputStream) {
            byte[] buffer = new byte[1024];
            try {
                int length = 0;
                String context = null;
                if((length = inputStream.read(buffer)) > 0){
                    context = new String(buffer, 0, length);
                }
    
                String firstRow = context.split("\n")[0];
                String[] firstColumn = firstRow.split(" ");
                requestMethod = firstColumn[0];
                requestUrl = firstColumn[1];
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        public String getRequestUrl() {
            return requestUrl;
        }
        public String getRequestMethod() {
            return requestMethod;
        }
    }
    

    SelfHttpResponse

    public class SelfHttpResponse {
        private OutputStream outputStream;
    
        public SelfHttpResponse(OutputStream outputStream) {
            this.outputStream = outputStream;
        }
    
        /**
         * post方法
         */
        public void write(String content) throws IOException {
            //用的是HTTP协议,输出也要遵循HTTP协议
            StringBuilder sb = new StringBuilder();
            sb.append("HTTP/1.1 200 OK\n")
                    .append("Content-Type: text/html;\n")
                    .append("\r\n")
                    .append(content);
            outputStream.write(sb.toString().getBytes());
        }
    }
    

    SelfHttpServlet

    public abstract class SelfHttpServlet {
        /**
         * doService
         */
        public void doService(SelfHttpRequest request, SelfHttpResponse response) throws IOException {
            if("get".equals(request.getRequestMethod().toLowerCase())){
                doGet(request, response);
            }else{
                doPost(request, response);
            }
        }
        /**
         * get方法
         */
        public abstract void doGet(SelfHttpRequest request, SelfHttpResponse response) throws IOException;
        /**
         * post方法
         */
        public abstract void doPost(SelfHttpRequest request, SelfHttpResponse response) throws IOException;
    }
    

    SelfTomcat

    public class SelfTomcat {
        private Integer port;
        private Map<String, Object> urlInstanceMap = new HashMap<>();
    
        public SelfTomcat(Integer port) {
            this.port = port;
    
            init();
        }
    
        /**
         * 初始化
         */
        private void init(){
            //加载配置文件
            Properties properties = new Properties();
            String configUrl = this.getClass().getClassLoader().getResource("web.properties").getFile();
            try {
                properties.load(new FileInputStream(configUrl));
            } catch (IOException e) {
                e.printStackTrace();
            }
    
            //初始化对象
            try {
                Set<String> requestUrlKeys = properties.stringPropertyNames().stream().filter(item -> item.endsWith(".url"))
                        .collect(Collectors.toSet());
                for (String requestUrlKey : requestUrlKeys) {
                    String requestUrl = properties.getProperty(requestUrlKey);
                    String classNameKey = requestUrlKey.substring(0, requestUrlKey.lastIndexOf(".url")) + ".className";
                    String className = properties.getProperty(classNameKey);
                    Object instance = Class.forName(className).newInstance();
                    urlInstanceMap.put(requestUrl, instance);
                }
            }catch (Exception e){
                e.printStackTrace();
            }
        }
        /**
         * 启动
         */
        public void start(){
            try {
                ServerSocket serverSocket = new ServerSocket(port);
                while(true){
                    Socket socket = serverSocket.accept();
                    handleRequest(socket);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        /**
         * 处理请求
         */
        private void handleRequest(Socket socket) throws Exception {
            SelfHttpRequest request = new SelfHttpRequest(socket.getInputStream());
            SelfHttpResponse response = new SelfHttpResponse(socket.getOutputStream());
            if(request.getRequestUrl() == null){
                return;
            }
            Object instance = urlInstanceMap.get(request.getRequestUrl());
            if(null == instance){
                throw new RuntimeException("404 NOT FOUND");
            }
            Method method = instance.getClass().getMethod("doService",
                    new Class[]{SelfHttpRequest.class, SelfHttpResponse.class});
            method.invoke(instance, request, response);
        }
        public static void main(String[] args) {
            SelfTomcat selfTomcat = new SelfTomcat(8000);
            selfTomcat.start();
        }
    }
    

    FirstServlet

    public class FirstServlet extends SelfHttpServlet {
    
        @Override
        public void doGet(SelfHttpRequest request, SelfHttpResponse response) throws IOException {
            response.write("调用FirstServlet的get方法");
        }
    
        @Override
        public void doPost(SelfHttpRequest request, SelfHttpResponse response) throws IOException {
            response.write("调用FirstServlet的post方法");
        }
    }
    

    SecondServlet

    public class SecondServlet extends SelfHttpServlet {
        @Override
        public void doGet(SelfHttpRequest request, SelfHttpResponse response) throws IOException{
            response.write("调用SecondServlet的get方法");
        }
    
        @Override
        public void doPost(SelfHttpRequest request, SelfHttpResponse response) throws IOException {
            response.write("调用SecondServlet的get方法");
        }
    }
    

    配置

    servlet.one.url=/firstServlet.do
    servlet.one.className=com.tomcat.servlet.FirstServlet
    servlet.two.url=/secondServlet.do
    servlet.two.className=com.tomcat.servlet.SecondServlet
    

    相关文章

      网友评论

          本文标题:使用bio手写tomcat

          本文链接:https://www.haomeiwen.com/subject/lewiyhtx.html