首页 > 解决方案 > 应用重启后使用 Spring Boot 获取外部 API 返回 400 错误请求

问题描述

我正在使用 Spring Boot 作为我的应用程序的 API 网关,我遇到了这个奇怪的问题 - 当我重新启动应用程序(有时甚至经常发生)并调用我的端点(例如/api/all:)时,它应该从外部 API 返回解析和格式化的数据,第一个外部 API 调用返回 400 Bad Request Status。我不知道这是他们的后端问题还是我的问题,但是当我在邮递员中调用他们的端点时,它工作得很好。

我发现他们可能有一些 .NET 后端(通过搜索返回的错误消息),但我不确定这是否对您有帮助。

这是 400 响应 这是 400 响应

这是 200 响应 这是 200 响应

这是从他们的后端返回的错误消息 这是从他们的后端返回的错误消息

另外,我compile group: 'com.hynnet', name: 'httpclient', version: '4.5.1'用于获取外部 API。

这是我的 POST 请求构建器方法

public static HttpRequest buildPostRequest(final String url, final String body) {
    return HttpRequest.newBuilder()
            .version(HttpClient.Version.HTTP_1_1)
            .uri(URI.create(url))
            .setHeader(CONTENT_TYPE, APPLICATION_JSON)
            .POST(HttpRequest.BodyPublishers.ofString(body))
            .build();
}

这是我的 POST 请求发送方方法

public HttpResponse<String> sendPostRequest(
        final LinkedHashMap<String, Object> bodyStructure,
        final String url)
        throws Exception {
    final String body = buildBody(bodyStructure);
    final HttpRequest request = buildPostRequest(url, body);

    return client.send(request, HttpResponse.BodyHandlers.ofString());
}

这是我的 CacheService (它只是缓存来自外部 API 的响应,当它失败时,它会在一秒钟后再次尝试)。顺便提一句。这种方法工作得很好,在第二次调用时,它返回 200 OK 响应。

@Override
@Cacheable(value = TRANSPORT_LOCATIONS, cacheManager = CACHE_MANAGER, key = ROOT_METHOD_NAME)
public HttpResponse<String> getTransportsLocations(
        final LinkedHashMap<String, Object> bodyStructure,
        final String url)
        throws Exception {
    HttpResponse<String> response = requestSender.sendPostRequest(bodyStructure, url);

    if (response.statusCode() != OK_STATUS) {
        LOG.error(GET_TRANSPORT_LOCATION_BAD_REQUEST_ERROR_MESSAGE);
        Thread.sleep(FALLBACK_TIMEOUT);
        response = requestSender.sendPostRequest(bodyStructure, url);
    }
    return response;
}

你有什么想法,问题应该出在哪里?非常感谢。

标签: java.netspringspring-boot

解决方案


我认为您需要检查您发送的参数的差异,看起来 api 端返回错误请求。

此外,您可以尝试将repsonsebody 保存在一个html 文件中,这样更容易阅读响应信息。

顺便说一句,我注意到第二个调用的标题有“access-control-allow-origin :*”,

在 Springboot 中,您可以在 Controller 上使用 @CrossOrigin 到 CROS


推荐阅读