Пов’язування списку в @RequestParam


127

Я надсилаю деякі параметри з форми таким чином:

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. Навіть коли я додаю значення до карти, він не може прив’язати парами:

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

Чи є синтаксис, який прив'язує деякі параметри до списку чи масиву, не створюючи об’єкт як @ModelAttribute з атрибутом списку в ньому?

Дякую


Я не думаю, що це можливо. Код HandlerMethodInvoker.resolveRequestParamлише коли-небудь отримує перше значення
skaffman

6
( Весняний черевик ): Це близько method = RequestMethod.GETчи method = RequestMethod.POST? Якщо .GET @RequestParam List<String> groupValвиконано з ?groupVal=kkk,ccc,mmmуспіху ( Весняний черевик )
базилік

Відповіді:


77

Масиви в @RequestParamвикористовуються для прив'язки кількох однойменних параметрів:

myparam=myValue1&myparam=myValue2&myparam=myValue3

Якщо вам потрібно прив’язати @ModelAttributeпараметри, індексовані в стилі, я думаю, вам це @ModelAttributeвсе одно потрібно .


1
можуть бути проблеми з замовленням (що дуже важливо зберегти в моєму випадку), оскільки я надсилаю параметри шляхом серіалізації форми та надсилання i з ajax. Я буду використовувати "традиційний" @ModelAttribute спосіб.
Хаві

Чи трапляється вам знати, як побудувати URI за допомогою подібного зіставлення за допомогою UriTemplate або іншим способом? (для клієнта такого роду ресурсів).
Хоме

Відповідаючи на мій власний питання, apears пружини UriTemplate не підтримує RFC6570, використовуйте damnhandy реалізації: 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
це зберігає порядок?
andrew cooke

7
Я зміг використовувати лише ім’я, а не [] у Spring 3.0 таким чином: @RequestParam (value = "myParam") String [] myParams
M Smith

3
Я не поділяю висновки @MSmith.
droope

2
Чи можна отримати List<String>через це. Також можна отримати квасоля java на зразокList<MyBean>
Juzer Ali

3
Я думаю, ви можете зняти дужки з назви парам.
theblang

19

Щойно доповнюючи те, що сказали стипендіати, ви можете скористатися списком за допомогою @RequestParam

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

Сподіваюся, це допомагає!


12

Підписавшись, що сказав Василь у коментарі до самого питання, якщо method = RequestMethod.GETви можете використовувати @RequestParam List<String> groupVal.

Тоді викликати службу зі списком парам так само просто:

API_URL?groupVal=kkk,ccc,mmm

11

Один із способів, який ви могли б досягти цього (хакітським способом) - створити клас обгортки для 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, різниця лише в тому, що параметр не коментується. Я хотів уникати @ModelAttribute лише тому, що не хотів створювати обгортку. Я читав десь у stackoverflow (я не пам'ятаю, де саме), що якщо ви додасте парам у методі контролера без анотації @ModelAttribute (а це не був спеціальний об'єкт, як HttpRequest, HttpResponse ...), рамки трактують це як якби це було помічено за допомогою @ModelAttribute. Тож якщо це було правдою, це точно так, як мати @ModelAttribute. Але дякую за вашу відповідь.
Хаві

4

Мені не було очевидно, що хоч ви можете прийняти колекцію як параметр запиту, але з боку споживача вам все одно потрібно передавати елементи колекції у вигляді розділених комами значень .

Наприклад, якщо api на сервері виглядає так:

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

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

Безпосереднє передання колекції до RestTemplate як RequestParam, як показано нижче, призведе до пошкодження даних

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

    }

}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.