400 Bad Request получен с использованием java.net.HTTPClient, но отлично работает с Spring RestTemplate и Postman с тем же URL-адресом и телом

Я пытаюсь отправить запрос JSON POST на URL-адрес с помощью HTTPClient в моем приложении Springboot, но я получаю ответ о статусе 400 от сервера. Однако, когда я отправляю тот же запрос с помощью Postman, я получаю желаемый ответ от сервера.

Вот мой код:

// some dummy url:
String url = "http://88.22.199.111:5000/detect";

JSONObject json1 = new JSONObject();
json1.put("From", "Sawan");
json1.put("to", "Mohan");
json1.put("message", "is API working?");
json1.put("check_list", 1);

HttpClient httpClient = HttpClient.newBuilder().build();

HttpRequest httpRequest = HttpRequest.newBuilder()
        .uri(URI.create(url))
        .header("Content-Type", "application/json")
        .POST(HttpRequest.BodyPublishers.ofString(json1.toString()))
        .build();

System.out.println(json1.toString());
HttpResponse<String> httpResponse = httpClient.send(httpRequest, HttpResponse.BodyHandlers.ofString());

System.out.println(httpResponse.statusCode());
System.out.println(httpResponse.body());

Это вывод на консоль:

{"check_list":1,"From":"Sawan","to":"Mohan","message":"is API working?"}
400
{"message": "The browser (or proxy) sent a request that this server could not understand."}

Когда я нажимаю тот же URL-адрес через Postman со следующими данными, я получаю желаемый ответ от сервера:

Тип запроса: ОТПРАВКА

URL: тот же URL, что и выше

URL-адрес:

curl --location 'http://88.22.199.111:5000/detect' \
--header 'Content-Type: application/json' \
--data '{
    "From":"Sawan"
    ,"to":"Mohan"
    ,"message":"is API working?"
    ,"check_list":1
} '

Желаемый результат:

{
    "status": 200,
    "message": "Success",
    "timestamp": "2023-03-31 05:20:33.455868 +0000",
    "data": {
        "Message": "is API working?",
        "MessageTimeUTC": "Fri, 31 Mar 2023 05:20:33 GMT",
        "Message_By": "sawan",
        "Message_To": "mohan",
        "Message_Intended_For": "mohan",
        "Sentences": []
}

Кроме того, когда я использую класс RestTemplate, он работает нормально, и я получаю желаемый результат на консоли, но в реальном приложении я не могу использовать класс Springboot RestTemplate, поэтому мне нужна помощь с этим.

Что-то не так с моим кодом? Нужно ли мне включать какие-либо дополнительные заголовки в мой запрос? Любая помощь будет оценена по достоинству.

Пожалуйста, сделайте следующее и добавьте к вопросу. Добавьте System.out.println(json1.toString()); над отправкой и добавлением вывода. Получите завиток для запроса, который работает от Postman, используя «</>» справа.

John Williams 31.03.2023 09:13

Добавил это в вопрос!

Mohan 31.03.2023 09:34
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Версия Java на основе версии загрузки
Версия Java на основе версии загрузки
Если вы зайдете на официальный сайт Spring Boot , там представлен start.spring.io , который упрощает создание проектов Spring Boot, как показано ниже.
Документирование API с помощью Swagger на Springboot
Документирование API с помощью Swagger на Springboot
В предыдущей статье мы уже узнали, как создать Rest API с помощью Springboot и MySql .
0
2
134
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Надеюсь, это сблизит вас. У меня нет доступа к вашему серверу.

Я сравнил то, что отправляет java.net.http.HttpClient, с тем, что отправляет Postman/cURL. Единственные различия, которые я вижу, это заголовки Accept, Upgrade и Http2-Settings, которые я добавил в код ниже. Заголовок User-Agent не важен. Это не должно иметь значения, но, возможно, сервер, на который вы звоните, очень специфичен, например, он не может работать с http2.

Для таких проблем я считаю очень полезным отправлять запросы на httpbin.org. Он отвечает всем, что получил.

import java.io.IOException;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

import org.json.JSONObject;

public class App 
{
    public static void main( String[] args ) throws IOException, InterruptedException
    {
        String url = "http://88.22.199.111:5000/detect";
        // or url = "http://httpbin.org/post"; // this is very helpful

        JSONObject json1 = new JSONObject();
        json1.put("From", "Sawan");
        json1.put("to", "Mohan");
        json1.put("message", "is API working?");
        json1.put("check_list", 1);

        HttpClient httpClient = HttpClient
            .newBuilder()
            .version(Version.HTTP_1_1) // added this
            .build();

        HttpRequest httpRequest = HttpRequest.newBuilder()
                .uri(URI.create(url))
                .header("Content-Type", "application/json")
                .header("Accept", "*/*") // added this
                .POST(HttpRequest.BodyPublishers.ofString(json1.toString()))
                .build();

        System.out.println(json1.toString());
        HttpResponse<String> httpResponse = httpClient.send(httpRequest, HttpResponse.BodyHandlers.ofString());

        System.out.println(httpResponse.statusCode());
        System.out.println(httpResponse.body());
    }
}

Возможно, также попробуйте RestTemplate сравнить рабочие заголовки и полезную нагрузку с неисправными.

Большое спасибо за ваш ответ! Я пробовал это с HTTP-клиентом и RestTemplate: HTTP-клиент отправляет следующие заголовки: «Http2-Settings»: «AAEAAEAAAAIAAAABAAMAAABkAAQBAAAAAAAAAEAA», «Upgrade»: «h2c», «User-Agent»: «Java-http-client/11.0. 2", "Accept": "/", Rest Template отправляет следующее: "User-Agent": "Java/11.0.2", "Accept": "text/plain, application/json, application/*+json, / "Я попытался добавить "user-agent" и "accept", как и в остальных шаблонах, но все равно получил 400.

Mohan 31.03.2023 11:32

О боже - очень загадочно. Заголовок User-Agent не важен. «Принять» (с учетом регистра) может быть. Однако проблема может заключаться в «Http2-Settings»: «AAEAAAAAAAIAAAABAAMAAABkAAQBAAAAAAAAAEAA», «Upgrade»: «h2c». Попробуйте установить версию http на 1.1 с версией (Version.HTTP_1_1). Я обновил ответ, чтобы отразить.

John Williams 31.03.2023 11:57

Добавление HTTP-версии сработало. Большое спасибо!!!

Mohan 31.03.2023 12:05

Другие вопросы по теме