从DTO填充查询参数

问题描述

是否有一种方法可以让Spring自动从DTO填充RestTemplate查询参数,就像它如何自动实例化响应DTO一样?

我想写一些类似的东西:

RequestDto request = new RequestDto();
request.setFoo("foo");
request.setBar("bar");

ResponseDto response = restTemplate.getForObject(
        "http://example.com/api",ResponseDto.class,request
);

代替:

ResponseDto response = restTemplate.getForObject(
        "http://example.com/api?foo={foo}&bar={bar}","foo","bar"
);

因为有许多大型DTO,需要大量的样板代码,所以必须与任何DTO更改保持同步。

春季4.3.25

解决方法

我不认为这是直接可能的。以下并非完全使用 DTO,但它确实让您无需手动形成 URL 字符串即可构建请求。您可以使用 Spring 的 UriComponentsBuilder 类。

UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl("http://example.com/api")
    .queryParam("foo","bar")
    // etc. ...
    .queryParam("bar","foo");

String result = restTemplate.getForObject(builder.toString(),String.class);

您可以遍历 DTO 并按照上述方式构建查询。或者没有 DTO,您可以使用 Map<String,String> 并对其进行循环。

Map<String,String> params = new HashMap<>();
params.put("foo","bar");

UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl("http://example.com/api");
for (Map.Entry<String,String> entry : params.entrySet()) {
    builder.queryParam(entry.getKey(),entry.getValue());
}
String result = restTemplate.getForObject(builder.toString(),String.class);

编辑:

正如下面建议的 crizzis,您可以使用 Spring Cloud OpenFeign 的 REST 客户端(来自 Feign @QueryMap support):

OpenFeign @QueryMap 注释支持将 POJO 用作 GET 参数映射。不幸的是,默认的 OpenFeign QueryMap 注释与 Spring 不兼容,因为它缺少 value 属性。

Spring Cloud OpenFeign 提供了一个等效的 @SpringQueryMap 注解,用于将 POJO 或 Map 参数注解为查询参数映射。

以您的问题为例:

public class RequestDto {
  private string foo;
  private string bar;
}
@FeignClient(name = "client",url = "http://example.com")
public interface FooTemplate {

    @GetMapping(path = "/api")
    String endpoint(@SpringQueryMap RequestDto requestDto);
}

,

你可以这样做-

UriComponentsBuilder builder = UriComponentsBuilder.fromUriString("http://example.com/api")
        .queryParam("foo","foo")
        .queryParam("bar","bar");

ResponseDto response = restTemplate.getForObject(
        builder.buildAndExpand(builder).toUriString(),ResponseDto.class);

可以在此处找到更详细的答案-RestTemplate: How to send URL and query parameters together

,

如何使用 Feign?它允许您像 Spring Controller 一样描述远程端点。这包括对查询参数 DTO 的支持。

查看示例 here

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...