3

如何使用 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);

以下是明显不正确的实际请求 URL:

http://localhost:8080/admin/train?category=spam&positiveDocId%5B%5D=%5BLjava.lang.String;@4df2868&negativeDocId%5B%5D=%5BLjava.lang.String;@56d5c657`

一直在尝试四处搜索,但找不到解决方案。任何指针将不胜感激。

4

4 回答 4

10

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,并且您事先不知道数组的大小,请使用https://www.rfc-editor.org/rfc/rfc6570 UriTemplate with {?key*} 占位符并使用来自https://github.com/damnhandy/Handy-URI-Templates的 UriTemplate 类对其进行扩展 。

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

于 2013-06-06T06:53:38.390 回答
1

我最终通过遍历集合来构建 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);
于 2013-03-14T07:38:00.337 回答
0

试试这个

更改您的请求映射

@RequestMapping(value = "/train", method = RequestMethod.GET)

 @RequestMapping(value = "/train/{category}/{positiveDocId[]}/{negativeDocId[]}", method = RequestMethod.GET)

和你在 restTemplate 中的 URL

以以下给定格式更改 URl

http://localhost:8080/admin/train/category/1,2,3,4,5/6,7,8,9
于 2013-01-04T09:14:26.120 回答
0

这是我实现它的方法:

REST 控制器:

@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);

然后你只需要实现一个方法,将 theList或 the转换String[]为用逗号分隔的普通字符串,例如 inJava 8将是这样的:

private static String toPlainString(List<String> skus) {
    return skus.stream().collect(Collectors.joining(","));
}
于 2019-02-22T13:23:13.267 回答