【发布时间】:2016-06-24 14:04:05
【问题描述】:
我正在用 Java 构建一个简单的 http 请求解析器,作为工作中的学习练习。我的任务是简单地获取一个包含正文的 POST 请求,对其进行解析并根据 http 协议发回响应(状态 200 OK)。
当我使用 curl 命令发布请求时,请求行和标题会打印出来,但正文不会。在我按下 Ctrl c 退出卷曲后,身体会被打印出来。
nc -l 命令可以正常工作,并且正文与标题一起打印出来。
这两者有什么区别,如何使用 curl post 命令打印请求正文?
我的代码在下面,欢迎任何输入。
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.*;
public class Server {
private static ServerSocket serverSocket;
private static Socket clientSocket;
private static BufferedReader bufferedReader;
private static String inputLine;
private static PrintWriter output;
public static void main(String[] args) {
try {
serverSocket = new ServerSocket(3000);
while (true) {
List<String> list = new ArrayList<String>();
clientSocket = serverSocket.accept();
bufferedReader = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
output = new PrintWriter(clientSocket.getOutputStream());
inputLine = bufferedReader.readLine();
while (inputLine.length() > 0) {
System.out.println(inputLine);
list.add(inputLine);
inputLine = bufferedReader.readLine();
}
String bodyLine = bufferedReader.readLine();
while(bodyLine != null && bodyLine.length() > 0){
System.out.println(bodyLine);
output.println(bodyLine);
bodyLine = bufferedReader.readLine();
}
/* My Request class has a parse method that takes a List and parses in accordingly. getRequestLine() returns the request line of the request and getMethod() its method. */
Request r = Request.parse(list);
if (r.getRequestLine().getMethod().equals("GET")){
output.println("HTTP/1.0 200 OK");
output.println("Content-Type: text/html");
output.println("");
output.println("<p>GET REQUEST: </p><p>" + r + "</p>");
}
if (r.getRequestLine().getMethod().equals("POST")){
output.println("HTTP/1.0 200 OK");
output.println("Content-Type: text/html");
output.println("");
output.println("<p>POST REQUEST:</p><p>" + r + "</p>");
}
output.close();
bufferedReader.close();
clientSocket.close();
}
} catch (IOException error) {
System.out.println(error);
}
}
}
请求类:
import java.util.*;
public class Request {
private Map<String, String> headers;
private String body;
private RequestLine requestLine;
public Request(Map<String, String> headers, String body, RequestLine requestLine) {
this.headers = headers;
this.body = body;
this.requestLine = requestLine;
}
public Map<String, String> getHeaders() {
return headers;
}
public String getBody() {
return body;
}
public RequestLine getRequestLine() {
return requestLine;
}
public String toString() {
return "Request Line: " + getRequestLine() + '\n' + "Headers: " + getHeaders();
}
public static Request parse(List<String> lines) {
String requestLineStr = lines.get(0);
String[] requestLineArr = requestLineStr.split(" ");
String method = requestLineArr[0];
String URI = requestLineArr[1];
String status = requestLineArr[2];
RequestLine requestLine = new RequestLine(URI, method, status);
// int index = lines.indexOf("\r\n\r\n");
// List<String> headerList = lines.subList(1, index);
// List<String> bodyList = lines.subList(index, -1);
List<String> headerList = lines.subList(1, lines.size()-1);
Map<String, String> headersMap = new HashMap<>();
for(int i = 0; i <headerList.size(); i++) {
String line = headerList.get(i);
String[] arr = line.split(" ");
headersMap.put(arr[0], arr[1]);
}
/*String bodyString = "";
for(int i = 0; i < bodyList.size(); i++) {
bodyString += bodyList.get(i);
}*/
return new Request(headersMap, "", requestLine);
}
}
【问题讨论】:
-
Request 使用什么库?如果自定义 - 提供您的代码
-
添加到问题中,但我很确定问题出在我获取输入流的方式上
-
能否请您添加到目前为止的 HTTP 请求和控制台输出?
-
我使用 curl 发送带有正文的 post 请求,它会看到第一个缓冲的阅读器,输入行,打印出请求行和标题并停止
-
RequestLine 也是自定义类吗?
标签: java http httprequest