ответ http-сервера java

#java #http #server #postman

#java #http #сервер #почтальон

Вопрос:

Я создаю java-сервер, который должен обрабатывать http-запросы. Я пытаюсь обработать запрос 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, и это то, что он получает в качестве ответа:

введите описание изображения здесь

Комментарии:

1. … но это то, что вы пишете в своем ответе. Если вы только хотели записать JSON, только напишите JSON.

2. @Makoto строка с именем json на самом деле является json. Но я думаю, вы имеете в виду что-то другое, поэтому, пожалуйста, не могли бы вы подробнее объяснить?

3. То, что вы говорите, правильно @Makoto, поэтому главное, чтобы вы изучили Frid Ric, — это то, как вы отправляете заголовки ответа отдельно от тела ответа, на данный момент это просто текст, отправляемый в качестве ответа

4. @Chris Отделить каким образом, что вы подразумеваете под разделением? Я даже не могу себе представить это разделение, поэтому я не могу придумать решение

5. Также лучше позвонить .getBytes(StandardCharsets.UT8) . Вы уверены, что CRLF = "rn" ? Он выглядит перевернутым.

Ответ №1:

Вы уверены, что CRLF = «r n»? Он выглядит перевернутым.

» n r» может интерпретироваться как две строки (Unix macOS), следовательно, заголовок HTTP заканчивается после первой строки.

Также лучше вызвать .getBytes(StandardCharsets.UT8).

Ответ №2:

Я думаю, что проблема, с которой вы сталкиваетесь, заключается в том, что вы отправляете HTTP-заголовки и тело вместе, они должны быть отдельными.

Я нашел эту статью после быстрого поиска, который демонстрирует это. Из примера кода в этой статье (слегка скорректирован для использования значений в вашем примере):

 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();

 

Я рекомендую ознакомиться с этой статьей. Мой приведенный выше пример был написан вручную, и я не работал должным образом.

Комментарии:

1. Нет абсолютно никакого требования отправлять заголовки отдельно (из тела или друг от друга), хотя некоторые серверы делают это, потому что это удобнее и разрешено . Использование OTOH PrintWriter.println неверно; он использует (локальную) платформу EOL, которая в Unix является только LF, а не CRLF, в то время как спецификация HTTP требует CRLF (и всегда имеет), хотя многие клиенты терпимы и принимают LF (аналогично, многие серверы допускают его при запросах).