WebServer解析请求行和消息头

新建Maven项目

目录结构:
在这里插入图片描述

ClientHandler

public class ClientHandler implements Runnable {
    
    
    private Socket socket;
    //新建构造方法,实话化时将传入的socket赋值
    public ClientHandler(Socket socket){
    
    
        this.socket = socket;
    }

    public void run() {
    
    
        /**
         * 一问一答交互方式
         * 1. 解析请求
         * 2. 处理请求
         * 3. 发送响应
         */
        try {
    
    
            //实例化HttpRequest对象,解析请求
            HttpRequest request = new HttpRequest(socket);

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

WebServer

public class WebServer {
    
    
    private ServerSocket server;

    public WebServer(){
    
    

        try {
    
    
            System.out.println("服务端正在启动");
            server = new ServerSocket(8088);
            System.out.println("启动完成");
        } catch (IOException e) {
    
    
            e.printStackTrace();
        }

    }

    public static void main(String[] args) {
    
    
        WebServer server = new WebServer();
        server.start();
    }

    private void start() {
    
    
        try {
    
    
            System.out.println("等待客户端链接");
            //阻塞线程,等待一个客户端链接,连接后继续执行
            Socket socket = server.accept();
            System.out.println("一个客户端链接了");

            ClientHandler handler = new ClientHandler(socket);
            Thread t = new Thread(handler);
            t.start();

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

HttpRequest

/**
 * 该类对象对应客户端的一次请求
 * 包含请求中的各种属性
 * 请求行中的请求方法/路径/版本  消息头中的信息等
 */
public class HttpRequest {
    
    
    //请求行三个属性
    private String method;
    private String url;
    private String protocol;

    //消息头中的信息

    //消息正文中的信息

    //客户端发送过来的socket
    private Socket socket;
    //通过socket获得的输入流
    private InputStream is;
    /**
     * 构造方法
     * 初始化当前类的socket和is
     * 获得请求信息
     */
    public HttpRequest(Socket socket){
    
    
        try {
    
    
            this.socket = socket;
            this.is = socket.getInputStream();
        } catch (IOException e) {
    
    
            e.printStackTrace();
        }

        System.out.println("HttpRequest开始解析请求。。。");

        //1.解析请求行
        parseRequestLine();
        //2.解析消息头
        parseHeaders();
        //3.解析消息正文
        parseContent();
        System.out.println("HttpRequest解析请求结束");
    }
    //解析请求行
    public void parseRequestLine(){
    
    
        System.out.println("开始请求请求行");
        try {
    
    
            String line = readLine();
            System.out.println("请求行信息获得"+line);
            //按空格拆分
            String[] data = line.split("\\s");
            method = data[0];
            url = data[1];
            protocol = data[2];
            System.out.println("method"+method);
            System.out.println("url"+url);
            System.out.println("protocol"+protocol);
        } catch (IOException e) {
    
    
            e.printStackTrace();
        }
        System.out.println("请求行解析结束");
    }
    //解析消息头
    public void parseHeaders(){
    
    
        System.out.println("开始解析消息头");
        try {
    
    
            while (true){
    
    
                String line = readLine();
                //消息头结束时会有个空行,读取到空行表示消息头结束
                if ("".equals(line)){
    
    
                    break;
                }
                System.out.println("消息头"+line);
            }
        } catch (IOException e) {
    
    
            e.printStackTrace();
        }
    }

    //解析消息正文
    public void parseContent(){
    
    

    }
    //从客户端发送过来的请求中读取一行信息
    public String readLine() throws IOException {
    
    
        //定义一个可变长度字符串接受一行文字
        StringBuilder builder = new StringBuilder();
        int d = -1;
        //定义两个值,什么都行只要不是13和10,保证循环不退出
        char c1 = 'a', c2 = 'a';
        //读取低八位,如果不为-1则证明还有下一个字节
        while((d=is.read()) != -1){
    
    
            c2 = (char)d;
            //按照http规定协议判断是否在换行
            if (c1==13 && c2==10){
    
    
                break;
            }
            //append累加,c2已经转换成为charl,不要再转换了
            builder.append(c2);
            //c2吃赋值给c1,作为下次循环的上一个字符
            c1=c2;
//                System.out.print((char) d);
        }
        return  builder.toString().trim();
    }
}

猜你喜欢

转载自blog.csdn.net/sinat_33940108/article/details/121382110