Mengikat daftar di @RequestParam

127

Saya mengirimkan beberapa parameter dari formulir dengan cara ini:

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

Saya tahu saya bisa mendapatkan semua parameter dalam metode pengontrol dengan menambahkan parameter seperti

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

Saya ingin mengikat parameter myParam [] (bukan yang lain) ke daftar atau larik (apa pun yang menjaga urutan indeks), jadi saya sudah mencoba dengan sintaks seperti:

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

dan

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

tapi tidak satupun dari mereka mengikat myParams. Bahkan ketika saya menambahkan nilai ke peta, itu tidak dapat mengikat parameter:

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

Apakah ada sintaks untuk mengikat beberapa params ke daftar atau larik tanpa harus membuat objek sebagai @ModelAttribute dengan atribut daftar di dalamnya?

Terima kasih

Javi
sumber
Saya rasa ini tidak mungkin. Kode dalam HandlerMethodInvoker.resolveRequestParamhanya mendapatkan nilai pertama
skaffman
6
( Spring Boot ): Apakah tentang method = RequestMethod.GETatau method = RequestMethod.POST? Jika .GET @RequestParam List<String> groupValdipenuhi dari ?groupVal=kkk,ccc,mmmberhasil ( Spring Boot )
basil

Jawaban:

77

Array in @RequestParamdigunakan untuk mengikat beberapa parameter dengan nama yang sama:

myparam=myValue1&myparam=myValue2&myparam=myValue3

Jika Anda perlu mengikat @ModelAttributeparameter indeks gaya, saya rasa Anda @ModelAttributetetap membutuhkannya .

axtavt
sumber
1
mungkin ada masalah dengan pesanan (yang sangat penting untuk disimpan dalam kasus saya) karena saya mengirim parameter dengan membuat serialisasi formulir dan mengirim saya dengan ajax. Saya akan menggunakan cara @ModelAttribute "tradisional".
Javi
Apakah Anda kebetulan mengetahui cara membuat URI dengan pemetaan semacam ini dengan UriTemplate, atau cara lain? (untuk klien sumber daya semacam ini).
Chomeh
Menjawab pertanyaan saya sendiri, tampaknya musim semi UriTemplate tidak mendukung RFC6570, gunakan implementasi sialan: stackoverflow.com/questions/14153036/…
Chomeh
110

Atau Anda bisa melakukannya seperti itu:

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

Itu berfungsi misalnya untuk formulir seperti ini:

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

Ini adalah solusi paling sederhana :)

Bernhard
sumber
4
apakah itu menjaga ketertiban?
andrew cooke
7
Saya hanya bisa menggunakan nama daripada [] di Spring 3.0 dengan demikian: @RequestParam (value = "myParam") String [] myParams
M Smith
3
Saya tidak membagikan temuan @MSmith.
terkulai
2
Apakah mungkin untuk mendapatkannya List<String>melalui ini. Juga dimungkinkan untuk mendapatkan biji jawa sepertiList<MyBean>
Juzer Ali
3
Saya pikir Anda dapat menghapus tanda kurung dari nama param.
theblang
19

Hanya melengkapi apa yang dikatakan Donal Fellows, Anda dapat menggunakan List dengan @RequestParam

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

Semoga membantu!

Jorge Peres
sumber
12

Berlangganan apa yang dikatakan basil dalam komentar untuk pertanyaan itu sendiri, jika method = RequestMethod.GETAnda bisa menggunakan @RequestParam List<String> groupVal.

Kemudian memanggil layanan dengan daftar params sesederhana:

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

Salah satu cara Anda bisa melakukannya (dengan cara hackish) adalah dengan membuat kelas pembungkus untuk List. Seperti ini:

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

Kemudian tanda tangan metode pengontrol Anda akan terlihat seperti ini:

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

Tidak perlu menggunakan anotasi @RequestParamatau @ModelAttributejika nama koleksi yang Anda berikan dalam permintaan cocok dengan nama bidang koleksi kelas pembungkus, dalam contoh saya, parameter permintaan Anda akan terlihat seperti ini:

myList[0]     : 'myValue1'
myList[1]     : 'myValue2'
myList[2]     : 'myValue3'
otherParam    : 'otherValue'
anotherParam  : 'anotherValue'
gerimis
sumber
Ini hampir sama dengan menggunakan @ModelAttribute, satu-satunya perbedaan adalah param tidak dianotasi. Saya ingin menghindari @ModelAttribute hanya karena saya tidak ingin membuat pembungkus. Saya membaca di suatu tempat di stackoverflow (saya tidak ingat di mana tepatnya) bahwa jika Anda menambahkan param dalam metode pengontrol tanpa anotasi @ModelAttribute (dan itu bukan objek khusus seperti HttpRequest, HttpResponse ...) kerangka kerja memperlakukannya sebagai jika dianotasi dengan @ModelAttribute. Jadi jika itu benar, ini persis seperti memiliki @ModelAttribute. Tapi terima kasih atas jawaban Anda.
Javi
4

Tidak jelas bagi saya bahwa meskipun Anda dapat menerima Collection sebagai parameter permintaan, tetapi di sisi konsumen Anda masih harus memasukkan item koleksi sebagai nilai yang dipisahkan koma .

Misalnya jika api sisi server terlihat seperti ini:

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

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

Meneruskan koleksi secara langsung ke RestTemplate sebagai RequestParam seperti di bawah ini akan mengakibatkan kerusakan data

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

Sebagai gantinya Anda bisa menggunakan

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

Contoh lengkapnya dapat ditemukan di sini , semoga bisa menyelamatkan seseorang dari sakit kepala :)

Péter Veres
sumber
-7

Ubah nilai bidang tersembunyi dengan kotak centang beralih seperti di bawah ini ...

HTML:

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

Naskah:

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

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

    } else {

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

    }

}
Khomeni
sumber