繁体   English   中英

在 Spring Boot 中使用 @JsonView 时自定义 Jackson XML 输出

[英]Customize Jackson XML output when using @JsonView in Spring Boot

我正在使用@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> ,但我找不到更改这些通用名称的方法。 我试过像@XmlRootElement(name="user")@XmlElementWrapper(name="users")这样的注释,但没有运气。

使用@XmlElementWrapper通常是一个很好的方法。 但这仅在列表位于实体内时才有效。

我建议不要返回List<User>而是返回一个带有属性usersUsers实体(注意复数)。 我们甚至可以在这里省略@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>

xml 映射器在根级别支持的集合是有限的(请参阅此处此处(答案有点过时,但您应该明白这一点),但完全支持作为 pojo 属性的集合。因此,对于自定义,最好创建一个包装器。

还要注意 @JsonView(UserView.Summary.class) 到 spring 的包装器属性以获取它。

就像是

@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>

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM