web-dev-qa-db-ja.com

@RequestParamでリストをバインドする

この方法でフォームからいくつかのパラメーターを送信しています。

myparam[0]     : 'myValue1'
myparam[1]     : 'myValue2'
myparam[2]     : 'myValue3'
otherParam     : 'otherValue'
anotherParam   : 'anotherValue' 
...

次のようなパラメーターを追加することで、コントローラーメソッドのすべてのパラメーターを取得できることを知っています。

public String controllerMethod(@RequestParam Map<String, String> params){
    ....
}

パラメータmyParam [](他のパラメータではない)をリストまたは配列(インデックスの順序を保持するもの)にバインドしたいので、次のような構文で試しました。

public String controllerMethod(@RequestParam(value="myParam") List<String> myParams){
    ....
}

そして

public String controllerMethod(@RequestParam(value="myParam") String[] myParams){
    ....
}

しかし、いずれもmyParamsをバインドしていません。マップに値を追加しても、paramsをバインドできません:

public String controllerMethod(@RequestParam(value="myParam") Map<String, String> params){
    ....
}

リスト属性を持つオブジェクトを@ModelAttributeとして作成することなく、いくつかのパラメーターをリストまたは配列にバインドする構文はありますか?

ありがとう

112
Javi

@RequestParamの配列は、同じ名前のいくつかのパラメーターをバインドするために使用されます。

myparam=myValue1&myparam=myValue2&myparam=myValue3

@ModelAttributeスタイルのインデックス付きパラメーターをバインドする必要がある場合は、とにかく@ModelAttributeが必要だと思います。

68
axtavt

または、そのようにすることができます:

public String controllerMethod(@RequestParam(value="myParam[]") String[] myParams){
    ....
}

これは、たとえば次のようなフォームで機能します。

<input type="checkbox" name="myParam[]" value="myVal1" />
<input type="checkbox" name="myParam[]" value="myVal2" />

これは最も簡単なソリューションです:)

104
Bernhard

Donal Fellowsが言ったことを補足するだけで、@ RequestParamでListを使用できます。

public String controllerMethod(@RequestParam(value="myParam") List<ObjectToParse> myParam){
....
}

それが役に立てば幸い!

16
Jorge Peres

これを達成する1つの方法(ハック的な方法)は、Listのラッパークラスを作成することです。このような:

class ListWrapper {
     List<String> myList; 
     // getters and setters
}

コントローラーメソッドのシグネチャは次のようになります。

public String controllerMethod(ListWrapper wrapper) {
    ....
}

リクエストで渡すコレクション名がラッパークラスのコレクションフィールド名と一致する場合、@RequestParamまたは@ModelAttributeアノテーションを使用する必要はありません。私の例では、リクエストパラメータは次のようになります。

myList[0]     : 'myValue1'
myList[1]     : 'myValue2'
myList[2]     : 'myValue3'
otherParam    : 'otherValue'
anotherParam  : 'anotherValue'
10
ggreiner

method = RequestMethod.GET@RequestParam List<String> groupValを使用できる場合、質問自体へのコメントでbasilが言ったことを購読します。

次に、paramsのリストを使用してサービスを呼び出すのは次のように簡単です。

API_URL?groupVal=kkk,ccc,mmm
7
Juangui Jordán

コレクションを要求パラメーターとして受け入れることはできますが、コンシューマー側ではコレクション項目をコンマ区切り値として渡す必要があることは私には明らかではありませんでした

たとえば、サーバー側のAPIが次のようになっている場合:

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

    topicStrings.forEach(topic -> System.out.println(topic));
}

のような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);
}

代わりに使用できます

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

完全な例はここにあります 、頭痛の種を救うことを願っています:)

2
Péter Veres