@RequestParam'da bir liste bağlama


127

Bir formdan bazı parametreleri şu şekilde gönderiyorum:

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

Denetleyici yöntemindeki tüm parametreleri aşağıdaki gibi bir parametre ekleyerek elde edebileceğimi biliyorum.

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

MyParam [] parametrelerini (diğerlerini değil) bir listeye veya diziye (dizin sırasını koruyan herhangi bir şey) bağlamak istiyorum, bu nedenle şöyle bir sözdizimi kullanmayı denedim:

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

ve

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

ancak hiçbiri myParam'ları bağlamaz. Haritaya bir değer eklediğimde bile parametreleri bağlayamıyor:

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

Bir liste özniteliği olan @ ModelAttribute olarak bir nesne oluşturmak zorunda kalmadan bazı parametreleri bir listeye veya diziye bağlamak için herhangi bir sözdizimi var mı?

Teşekkürler


Bunun mümkün olduğunu sanmıyorum. Kod HandlerMethodInvoker.resolveRequestParamyalnızca ilk değeri alır
skaffman

6
( Spring Boot ): method = RequestMethod.GETYa hakkında mı method = RequestMethod.POST? Eğer .GET @RequestParam List<String> groupValkarşılanmış ?groupVal=kkk,ccc,mmmbaşarıyla ( Bahar Boot )
fesleğen

Yanıtlar:


77

İçindeki diziler @RequestParam, aynı ada sahip birkaç parametreyi bağlamak için kullanılır:

myparam=myValue1&myparam=myValue2&myparam=myValue3

@ModelAttribute-Stilli indekslenmiş parametreleri bağlamanız gerekiyorsa , sanırım @ModelAttributeyine de ihtiyacınız var .


1
Siparişle ilgili sorunlar olabilir (benim durumumda saklamak çok önemlidir) çünkü parametreleri bir formu seri hale getirip ajax ile i göndererek gönderiyorum. "Geleneksel" @ModelAttribute yolunu kullanacağım.
Javi

UriTemplate ile bu türden bir eşleme veya başka bir yolla bir URI'nin nasıl oluşturulacağını biliyor musunuz? (bu tür bir kaynağın müşterisi için).
Chomeh

Kendi sorumu yanıtlarken, UriTemplate yayının RFC6570'i desteklemediğini gösteriyor, lanet olası uygulamayı kullanın: stackoverflow.com/questions/14153036/…
Chomeh

110

Ya da sadece şu şekilde yapabilirsiniz:

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

Bu, örneğin aşağıdaki gibi formlarda işe yarar:

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

Bu en basit çözüm :)


4
bu düzeni koruyor mu?
Andrew cooke

7
İlkbahar 3.0'da [] yerine yalnızca adı kullanabildim, böylece: @RequestParam (value = "myParam") String [] myParams
M Smith

3
Yine de @MSmith'in bulgularını paylaşmıyorum.
droope

2
Bununla elde etmek mümkün mü List<String>? Ayrıca bir java fasulyesi elde etmek de mümkünList<MyBean>
Juzer Ali

3
Parantez adındaki parantezleri kaldırabileceğinizi düşünüyorum.
theblang

19

Donal Fellows'un söylediklerini tamamlayarak Listeyi @RequestParam ile kullanabilirsiniz.

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

Umarım yardımcı olur!


12

Fesleğenin bir yorumda söylediklerine abone olmak, eğer method = RequestMethod.GETkullanabilirseniz , sorunun kendisine @RequestParam List<String> groupVal.

O zaman servisi parametrelerin listesiyle aramak kadar basit:

API_URL?groupVal=kkk,ccc,mmm

10

Bunu başarmanın bir yolu (hilekar bir şekilde) için bir sarmalayıcı sınıfı oluşturmaktır List. Bunun gibi:

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

Daha sonra denetleyici yöntemi imzanız şöyle görünür:

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

İstekte ilettiğiniz koleksiyon adı, sarmalayıcı sınıfının koleksiyon alanı adıyla eşleşiyorsa @RequestParamveya @ModelAttributeek açıklamayı kullanmaya gerek yoktur , örneğimde istek parametreleriniz şöyle görünmelidir:

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

Bu, @ModelAttribute kullanmakla neredeyse aynıdır, tek fark, paramın açıklamalı olmamasıdır. @ ModelAttribute'tan kaçınmak istedim çünkü bir sarmalayıcı oluşturmak istemedim. Stackoverflow'da bir yerde okudum (tam olarak nerede olduğunu hatırlayamıyorum) denetleyici yöntemine @ModelAttribute ek açıklaması olmadan bir param eklerseniz (ve bu HttpRequest, HttpResponse gibi özel bir nesne değildi ...) @ ModelAttribute ile açıklanmışsa. Yani eğer bu doğruysa, bu tam olarak @ModelAttribute'a sahip olmak gibidir. Ama cevabın için teşekkürler.
Javi

4

Bir Koleksiyonu bir istek parametresi olarak kabul edebilecek olsanız da, tüketici tarafında hala koleksiyon öğelerini virgülle ayrılmış değerler olarak geçirmeniz gerektiği bana açık değildi .

Örneğin, sunucu tarafı api şöyle görünüyorsa:

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

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

Bir koleksiyonun RestTemplate'e aşağıdaki gibi bir RequestParam olarak doğrudan aktarılması veri bozulmasına neden olur

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

Bunun yerine kullanabilirsiniz

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

Tam örnek burada bulunabilir , umarım birini baş ağrısından kurtarır :)


-7

Gizli alan değerini aşağıdaki gibi onay kutusu geçişiyle değiştirin ...

HTML:

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

Senaryo:

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

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

    } else {

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

    }

}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.