#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 (аналогично, многие серверы допускают его при запросах).