不同contentType的数据类型

Server代码

package com.test.tomcat.servlet;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketAddress;

public class Server {
    
    

    /**
     * 初始化服务器
     *
     * @param host
     * @param port
     */
    public void init(String host, int port) {
    
    
        try {
    
    
            ServerSocket serverSocket = new ServerSocket();
            System.out.println("服务器 " + host + ":" + port + " 启动成功...");
            SocketAddress socketAddress = new InetSocketAddress(host, port);
            serverSocket.bind(socketAddress);
            readyAccept(serverSocket);
        } catch (Exception e) {
    
    
            e.printStackTrace();
        }
    }

    /**
     * 接收请求
     *
     * @param serverSocket
     * @throws IOException
     */
    public void readyAccept(ServerSocket serverSocket) throws IOException {
    
    
        while (true) {
    
    
            Socket client = serverSocket.accept();
            System.out.println();
            new HandlerThread(client);
        }
    }

    /**
     * 请求处理
     */
    static class HandlerThread implements Runnable {
    
    
        private Socket socket;

        public HandlerThread(Socket socket) {
    
    
            this.socket = socket;
            new Thread(this).start();
        }

        @Override
        public void run() {
    
    
            try {
    
    
                showRequestData(socket);
                writeResponseData(socket);
            } catch (Exception e) {
    
    
                e.printStackTrace();
            } finally {
    
    
                if (socket != null) {
    
    
                    try {
    
    
                        socket.close();
                        System.out.println("socket closed...");
                    } catch (Exception e) {
    
    
                        socket = null;
                        System.out.println("socket close failed:" + e.getMessage());
                    }
                }
            }
        }

        /**
         * 不能使用BufferedReader读取数据,因为会有数据读不全,导致读取数据一直阻塞
         * 错误代码:
         * BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
         * String line;
         * while ((line = br.readLine()) != null) {
         * System.out.println(line);
         * }
         *
         * @param socket
         * @throws Exception
         */
        public void showRequestData(Socket socket) throws Exception {
    
    
            DataInputStream input = new DataInputStream(socket.getInputStream());
            byte[] bytes = new byte[input.available()];
            input.read(bytes);
            System.out.println(new String(bytes));
        }

        public void writeResponseData(Socket socket) throws IOException {
    
    
            DataOutputStream out = new DataOutputStream(socket.getOutputStream());
            StringBuilder sb = new StringBuilder();
            sb.append("HTTP/1.1 200 ok").append("\r\n").append("Content-Type: application/json").append("\r\n").append("\r\n").append("{\"code\":200}");
            out.write(sb.toString().getBytes("UTF8"));
        }
    }
    public static void main(String[] args) {
    
    
        Server server = new Server();
        server.init("localhost", 8081);
    }
}

数据

application/x-www-form-urlencoded

在这里插入图片描述

multipart/form-data

在这里插入图片描述

application/json

在这里插入图片描述

遇到的问题

一下情况都是以postman作为客户端模拟请求的!

获取请求数据的代码不同会导致不同的结果

  1. InputStream#read(byte b[]) +while循环发生阻塞问题
public void showRequestData(Socket socket) throws Exception {
    
    

    byte[] bytes = new byte[1024];
    int len;
    InputStream inputStream = socket.getInputStream();
    while ((len = inputStream.read(bytes)) != -1) {
    
    
        String s = new String(bytes, 0, len);
        System.out.println(s);
    }
}

此代码循环完请求数据后,由于postman没有断开链接,会一直阻塞在while ((len = inputStream.read(bytes)) != -1)代码块这,并且通过idea的Evaluate Expression计算不出值,会一直阻塞。此时如果在postman上取消请求,这样才会跳出while循环。

  1. BufferedReader#readLine发生阻塞问题
BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String line;
while ((line = br.readLine()) != null) {
    
    
    System.out.println(line);
}

此代码与上面的代码时一个效果
3. 使用DataInputStream可以解决阻塞的问题

DataInputStream input = new DataInputStream(socket.getInputStream());
byte[] bytes = new byte[input.available()];
input.read(bytes);
System.out.println(new String(bytes));

总结

  1. HTTP/1.1这一行上面都有一行空行
  2. Content-length下一行是空行,再下一行是数据

Guess you like

Origin blog.csdn.net/qq_30038111/article/details/119787256