Spring Boot 3.4.0 损坏的 HTTP 接口

问题描述 投票:0回答:1

我使用的是最新版本的 Spring Boot 3.3.6,HTTP 接口如下:

    @Bean
    public RestRepositoryGsUser restRepositoryGsUser(
            @NonNull @Value("${gsrest.url}") String gsrestUrl) throws URISyntaxException {

        RestClient restClient = RestClient.builder().baseUrl(new URI(gsrestUrl)).build();

        HttpServiceProxyFactory factory = HttpServiceProxyFactory.builder()
                .exchangeAdapter(RestClientAdapter.create(restClient)).build();

        return factory.createClient(RestRepositoryGsUser.class);
    }

RestRepositoryUser.class 上有以下内容

public interface RestRepositoryGsUser {

    @GetExchange("/gsrest/clientPf-data")
    public ResponseEntity<List<ClientPf>> findAllPortfolios(
            @RequestHeader("gsrest-version") String version,
            @RequestHeader("gsrest-requesterId") String requesterId,
            @RequestHeader("gsrest-invocationContext") String invocationContext);
}

在我的服务代码中我像这样使用它

@Log4j2
@Service
@RequiredArgsConstructor
public class ServicePortfolio {

    private final RestRepositoryGsUser restRepositoryPortfolio;

    public List<ClientPf> findAllPortfolios() {

        ResponseEntity<List<ClientPf>> response =
                restRepositoryPortfolio.findAllPortfolios("1.0", "maydaylocal", "maydaylocal");
        log.info("FindAllPortfolios: response from GSRest " + response.getStatusCode());
        return response.getBody();
    }
}

当我迁移到 Spring boot 3.4.0 时,我相应地更新了我的 http 内容的依赖关系

        <dependency>
            <groupId>org.apache.httpcomponents.client5</groupId>
            <artifactId>httpclient5</artifactId>
        </dependency>

通过测试,看起来我所有的 GET 请求都不再起作用,我面临一个奇怪的行为:

  • 我在第一个 get 请求上收到了 401(很奇怪,通常对于 401,我应该从我的服务器接收一个 JSON(它是这样工作的),但这里我有一个带有空的 401正文,就像 401 不是来自我的服务器一样...)
  • 然后我超时了:o

我测试了使用新参数“spring.http.client.factory”。默认情况下,据我了解,它使用“http-components”。

添加到这个新参数中,我还尝试修改我的 RestClient 以使用 RestTemplate 代替,这是我发现的:

使用 RestTemplate 进行测试

  • 带有 http 组件的 RestTemplate:可以工作,但性能看起来被破坏了(加载一点 json 需要 15 秒)-> 当我发送垃圾邮件请求时没有超时
  • RestTemplate 很简单:可以工作,但性能看起来被破坏了(加载一点 json 需要 17 秒)-> 当我发送垃圾邮件请求时没有超时
  • 带有 jdk 的 RestTemplate:可以工作,但性能看起来被破坏了(加载一点 json 需要 19 秒)-> 当我发送垃圾邮件请求时没有超时

使用 RestClient 进行测试:

  • 带有http组件的RestClient:不工作(当我发送垃圾邮件时超时)
  • RestTemplate 简单:不工作(当我发送垃圾邮件时超时)
  • 带有jdk的RestTemplate:不工作(当我发送垃圾邮件时超时)
spring spring-boot http interface apache-httpcomponents
1个回答
0
投票

好的,找到解决方案了。这是我发现的:

我在我的 HTTP 接口上调用 http 端点。所以我认为这段代码(在 Spring 补丁说明中提供)对我来说没有用:

    public HttpComponentsClientHttpRequestFactoryBuilder httpComponentsClientHttpRequestFactoryBuilder() {
    return ClientHttpRequestFactoryBuilder.httpComponents().withDefaultRequestConfigCustomizer(
            (builder) -> builder.setProtocolUpgradeEnabled(false));
    }

所以,事实并非如此:无论它是 HTTP 还是 HTTPS 端点,我都必须声明它。 (不确定是否正常)。我在服务器端没有看到 401,因为该请求之前被代理阻止了。话虽这么说,我仍然不明白为什么我有一些超时,但看起来也已经解决了。

而且,我必须在我的 bean 配置中强制使用新功能:

        RestClient restClient = RestClient.builder().baseUrl(gsrestUrl)
            .requestFactory(httpComponentsClientHttpRequestFactoryBuilder().build()) // this line
            .defaultHeaders(header -> {
                header.setAccept(Arrays.asList(MediaType.APPLICATION_JSON));
                header.set("gsrest-requesterId", "mayday");
                header.set("gsrest-invocationContext", "mayday");
                header.set(HttpHeaders.AUTHORIZATION, "Basic " + Base64.getEncoder()
                        .encodeToString((gsrestUser + ":" + gsrestPassword).getBytes()));
            }).build();

我希望它可以帮助一些跟我一样的人!

© www.soinside.com 2019 - 2024. All rights reserved.