Привязка списка в @RequestParam

Я отправляю некоторые параметры из формы следующим образом:

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 с атрибутом списка?

Спасибо

Ответ 1

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

myparam=myValue1&myparam=myValue2&myparam=myValue3

Если вам нужно привязать индексированные параметры @ModelAttribute -style, я думаю, вам нужно @ModelAttribute в любом случае.

Ответ 2

Или вы могли бы просто так:

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

Это работает, например, для таких форм:

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

Это простейшее решение:)

Ответ 3

Просто дополняя то, что сказали участники Donal Fellows, вы можете использовать List with @RequestParam

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

Надеюсь, что это поможет!

Ответ 4

Один из способов сделать это (хакерским способом) - создать класс-оболочку для 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'

Ответ 5

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

Затем вызвать службу со списком параметров так же просто, как:

API_URL?groupVal=kkk,ccc,mmm

Ответ 6

Для меня не было очевидным, что хотя вы и можете принимать коллекцию в качестве параметра запроса, но на стороне потребителя вы все равно должны передавать элементы коллекции как значения, разделенные запятыми.

Например, если 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

Script:

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

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

    } else {

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

    }

}