从 DTO 填充查询参数
Populate query parameters from 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}",
ResponseDto.class,
"foo",
"bar"
);
因为有很多大型 DTO,需要大量样板代码,必须与任何 DTO 更改保持同步。
Spring 4.3.25
我不认为这是直接可能的。以下内容并未完全使用 DTO,但它确实允许您构建请求而无需手动形成 URL 字符串。您可以使用 Spring 的 UriComponentsBuilder class.
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's REST Client (from Feign @QueryMap support):
The OpenFeign @QueryMap annotation provides support for POJOs to be used as GET parameter maps. Unfortunately, the default OpenFeign QueryMap annotation is incompatible with Spring because it lacks a value property.
和
Spring Cloud OpenFeign provides an equivalent @SpringQueryMap annotation, which is used to annotate a POJO or Map parameter as a query parameter 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);
可以在这里找到更详细的答案-
使用 Feign 怎么样?它允许您像 Spring 控制器一样描述远程端点。这包括对查询参数 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}",
ResponseDto.class,
"foo",
"bar"
);
因为有很多大型 DTO,需要大量样板代码,必须与任何 DTO 更改保持同步。
Spring 4.3.25
我不认为这是直接可能的。以下内容并未完全使用 DTO,但它确实允许您构建请求而无需手动形成 URL 字符串。您可以使用 Spring 的 UriComponentsBuilder class.
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's REST Client (from Feign @QueryMap support):
The OpenFeign @QueryMap annotation provides support for POJOs to be used as GET parameter maps. Unfortunately, the default OpenFeign QueryMap annotation is incompatible with Spring because it lacks a value property.
和
Spring Cloud OpenFeign provides an equivalent @SpringQueryMap annotation, which is used to annotate a POJO or Map parameter as a query parameter 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);
可以在这里找到更详细的答案-
使用 Feign 怎么样?它允许您像 Spring 控制器一样描述远程端点。这包括对查询参数 DTO 的支持。
查看示例