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


126

私はこのようにフォームからいくつかのパラメータを送信しています:

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としてオブジェクトを作成せずに、パラメーターをリストまたは配列にバインドする構文はありますか?

ありがとう


これは可能ではないと思います。HandlerMethodInvoker.resolveRequestParam唯一のコードは、最初の値を取得します
skaffman

6
春ブーツ):についてですmethod = RequestMethod.GETmethod = RequestMethod.POST?正常に.GET @RequestParam List<String> groupVal実行され?groupVal=kkk,ccc,mmmた場合(スプリングブート
バジル

回答:


76

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

myparam=myValue1&myparam=myValue2&myparam=myValue3

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


1
フォームをシリアル化してajaxでiを送信することでパラメーターを送信するため、順序に問題がある可能性があります(私の場合は非常に重要です)。「従来の」@ModelAttributeの方法を使用します。
Javi

UriTemplateを使用したこのソートマッピング、またはその他の方法でURIを構築する方法を知っていますか?(この種のリソースのクライアントの場合)。
Chomeh 2015年

:自分の質問に答える、それがUriTemplateは、RFC6570をサポートしていない春は、damnhandy実装を使用apears stackoverflow.com/questions/14153036/...
Chomeh

110

または、その方法で行うこともできます。

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

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

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

これは最も簡単な解決策です:)


4
それは順序を維持しますか?
アンドリュークック2012年

7
したがって、Spring 3.0では[]ではなく名前だけを使用することができました:@RequestParam(value = "myParam")String [] myParams
M Smith

3
ただし、@ MSmithの調査結果は共有しません。
垂れ下がる

2
List<String>これで入手できますか?次のようなJava Beanを取得することもできますList<MyBean>
Juzer Ali

3
パラメータ名からブラケットを削除できると思います。
theblang 2013年

19

ドナルフェローが言ったことを補足するだけで、@ RequestParamでListを使用できます。

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

それが役に立てば幸い!


12

バジルが質問自体へのコメントで言ったことをサブスクライブmethod = RequestMethod.GETする(使用できる場合)@RequestParam List<String> groupVal

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

API_URL?groupVal=kkk,ccc,mmm

11

これを(ハックな方法で)達成できる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'

これは、@ ModelAttributeを使用する場合とほとんど同じですが、唯一の違いは、paramに注釈が付けられていないことです。ラッパーを作成したくなかったからといって、@ ModelAttributeを避けたかったのです。私はstackoverflowのどこかを読んでいます(正確にどこにあるか思い出せません)@ModelAttribute注釈なしでコントローラメソッドにパラメータを追加すると(そしてそれはHttpRequest、HttpResponseのような特別なオブジェクトではありませんでした...)フレームワークはそれを次のように扱います@ModelAttributeで注釈が付けられている場合。そのため、これが真であった場合、これは、@ ModelAttributeを持っているのとまったく同じです。しかし、あなたの答えをありがとう。
Javi

4

コレクションをリクエストパラメータとして受け入れることはできますが、コンシューマ側では、コンマ区切りの値としてコレクションアイテムを渡す必要があることは明らかではありませんでした。

たとえば、サーバー側の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);
}

完全な例はここ見つけることができます、それが誰かの頭痛を救うことを願っています :)


-7

以下のようにチェックボックスを切り替えて非表示フィールドの値を変更します...

HTML:

<input type='hidden' value='Unchecked' id="deleteAll" name='anyName'>
<input type="checkbox"  onclick="toggle(this)"/> Delete All

脚本:

function toggle(obj) {`var $input = $(obj);
    if ($input.prop('checked')) {

    $('#deleteAll').attr( 'value','Checked');

    } else {

    $('#deleteAll').attr( 'value','Unchecked');

    }

}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.