栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

动手实现一个简单的BS模型(仿照tomcat)

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

动手实现一个简单的BS模型(仿照tomcat)

动手实现一个简单的BS模型(仿照tomcat)

Tomcat 服务器是Web 应用服务器,浏览器则可看作web应用客户端。客户端与服务端是通过点对点的socket通信,在http协议规范下进行的。

http协议分为请求部分和响应部分

请求部分格式
请求行 : 请求方法 请求路径 http协议及版本
请求头 :  键值对
请求空行 
请求体 : get方法无,post方法有

例子:
GET / HTTP/1.1
Host: www.baidu.com
...

响应部分格式
响应行    http协议及版本 状态码 响应提示信息
响应头    键值对
响应空行
响应体    服务器返回的数据
 HTTP/1.1 200 ok
 server: Apache-Coyote/1.1
 ...
 
 网页数据

基于socket和请求,模拟浏览器请求数据

public class TestClient {

    public static void main(String[] args) {

        Socket s = null;
        OutputStream os = null;
        InputStream is = null;

        try {
            
            s = new Socket("www.baidu.com",80);
            os = s.getOutputStream();
            is = s.getInputStream();

            os.write("GET / HTTP/1.1n".getBytes());
            os.write("HOST:www.baidu.comn".getBytes());
            os.write("n".getBytes());

            int i = is.read();
            while(i!=-1){
                System.out.print((char)i);
                i = is.read();
            }

        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            if(s!=null){
                try {
                    s.close();
                } catch (IOException e) { }
            }

            if(os!=null){
                try {
                    os.close();
                } catch (IOException e) { }
            }

            if(is!=null){
                try {
                    is.close();
                } catch (IOException e) { }
            }
        }


    }
}

基于socket和响应,模拟服务器响应客户端

package com.lovehot.learn.BS;

import java.io.IOException;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;


public class TestServer {
    public static void main(String[] args) {
        ServerSocket ss = null;
        Socket s = null;
        OutputStream os = null;

        try {
            
            ss = new ServerSocket(8080);
            while(true) {

                
                s = ss.accept();
                
                os = s.getOutputStream();
                
                os.write("HTTP/1.1 200 okn".getBytes());
                os.write("Content-Type: text/html;charset=utf-8n".getBytes());
                os.write("Server: zhoumu/2020n".getBytes());
                os.write("nn".getBytes());
                StringBuffer buffer = new StringBuffer();
                buffer.append("");
                buffer.append("");
                buffer.append("");
                buffer.append("百度一下,你就知道");
                buffer.append("");
                buffer.append("");
                buffer.append("");
                buffer.append("度娘");
                buffer.append("");
                buffer.append("");
                os.write(buffer.toString().getBytes());

                
                os.flush();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            if(ss != null){
                try {
                    ss.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

            if(s != null){
                try {
                    s.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

            if(os != null){
                try {
                    os.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }


    }
}

完整版本

tomcat中有分为静态请求和动态请求,在MyServer简单的分离了动静态的请求,静态请求直接返回静态资源,动态请求则会由Servlet流程负责返回动态数据,为了简便起见这里未链接数据库而实现业务。

MyServlet中定义servlet的基本行为,MyServer被请求,解析请求和分离请求。

MyServlet

package com.lovehot.learn.mycat;

import java.io.InputStream;
import java.io.OutputStream;

public interface MyServlet {

        //初始化
        void init();
        //服务
        void Service(InputStream is, OutputStream ops);
        //销毁
        void destroy();

}

MyServletImpl

package com.lovehot.learn.mycat;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;


public class MyServletImpl implements MyServlet{

    @Override
    public void init() {
        System.out.println("初始化servlet生存环境");
    }

    @Override
    public void Service(InputStream is, OutputStream os) {
        try {
            os.write("已经获取到前端传来的数据,servlet进行处理".getBytes());
            os.flush();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void destroy() {
        System.out.println("生命周期结束,销毁");
    }
}

MyServer

package com.lovehot.learn.mycat;

import com.lovehot.learn.version2.Servlet;

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.HashMap;
import java.util.Map;


public class MyServer {
    //获取到项目下的WebContent目录
    public static final String WEB=System.getProperty("user.dir") + "\" + "Web";
    // 代表客户端要请求资源的路径
    public  static String url = "";

    public static Map map = new HashMap<>();

    //加载配置信息
    static {
        map.put("aa","MyServletImpl");
    }

    public static void main(String[] args) {


        ServerSocket ss = null;
        Socket s = null;
        OutputStream os = null;
        InputStream is = null;


        try {
            ss = new ServerSocket(8080);
            
            s = ss.accept();

            os = s.getOutputStream();
            is = s.getInputStream();

            //获取url
            parseUrl(is);

            if(url.indexOf(".")!=-1){
                //静态资源
                sendStaticResource(os);
            }else{
                //动态资源
                sendDynamicResource(os,is);
            }


        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            if(ss != null){
                try {
                    ss.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

            if(s != null){
                try {
                    s.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

            if(os != null){
                try {
                    os.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

            if(is != null){
                try {
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }


    }

    private static void sendDynamicResource(OutputStream os, InputStream is) {
        try {
            os.write("HTTP/1.1 200 OKn".getBytes());
            os.write("Server:apachen".getBytes());
            os.write("Content-Type:text/html;charset=utf-8n".getBytes());
            os.write("n".getBytes());

            if(map.containsKey(url)){

                String value = map.get(url);
			
                Class clazz = Class.forName(value);
                Servlet servlet = (Servlet)clazz.newInstance();

                servlet.init();
                servlet.Service(is, os);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    private static void sendStaticResource(OutputStream os) {

        byte[] bytes = new byte[1024*2];

        FileInputStream fis = null;

        File file = new File(WEB+url);

        try{
            if(file.exists()){
                os.write("HTTP/1.1 200 OKn".getBytes());
                os.write("Server:apache-Coyote/1.1n".getBytes());
                os.write("Content-Type:text/html;charset=utf-8n".getBytes());
                os.write("n".getBytes());

                fis = new FileInputStream(file);

                int i = fis.read(bytes);
                while(i!=-1){
                    os.write(bytes,0,i);
                    i = fis.read(bytes);
                }
            }else {
                //如果文件不存在,客户端响应文件不存在消息
                os.write("HTTP/1.1 404 not foundn".getBytes());
                os.write("Server:apache-Coyote/1.1n".getBytes());
                os.write("Content-Type:text/html;charset=utf-8n".getBytes());
                os.write("n".getBytes());
                String errorMessage = "file not found";
                os.write(errorMessage.getBytes());
                os.flush();
            }
        }catch (Exception e){
            throw new RuntimeException("发送资源出错");
        }finally {
            if(fis!=null){
                try {
                    fis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

    }

    private static void parseUrl(InputStream is) {

        
        StringBuffer content = new StringBuffer(1024*3);

        byte[] buffer = new byte[1024*3];

        try {
            int i = is.read(buffer);
            for (int j = 0; j  

通过:https://www.bilibili.com/video/BV1AW41117Cu?spm_id_from=333.337.search-card.all.click 学习

完整版本源码:

链接:https://pan.baidu.com/s/12sCER8_sVPjJbwC7RkVG3A

提取码:java

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/781437.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号