@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.