【问题标题】:Customize Jackson XML output when using @JsonView in Spring Boot在 Spring Boot 中使用 @JsonView 时自定义 Jackson XML 输出
【发布时间】:2020-07-03 08:57:49
【问题描述】:

我正在使用@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>

我想用&lt;Users&gt; 代替&lt;List&gt;&lt;User&gt; 代替&lt;item&gt;,但我找不到更改这些通用名称的方法。我尝试过像@XmlRootElement(name="user")@XmlElementWrapper(name="users") 这样的注释,但没有运气。

【问题讨论】:

  • 您能对答案提供反馈吗?谢谢。
  • 嗨@SagarVeeram,是的,对不起。我已经尝试了两个答案,它们都有效。我将接受提供的第一个。非常感谢你们的贡献!
  • @viorel 在我的情况下,xml 输出不受 JsonView 的影响,但 json 呈现完美。你是如何制作你的作品的,你能分享一下。

标签: java spring-boot jackson2 jackson-dataformat-xml


【解决方案1】:

对 xml 映射器的根级集合支持有限(请参阅 herehere(答案有点过时,但您应该明白),但完全支持作为 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>

【讨论】:

    【解决方案2】:

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

    我建议不要返回List&lt;User&gt;,而是返回一个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>
    

    【讨论】:

      猜你喜欢
      • 2015-10-30
      • 2017-01-08
      • 2020-05-20
      • 1970-01-01
      • 2011-11-30
      • 2015-07-03
      • 2021-01-24
      • 2019-02-27
      • 2018-12-23
      相关资源
      最近更新 更多