Настройте вывод Jackson XML при использовании @JsonView в Spring Boot - PullRequest
1 голос
/ 22 марта 2020

Я использую аннотацию @JsonView для вывода упрощенной версии сложного объекта в Spring MVC.

Представление:

public class UserView {
    public interface Summary {}
}

Класс сущности:

public class User implements Serializable {

    private static final long serialVersionUID = 1L;

    @Column(name = "name", length = 255)
    @JsonView(UserView.Summary.class)
    private String name;

Метод ресурса:

@GetMapping(value = "users", produces = {MediaType.APPLICATION_XML_VALUE, MediaType.APPLICATION_JSON_UTF8_VALUE})
@JsonView(UserView.Summary.class)
public List<User> getAllUsers() {
    return userRepository.findAllBy();
}

Это прекрасно работает при выводе JSON:

[
    {"name": "User 1"},
    {"name": "User 2"}
]

Но когда для "Content-Type" установлено значение XML, возвращается следующий вывод:

<List>
    <item>
        <name>User 1</name>
    </item>
    <item>
        <name>User 2</name>
    </item>
</List>

Я хотел бы иметь <Users> вместо <List> и <User> вместо <item>, но я не смог найти способ изменения этих родовых c имен. Я пробовал аннотации типа @XmlRootElement(name="user") или @XmlElementWrapper(name="users"), но не повезло.

Ответы [ 2 ]

1 голос
/ 26 марта 2020

Коллекции на уровне поддержки root ограничены для xml mapper (см. здесь и здесь (ответы немного устарели, но вы должны понять), но коллекции как Свойство pojo полностью поддерживается. Поэтому для настройки лучше создать оболочку.

Также обратите внимание на @JsonView (UserView.Summary.class) в свойстве оболочки для пружины, чтобы подобрать его.

Что-то вроде

@JacksonXmlRootElement(localName = "Users")
public class CollectionWrapper {

    @JacksonXmlElementWrapper(useWrapping = false)
    @JacksonXmlProperty(localName = "User")
    @JsonView(UserView.Summary.class)
    private List<User> users;

    public CollectionWrapper(List<User> users) {
        this.users = users;
    }

}

Ресурс

@GetMapping(value = "users", produces = {MediaType.APPLICATION_XML_VALUE, MediaType.APPLICATION_JSON_UTF8_VALUE})
@JsonView(UserView.Summary.class)
public CollectionWrapper getAllUsers() {
    return new CollectionWrapper(userRepository.findAllBy());
}

Вывод

<Users>
    <User>
        <name>User 1</name>
    </User>
    <User>
        <name>User 2</name>
    </User>
</Users>
1 голос
/ 26 марта 2020

Использование @XmlElementWrapper обычно является хорошим способом сделать это. Но это работает только тогда, когда список находится внутри сущности.

Я бы рекомендовал не возвращать List<User>, а вместо этого Users сущность (обратите внимание на множественное число) с атрибутом users. Мы даже можем опустить @XmlElementWrapper здесь, поскольку сама сущность является оберткой элемента.

@XmlRootElement
public class Users implements Serializable {

    private static final long serialVersionUID = 1337L;

    @XmlElement(name = "User")
    private List<User> users = new ArrayList<>();

    public List<User> getUsers() {
        return users;
    }

    public void setUsers(List<User> users) {
        this.users = users;
    }
}

Выход

<Users>
    <User>
        <name>User 1</name>
    </User>
    <User>
        <name>User 2</name>
    </User>
</Users>
...