我有一个带有方法的Spring Boot 2服务
@RequestMapping(path = "/usable/search")
public List<Provider> findUsable(
@RequestParam(name = "country-id", required = false) Integer countryId,
@RequestParam(name = "network-ids[]", required = false) List<Integer> networkIds,
@RequestParam(name = "usages[]") Set<Usage> usages)
我想从另一个Spring Boot服务中调用该服务。为此我
HttpHeaders httpHeaders = new HttpHeaders();
httpHeaders.setContentType(MediaType.APPLICATION_JSON);
val response =
restTemplate.exchange(
"http://castor-v2/providers/usable/search?network-ids[]={0}&usages[]={1}",
HttpMethod.GET,
new HttpEntity<Long>(httpHeaders),
new ParameterizedTypeReference<List<Provider>>() {},
Collections.singletonList(networkId),
Collections.singleton(Usage.MESSAGE_DELIVERY));
这会生成一个类似search?network-ids[]=[428]&usages[]=[MESSAGE_DELIVERY]
的http请求,该请求是错误的(服务器用org.springframework.web.method.annotation.MethodArgumentTypeMismatchException: Failed to convert value of type 'java.lang.String' to required type 'java.util.List'; nested exception is java.lang.NumberFormatException: For input string: "[573]"
轰炸了);正确的应该是search?network-ids[]=77371&usages[]=MESSAGE_DELIVERY
。
很可能URI模板错误。应该如何与Java集合一起使用?
更新:我创建了一个没有括号的新api端点,并按照@vatsal的建议使用了UriComponentsBuilder
。
答案 0 :(得分:1)
您不能将对象作为请求参数传递。请求参数是String到String的多值映射。如果您想将用法作为字符串传递,则可以创建这样的方法
@RequestMapping(path = "/usable/search")
public List<Provider> findUsable(
@RequestParam(name = "country-id", required = false) Integer countryId,
@RequestParam(name = "networkIds", required = false) List<Integer> networkIds,
@RequestParam(name = "usages") Set<String> usages)
致电此服务
http://castor-v2/providers/usable/search?networkIds=0&networkIds=1&usages=usages1&usages=usages2
答案 1 :(得分:1)
它可能会将singletonList转换为字符串。其中将包括块括号。 因此,您可以预先将列表转换为字符串,也可以创建自己的列表实现,该实现具有to字符串方法,该方法将值转换为逗号分隔的列表。
答案 2 :(得分:1)
要轻松操纵URL /路径/参数/等,可以使用Spring的UriComponentsBuilder类。手动连接字符串比较干净,它会为您处理URL编码:
使用RestTemplate进行此操作的简单代码如下:
HttpHeaders httpHeaders = new HttpHeaders();
httpHeaders.setContentType(MediaType.APPLICATION_JSON);
String url = "http://castor-v2/providers/usable/search";
UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(url)
.queryParam("country-id", countryId)
.queryParam("network-ids[]", networkId)
.queryParam("usages[]", Usage.MESSAGE_DELIVERY);
HttpEntity<?> entity = new HttpEntity<>(httpHeaders);
HttpEntity<String> response = restTemplate.exchange(
builder.toUriString(),
HttpMethod.GET,
entity,
String.class);
这应该可以解决您的查询。另外,请确保将“用法”作为字符串传递。如果您仍要继续使用Usage作为对象,则可以使用RequestBody代替RequestParam并将其作为Body传递给POST调用。