Конечная точка Spring Boot Controller и глубокий доступ ModelAttribute
Я хотел бы знать, как получить доступ к глубокому атрибуту класса коллекции в запросе GET. Моя конечная точка отображает мои строки запроса с помощью аннотации @ModelAttribute:
При условии:
public class MyEntity
{
Set<Item> items;
Integer status;
// getters setters
}
public class Item
{
String name;
// getters setters
}
И мой запрос GET: localhost/entity /? Status=0&items[0].name=Garry
Производит ниже поведение?
@RequestMapping(path = "/entities", method = RequestMethod.GET)
public List<MyEntity> findBy(@ModelAttribute MyEntity entity) {
// entity.getItems() is empty and an error is thrown: "Property referenced in indexed property path 'items[0]' is neither an array nor a List nor a Map."
}
Должны ли мои "элементы" быть массивом, списком или картой? Если так, есть ли альтернативы, чтобы продолжать использовать как Set?
1 ответ
Похоже, есть какая-то проблема с Set<Item>
,
Если вы хотите использовать Set для items
Коллекцию нужно инициализировать и добавить несколько элементов:
например, вот так:
public class MyEntity {
private Integer status;
private Set<Item> items;
public MyEntity() {
this.status = 0;
this.items = new HashSet<>();
this.items.add(new Item());
this.items.add(new Item());
}
//getters setters
}
но тогда вы сможете установить только значения этих 2 пунктов:
Это будет работать: http://localhost:8081/map?status=1&items[0].name=asd&items[1].name=aaa
Это не будет работать: http://localhost:8081/map?status=1&items[0].name=asd&items[1].name=aaa&items[2].name=aaa
он скажет: Invalid property 'items[2]' of bean class MyEntity.
Однако если вы переключитесь на список:
public class MyEntity {
private Integer status;
private List<Item> items;
}
оба URL-адреса отображаются без необходимости инициализации чего-либо и для различного количества элементов.
обратите внимание, что я не использовал @ModelAttribute
, просто установите класс в качестве параметра
@GetMapping("map")//GetMapping is just a shortcut for RequestMapping
public MyEntity map(MyEntity myEntity) {
return myEntity;
}
Не по теме
Отображение сложного объекта в запросе Get звучит для меня как запах кода. Обычно методы Get используются для получения / чтения данных, а параметры url используются для указания значений, которые следует использовать для фильтрации данных, которые должны быть прочитаны.
если вы хотите вставить или обновить некоторые данные, используйте POST, PATCH или PUT и поместите сложный объект, который вы хотите вставить / обновить, в тело запроса как JSON(вы можете отобразить это в Spring Controller с помощью @RequestBody
).