RestTemplate 与正文一起获取

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

如何使用rest模板制作get with body?

基于以下问题:通过 JSON 中的 RestTemplate 进行 POST 请求,我尝试通过 HttpEntity 使用正文进行 GET (只需检查是否可能),但是 接收失败:

缺少必需的请求正文

对于 HttpMethod.POST: localhost:8080/test/post 正文已正确添加,但是对于 HttpMethod.GET localhost:8080/test/get 它没有映射。 我的代码如下:

@RestController
@SpringBootApplication
public class DemoApplication {

  public static void main(String[] args) {
    SpringApplication.run(DemoApplication.class, args);
  }

  private final RestTemplate restTemplate = new RestTemplate();

  @GetMapping("/test/{api}")
  public SomeObject test(@PathVariable("api") String api) {
    String input = "{\"value\":\"ok\"}";

    HttpHeaders headers = new HttpHeaders();
    headers.setContentType(MediaType.APPLICATION_JSON);
    HttpEntity<String> entity = new HttpEntity<>(input, headers);

    HttpMethod method = "get".equals(api) ? HttpMethod.GET : HttpMethod.POST;
    String url = "http://localhost:8080/" + api;
    return restTemplate.exchange(url, method, entity, SomeObject.class).getBody();
  }

  @GetMapping("/get")
  public SomeObject getTestApi(@RequestBody(required = false) SomeObject someObject) {
    return new SomeObject() {{ setValue(someObject != null ? "ok" : "error"); }};
  }

  @PostMapping("/post")
  public SomeObject postTestApi(@RequestBody(required = false) SomeObject someObject) {
    return new SomeObject() {{ setValue(someObject != null ? "ok" : "error"); }};
  }

  @Data
  public static class SomeObject {
    private String value;
  }

}

这里是带有完整示例的存储库:https://gitlab.com/bartekwichowski/git-with-body

我想知道,代码有什么问题? 还根据:带有请求正文的HTTP GET GET with body 是可能的,但这不是一个好的做法。

spring-boot resttemplate
4个回答
4
投票

我发现这个不记得在哪里了。这不是一个好的做法,但如果在您的环境中您没有其他机会:

private static final class HttpComponentsClientHttpRequestWithBodyFactory extends HttpComponentsClientHttpRequestFactory {
    @Override
    protected HttpUriRequest createHttpUriRequest(HttpMethod httpMethod, URI uri) {
        if (httpMethod == HttpMethod.GET) {
            return new HttpGetRequestWithEntity(uri);
        }
        return super.createHttpUriRequest(httpMethod, uri);
    }
}

private static final class HttpGetRequestWithEntity extends HttpEntityEnclosingRequestBase {
    public HttpGetRequestWithEntity(final URI uri) {
        super.setURI(uri);
    }

    @Override
    public String getMethod() {
        return HttpMethod.GET.name();
    }
}

当你得到你的restTemplate对象时

restTemplate.setRequestFactory(new HttpComponentsClientHttpRequestWithBodyFactory());

0
投票

我在 Spring 6.x 中遇到了同样的问题 - 在这种情况下,由 demian 提供的解决方案不再编译(因为 API 已更改)。不过我能够克服这个问题 - 而且这种情况下的解决方案并不复杂。

首先,必须直接添加 Apache HttpClient 作为依赖项:

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

然后,在创建

HttpComponentsClientHttpRequestFactory
实例时使用
RestTemplate
即可:

RestTemplate restTemplate = new RestTemplate(new HttpComponentsClientHttpRequestFactory());

0
投票

JdkClientHttpRequestFactory 可以修复它。

        var restTemplate = new RestTemplate(new JdkClientHttpRequestFactory());

该类内部依赖于java.net.http.HttpClient。


-2
投票

我对 RestTemplate 和 GET 也有同样的问题。

尝试切换到 Unirest,但这也不允许将 body 与 GET 方法一起使用。

将GET更改为POST成功。

在 Liberty 中部署后,从邮递员处拨打电话工作正常,正文确实被接受并生成了预期的响应。

我相信它与使用的嵌入式tomcat服务器有关。

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