Конечная точка 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).

Другие вопросы по тегам