[Imitation Tomact of imitation framework] 4. Encapsulate HttpRequest object (attribute mapping http request message), HttpResponse object (attribute mapping http response message)

Article directory

  • 1. Create HttpRequest object
  • 2. Create HttpResponse object


1. Create HttpRequest object

The attributes in the HttpRequest object correspond to the content in the HTTP protocol, and are used for subsequent servlets to obtain the parameters in the request from the request.

Refer to the http request message:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.Map;

public class HttpRequest {<!-- -->
    private String method;
    private String url;
    private String version;
    // Store the KV in the request header
    private Map<String, String> headers = new HashMap<>();
    // The parameters in the url and the parameters in the body are put into this parameters hash table.
    private Map<String, String> parameters = new HashMap<>();
    // store cookies
    private Map<String, String> cookies = new HashMap<>();
    private String body;

    public static HttpRequest build(InputStream inputStream) throws IOException {<!-- -->
        HttpRequest request = new HttpRequest();
        BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
        // 1. Process the first line GET /url /HTTP/1.1
        String firstLine = bufferedReader. readLine();
        String[] firstLineTokens = firstLine. split(" ");
        request.method = firstLineTokens[0];
        request.url = firstLineTokens[1];
        request.version = firstLineTokens[2];
        // 2. Parse url
        int pos = request.url.indexOf("?");
        //2.1 If so? number, which also indirectly indicates that this is a GET request
        if (pos != -1) {<!-- -->
            // 2.1.1 Intercept all parameters
            String queryString = request.url.substring(pos + 1);
            // 2.2.2 parse the parameter into KV and store it
            parseKV(queryString, request.parameters);
        }
        // 3. Loop processing header part
        String line = "";
        while ((line = bufferedReader. readLine()) != null & amp; & amp; line. length() != 0) {<!-- -->
            String[] headerTokens = line. split(": ");
            request.headers.put(headerTokens[0], headerTokens[1]);
        }
        // 4. Parse cookies
        String cookie = request. headers. get("Cookie");
        if (cookie != null) {<!-- -->
            // parse the cookie
            parseCookie(cookie, request.cookies);
        }
        // 5. Parse body
        if ("POST".equalsIgnoreCase(request.method)
                || "PUT".equalsIgnoreCase(request.method)) {<!-- -->
            // These two methods need to process the body, other methods are not considered for the time being
            // Need to read the body.
            // Need to know the length of the body first. Content-Length is for this.
            // The length unit here is "byte"
            int contentLength = Integer. parseInt(request. headers. get("Content-Length"));
            // Pay attention to understand the meaning here~~
            // For example, if contentLength is 100, there are 100 bytes in body.
            // The length of the buffer created below is 100 char (equivalent to 200 bytes)
            // The buffer is not afraid of being long. It is afraid that it is not enough. The buffer created in this way can ensure that the length is sufficient~~
            char[] buffer = new char[contentLength];
            // Bundle
            int len = bufferedReader. read(buffer);
            request.body = new String(buffer, 0, len);
            // The format in the body is like: username=tanglaoshi & amp;password=123
            parseKV(request.body, request.parameters);
        }
        return request;
    }

    private static void parseCookie(String cookie, Map<String, String> cookies) {<!-- -->
        // 1. Split into multiple key-value pairs according to semicolon and space
        String[] kvTokens = cookie. split("; ");
        // 2. Split each key and value by =
        for (String kv : kvTokens) {<!-- -->
            String[] result = kv. split("=");
            cookies. put(result[0], result[1]);
        }
    }

    private static void parseKV(String queryString, Map<String, String> parameters) {<!-- -->
        // 1. Split into multiple key-value pairs according to & amp;
        String[] kvTokens = queryString.split(" & amp;");
        // 2. Split each key and value by =
        for (String kv : kvTokens) {<!-- -->
            String[] result = kv. split("=");
            parameters. put(result[0], result[1]);
        }
    }

    public String getMethod() {<!-- -->
        return method;
    }

    public String getUrl() {<!-- -->
        return url;
    }

    public String getVersion() {<!-- -->
        return version;
    }

    public String getBody() {<!-- -->
        return body;
    }

    public String getParameter(String key) {<!-- -->
        return parameters. get(key);
    }

    public String getHeader(String key) {<!-- -->
        return headers.get(key);
    }

    public String getCookie(String key) {<!-- -->
        return cookies.get(key);
    }
}


2. Create an HttpResponse object

Refer to the http request message:

import java.io.BufferedWriter;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.util.HashMap;
import java.util.Map;

public class HttpResponse {<!-- -->
    private String version = "HTTP/1.1";
    private int status;
    private String message;
    private Map<String, String> headers = new HashMap<>();
    private StringBuilder body = new StringBuilder();
    private OutputStream outputStream = null;

    public static HttpResponse build(OutputStream outputStream) {<!-- -->
        HttpResponse response = new HttpResponse();
        response. outputStream = outputStream;
        return response;
    }

    public void setVersion(String version) {<!-- -->
        this.version = version;
    }

    public void setStatus(int status) {<!-- -->
        this.status = status;
    }

    public void setMessage(String message) {<!-- -->
        this.message = message;
    }

    public void setHeader(String key, String value) {<!-- -->
        headers.put(key, value);
    }

    public void writeBody(String content) {<!-- -->
        body.append(content);
    }

    public void flush() throws IOException {<!-- -->
        BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(outputStream));
        bufferedWriter.write(version + " " + status + " " + message + "\\
");
        headers.put("Content-Length", body.toString().getBytes().length + "");
        for (Map.Entry<String, String> entry : headers.entrySet()) {<!-- -->
            bufferedWriter.write(entry.getKey() + ": " + entry.getValue() + "\\
");
        }
        bufferedWriter.write("\\
");
        bufferedWriter.write(body.toString());
        bufferedWriter.flush();
    }
}