我如何使用Spring RestTemplate发送数组参数?
这是在服务器端执行:
@RequestMapping(value = "/train", method = RequestMethod.GET)
@ResponseBody
public TrainResponse train(Locale locale, Model model, HttpServletRequest request,
@RequestParam String category,
@RequestParam(required = false, value = "positiveDocId[]") String[] positiveDocId,
@RequestParam(required = false, value = "negativeDocId[]") String[] negativeDocId)
{
...
}
这是我已经试过:
Map<String, Object> map = new HashMap<String, Object>();
map.put("category", parameters.getName());
map.put("positiveDocId[]", positiveDocs); // positiveDocs is String array
map.put("negativeDocId[]", negativeDocs); // negativeDocs is String array
TrainResponse response = restTemplate.getForObject("http://localhost:8080/admin/train?category={category}&positiveDocId[]={positiveDocId[]}&negativeDocId[]={negativeDocId[]}", TrainResponse.class, map);
以下是这显然是不正确的实际要求网址:
http://localhost:8080/admin/train?category=spam&positiveDocId%5B%5D=%5BLjava.lang.String;@4df2868&negativeDocId%5B%5D=%5BLjava.lang.String;@56d5c657`
一直在试图四处搜寻,但没有找到一个解决方案。 任何指针将不胜感激。
Spring的UriComponentsBuilder的伎俩也允许变量扩展。 假设你想传递的字符串作为参数“ATTR”的资源,而您只需要一个URI与路径变量数组:
UriComponents comp = UriComponentsBuilder.fromHttpUrl(
"http:/www.example.com/widgets/{widgetId}").queryParam("attr", "width",
"height").build();
UriComponents expanded = comp.expand(12);
assertEquals("http:/www.example.com/widgets/12?attr=width&attr=height",
expanded.toString());
否则,如果您需要定义应该是在运行时扩展一个URI,你不知道数组的大小提前,使用http://tools.ietf.org/html/rfc6570 UriTemplate与{?关键*}占位符,并与来自UriTemplate类展开https://github.com/damnhandy/Handy-URI-Templates 。
UriTemplate template = UriTemplate.fromTemplate(
"http://example.com/widgets/{widgetId}{?attr*}");
template.set("attr", Arrays.asList(1, 2, 3));
String expanded = template.expand();
assertEquals("http://example.com/widgets/?attr=1&attr=2&attr=3",
expanded);
对于非Java语言看https://code.google.com/p/uri-templates/wiki/Implementations 。
我最终通过收集循环构造URL。
Map<String, Object> map = new HashMap<String, Object>();
map.put("category", parameters.getName());
String url = "http://localhost:8080/admin/train?category={category}";
if (positiveDocs != null && positiveDocs.size() > 0) {
for (String id : positiveDocs) {
url += "&positiveDocId[]=" + id;
}
}
if (negativeDocId != null && negativeDocId.size() > 0) {
for (String id : negativeDocId) {
url += "&negativeDocId[]=" + id;
}
}
TrainResponse response = restTemplate.getForObject(url, TrainResponse.class, map);
试试这个
改变从你的要求映射
@RequestMapping(value = "/train", method = RequestMethod.GET)
至
@RequestMapping(value = "/train/{category}/{positiveDocId[]}/{negativeDocId[]}", method = RequestMethod.GET)
和你在restTemplate网址
变更网址如下格式
http://localhost:8080/admin/train/category/1,2,3,4,5/6,7,8,9
这里是我是如何实现的吧:
其余的控制器:
@ResponseBody
@RequestMapping(value = "/test", method = RequestMethod.GET)
public ResponseEntity<Response> getPublicationSkus(
@RequestParam(value = "skus[]", required = true) List<String> skus) {
...
}
请求:
List<String> skus = Arrays.asList("123","456","789");
Map<String, String> params = new HashMap<>();
params.put("skus", toPlainString(skus));
Response response = restTemplate.getForObject("http://localhost:8080/test?skus[]={skus}",
Response.class, params);
然后你只需要实现转换的方法List
或String[]
用逗号分隔中,例如一个普通字符串Java 8
会是这样的:
private static String toPlainString(List<String> skus) {
return skus.stream().collect(Collectors.joining(","));
}