Привязка списка в @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');
}
}