绑定@RequestParam中的列表

Jav*_*avi 116 java data-binding collections spring spring-mvc

我以这种方式从表单发送一些参数:

myparam[0]     : 'myValue1'
myparam[1]     : 'myValue2'
myparam[2]     : 'myValue3'
otherParam     : 'otherValue'
anotherParam   : 'anotherValue' 
...
Run Code Online (Sandbox Code Playgroud)

我知道我可以通过添加一个参数来获得控制器方法中的所有参数

public String controllerMethod(@RequestParam Map<String, String> params){
    ....
}
Run Code Online (Sandbox Code Playgroud)

我想将参数myParam [](而不是其他的)绑定到列表或数组(保持索引顺序的任何东西),所以我尝试使用如下语法:

public String controllerMethod(@RequestParam(value="myParam") List<String> myParams){
    ....
}
Run Code Online (Sandbox Code Playgroud)

public String controllerMethod(@RequestParam(value="myParam") String[] myParams){
    ....
}
Run Code Online (Sandbox Code Playgroud)

但它们都没有约束myParams.即使我向地图添加了一个值,它也无法绑定参数:

public String controllerMethod(@RequestParam(value="myParam") Map<String, String> params){
    ....
}
Run Code Online (Sandbox Code Playgroud)

是否有任何语法将一些参数绑定到列表或数组而不必创建一个具有列表属性的@ModelAttribute对象?

谢谢

小智 107

或者你可以这样做:

public String controllerMethod(@RequestParam(value="myParam[]") String[] myParams){
    ....
}
Run Code Online (Sandbox Code Playgroud)

这适用于例如这样的表单:

<input type="checkbox" name="myParam[]" value="myVal1" />
<input type="checkbox" name="myParam[]" value="myVal2" />
Run Code Online (Sandbox Code Playgroud)

这是最简单的解决方案:)

  • 我只能在Spring 3.0中使用名称而不是[]:@RequestParam(value ="myParam")String [] myParams (7认同)
  • 这会保留订单吗? (4认同)
  • 不过,我不同意@MSmith的发现. (3认同)
  • 我想你可以从param名称中删除括号. (3认同)
  • 是否可以通过此获取`List <String>`.也可以获得像`List <MyBean>`这样的java bean (2认同)

axt*_*avt 70

数组@RequestParam用于绑定同名的几个参数:

myparam=myValue1&myparam=myValue2&myparam=myValue3
Run Code Online (Sandbox Code Playgroud)

如果你需要bind @ModelAttribute-style索引参数,我想你@ModelAttribute无论如何都需要.


小智 17

只是补充Donal Fellows所说的,你可以使用List和@RequestParam

public String controllerMethod(@RequestParam(value="myParam") List<ObjectToParse> myParam){
....
}
Run Code Online (Sandbox Code Playgroud)

希望能帮助到你!


ggr*_*ner 11

你可以通过hackish方式实现这一目的的一种方法是为它创建一个包装类List.像这样:

class ListWrapper {
     List<String> myList; 
     // getters and setters
}
Run Code Online (Sandbox Code Playgroud)

然后您的控制器方法签名将如下所示:

public String controllerMethod(ListWrapper wrapper) {
    ....
}
Run Code Online (Sandbox Code Playgroud)

如果您在请求中传递的集合名称与包装类的集合字段名称匹配,则无需使用@RequestParam@ModelAttribute注释,在我的示例中,您的请求参数应如下所示:

myList[0]     : 'myValue1'
myList[1]     : 'myValue2'
myList[2]     : 'myValue3'
otherParam    : 'otherValue'
anotherParam  : 'anotherValue'
Run Code Online (Sandbox Code Playgroud)


Jua*_*dán 8

订阅罗勒在问题本身的评论中说的内容(如果method = RequestMethod.GET可以使用)@RequestParam List<String> groupVal

然后,使用参数列表调用服务非常简单:

API_URL?groupVal=kkk,ccc,mmm
Run Code Online (Sandbox Code Playgroud)


Pét*_*res 6

对我来说,虽然您可以接受 Collection 作为请求参数并不明显,但在消费者方面,您仍然必须将集合项作为逗号分隔值传递

例如,如果服务器端 api 如下所示:

@PostMapping("/post-topics")
public void handleSubscriptions(@RequestParam("topics") Collection<String> topicStrings) {

    topicStrings.forEach(topic -> System.out.println(topic));
}
Run Code Online (Sandbox Code Playgroud)

下面这样直接将集合作为 RequestParam 传递给 RestTemplate会导致数据损坏

public void subscribeToTopics() {

    List<String> topics = Arrays.asList("first-topic", "second-topic", "third-topic");

    RestTemplate restTemplate = new RestTemplate();
    restTemplate.postForEntity(
            "http://localhost:8088/post-topics?topics={topics}",
            null,
            ResponseEntity.class,
            topics);
}
Run Code Online (Sandbox Code Playgroud)

相反,您可以使用

public void subscribeToTopics() {

    List<String> topicStrings = Arrays.asList("first-topic", "second-topic", "third-topic");
    String topics = String.join(",",topicStrings);

    RestTemplate restTemplate = new RestTemplate();
    restTemplate.postForEntity(
            "http://localhost:8088/post-topics?topics={topics}",
            null,
            ResponseEntity.class,
            topics);
}
Run Code Online (Sandbox Code Playgroud)

完整的例子可以在这里找到,希望它可以让某人头疼:)