【问题标题】:java http server responsejava http服务器响应
【发布时间】:2021-04-14 15:01:41
【问题描述】:

我正在构建一个必须处理 http 请求的 java 服务器。我正在尝试处理一个 GET 请求,它部分工作正常。在我想在这里讨论的具体情况下,我想用 Json 来回应。这就是我正在做的:

    private Socket socket;
    OutputStream outputStream = socket.getOutputStream();

    String json = gson.toJson(conversazione);

    String response =
            "HTTP/1.1 200 OK" + CRLF +
            "Content-Length: " + (json.getBytes().length)+ CRLF +
            "Content-Type: application/json;charset=UTF-8" + CRLF +
            "Server: Federico's Java Server" + CRLF +
            "Date: " + new Date() + CRLF + CRLF +
            json + CRLF + CRLF;

    outputStream.write(response.getBytes());

它有效,我的意思是客户端收到状态 200 OK,但它收到的是文本而不是 Json。我正在向 Postman 提出请求,这是它收到的响应:

【问题讨论】:

  • ...但这就是您在回复中写出的内容。如果你只想写出 JSON,就只写出 JSON。
  • @Makoto 这个叫做json的字符串其实是一个json。但我认为你的意思是别的,所以请你再解释一下吗?
  • 你说的是正确的@Makoto,所以你研究 Frid Ric 的关键是你如何发送与响应正文分开的响应标头,目前它只是文本输出回应
  • @Chris 以哪种方式分离,分离是什么意思?我什至无法想象这种分离,所以我无法想出解决方案
  • 也最好致电.getBytes(StandardCharsets.UT8)。你确定 CRLF = "\r\n"?它看起来是倒置的。

标签: java http server postman


【解决方案1】:

我认为您遇到的问题是您将 HTTP 标头和正文一起发送,它们需要分开。

在快速搜索后发现this article 证明了这一点。从那篇文章中的代码示例(稍作调整以使用示例中的值):

PrintWriter out = new PrintWriter(socket.getOutputStream());
BufferedOutputStream dataOut = new BufferedOutputStream(connect.getOutputStream());

String content = "application/json;charset=UTF-8";
byte[] fileData = json.getBytes();
int fileLength = (int) file.length();

// send HTTP Headers
out.println("HTTP/1.1 200 OK");
out.println("Server: Federico's Java Server");
out.println("Date: " + new Date());
out.println("Content-type: " + content);
out.println("Content-length: " + fileLength);
out.println(); // blank line between headers and content, very important !
out.flush(); // flush character output stream buffer
                    
dataOut.write(fileData, 0, fileLength);
dataOut.flush();

我鼓励你去看看那篇文章。我上面的示例是手动编写的,我没有按预期工作。

【讨论】:

  • 绝对不需要单独发送标头(从正文或彼此之间),尽管有些服务器这样做是因为它更方便并且允许。 OTOH 使用PrintWriter.println 是错误的;它使用(本地)平台 EOL,在 Unix 上它只是 LF 而不是 CRLF,而 HTTP 规范需要 CRLF(并且总是有)尽管许多客户端都可以容忍并接受 LF(类似地,许多服务器在请求时都可以容忍它)。
【解决方案2】:

你确定 CRLF = "\r\n" 吗?看起来倒过来了。

"\n\r" 可能被解释为两行 (Unix+MacOS),因此 HTTP 标头在第一行之后结束。

最好调用 .getBytes(StandardCharsets.UT8)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-03-05
    • 2021-10-07
    • 1970-01-01
    • 1970-01-01
    • 2013-02-02
    • 1970-01-01
    • 1970-01-01
    • 2018-10-19
    相关资源
    最近更新 更多