Либо ошибка "HTTP/1.1 header parser received no bytes", либо не могу прочитать данные до конца
Все привет, 2 дня бился над, вроде бы, несложной задачей, не мог решить, помогите. Это простое клиент-серверное HTTP приложение, где клиент пересылает json как файл, а сервер парсит его и возвращает некоторые данные из него.
Вот клиентская часть
public class HttpClientRunner {
public static void main(String[] args) throws IOException, URISyntaxException, InterruptedException {
HttpClient client = HttpClient.newBuilder()
.version(HttpClient.Version.HTTP_1_1)
.build();
HttpRequest request = HttpRequest.newBuilder()
.uri(new URI("http://localhost:8082"))
.header("Content-Type", "application/json")
.POST(ofFile(Path.of("src/main/resources/testForServer.json")))
.build();
HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.headers());
System.out.println(response.body());
}
}
Вот серверная:
public class HttpServer {
private final int port;
public HttpServer(int port) {
this.port = port;
}
public void run() {
ServerSocket serverSocket = null;
try {
serverSocket = new ServerSocket(port);
Socket socket = serverSocket.accept();
processSocket(socket);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
private void processSocket(Socket socket) {
try (socket;
var in = new DataInputStream(socket.getInputStream());
var out = new DataOutputStream(socket.getOutputStream())
) {
byte[] clientRequest = in.readNBytes(520);
System.out.println(new String(clientRequest));
//List<Integer> rsl = parse(clientRequest);
byte[] body = """
<!DOCTYPE html>
<html lang="en">
<head>
<title>Salary</title>
</head>
<body>
<table>
<tr>
<th>Total income</th>
<th>Total tax</th>
<th>Total profit</th>
</tr>
<tr>
<td>%s</td>
<td>%s</td>
<td>%s</td>
</tr>
</table>
</body>
</html>"""
.getBytes();
//.formatted(rsl.get(0), rsl.get(1), rsl.get(2)).getBytes();
out.write("""
HTTP/1.1 200 OK
content-type: text/html
content-length: %s
""".formatted(body.length).getBytes());
out.write(System.lineSeparator().getBytes());
out.write(body);
} catch (IOException e) {
e.printStackTrace();
}
}
private List<Integer> parse(byte[] clientRequest) {
String str = new String(clientRequest, StandardCharsets.UTF_8);
String[] parts = str.split("\\r\\n\\r\\n");
List<Integer> rsl = new LinkedList<>();
int total_income = 0;
int total_tax = 0;
int total_profit = 0;
ObjectMapper objectMapper = new ObjectMapper();
try {
JsonNode jsonArray = objectMapper.readTree(parts[1]);
for(JsonNode jsonNode : jsonArray) {
total_income += jsonNode.get("salary").asInt();
total_tax += jsonNode.get("tax").asInt();
}
} catch (IOException e) {
throw new RuntimeException(e);
}
total_profit = total_income - total_tax;
rsl.add(total_income);
rsl.add(total_tax);
rsl.add(total_profit);
return rsl;
}
}
Если я в строке byte[] clientRequest = in.readNBytes(520);
использую readAllBytes()
, то процесс висит и не выдает никакого результата, как будто не может дойти до конца потока данных. Пробовал по-разному проходить по входящему потоку, и построково, и побайтово, но удается остановить только принудительно. Пробовал передавать json не как файл, а как строку, результат тот же.
Вторая часть проблемы, если ставить byte[] clientRequest = in.readNBytes(520);
, то он считывает эти данные, но при парсинге скорей всего на строке JsonNode jsonArray = objectMapper.readTree(parts[1])
вылетает ошибка "HTTP/1.1 header parser received no bytes"