【发布时间】:2019-04-02 23:31:35
【问题描述】:
问题与Spring's RestTemplate: complex object to query params有些不同 假设有一个请求以对象的形式接受一些参数:
@GetMapping("getRoute")
public ActionResult<Response> get(@Validated GetRequest req) {
//do some logic
}
请求本身如下所示:
public class GetRequest{
private String firstField;
private Long secondField;
private ComplexObject thirdField;
private static class ComplexObject{
private String subFirstField;
private Long subSecondField;
}
}
因此,当我从 RestTemplate 使用这个对象执行查询时,我想得到一个这样的 URI:
/getRoute?firstField=val&secondField=val&thirdField.subFirstField=val&thirdField.subSecondField=val
我该怎么做?对象绝对可以是任何东西。 更大的问题是如何将这样的 this 对象转换为 UriComponentsBuilder 的 MultiValueMap。
如果是 POST 请求,解决方案会很简单,但我需要它用于 GET。
我只知道Springfox库在生成Swagger API的时候就是用这种方式的,但是里面的逻辑太复杂了。 我的场景:
@SuppressWarnings("unchecked")
public <T> ActionResult<T> getAction(String relativeUrl, Class<T> responseType, @Nullable Object paramsObject) {
UriComponentsBuilder builder = createUriComponentsBuilder(relativeUrl, paramsObject);
final ApiErrorCode errorCode;
try {
ResponseEntity<ActionResult> responseEntity = this.restTemplate.getForEntity(builder.build().toUri(), ActionResult.class);
ActionResult responseBody = responseEntity.getBody();
if (!Objects.requireNonNull(responseBody).isSuccess()) {
return responseBody;
}
return ActionResult.ok(this.mapper.convertValue(responseBody.getValue(), responseType));
} catch (RestClientException | HttpMessageNotReadableException e) {
errorCode = ApiErrorCode.API_CONNECTION_ERROR;
} catch (Exception e) {
errorCode = ApiErrorCode.INTERNAL_SERVER_ERROR;
}
return ActionResult.fail(errorCode);
}
private UriComponentsBuilder createUriComponentsBuilder(String relativeUrl, @Nullable Object object) {
String url = this.baseUrl;
if (StringUtils.hasText(relativeUrl)) {
url += relativeUrl;
}
UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(url);
if (object != null) {
builder.queryParams(this.convertToMultiValueMap(object));
}
return builder;
}
private MultiValueMap<String, String> convertToMultiValueMap(Object object) {
//todo object to params
}
【问题讨论】:
-
你用 @ModelAttribute 注释了吗?另外,您为什么不将其设置为 RequestBody 并使用 POST 之类的东西?
-
@RoddyoftheFrozenPeas 我不需要 ModelAttribute。我使用该对象是因为使用它比使用 RequestParam 注释更方便。为什么要获取?它具有源自方法语义的所有优点(幂等性、安全性和缓存)
-
只有以这种方式实现才能获得幂等性和缓存。不知道你说的安全是什么意思。无论哪种方式,我都将其解释为“我想要”。无论如何,既然各种值只是美化的请求参数,那么,只需使用
queryParams方法来传递各种值。 -
@RoddyoftheFrozenPeas 问题是如何从对象中获取queryParams,不要手动将对象映射到这些参数
标签: java spring resttemplate