等效于@JsonIgnore,但仅适用于使用 Jackson 的 xml 字段/属性转换

Posted

技术标签:

【中文标题】等效于@JsonIgnore,但仅适用于使用 Jackson 的 xml 字段/属性转换【英文标题】:Equivalent of @JsonIgnore but that works only for xml field/property conversion using Jackson 【发布时间】:2014-08-15 00:10:15 【问题描述】:

我有一个类,我正在使用 Jackson 对 JSON、XML 进行序列化/反序列化。

public class User 
    Integer userId;
    String name;
    Integer groupId;
...

我想在处理 xml 时忽略 groupId,所以我的 XML 不会包含它:

<User>
 <userId>...</userId>
 <name>...</name>
</User>

但是 JSON 会:


  "userId":"...",
  "name":"...",
  "groupId":"..."

我知道@JsonIgnore 可以在两者中使用,但我只想在 xml 中忽略它。

我知道可用于执行此操作的混合注释 (https://***.com/a/22906823/2487263),但我认为应该有一个简单的注释来执行此操作,但找不到它。杰克逊文档(至少对我而言)在尝试查找此类内容时并没有我想要的那么好。

【问题讨论】:

如何序列化/反序列化 XML?你在使用 XML 映射器吗? 【参考方案1】:

Jackson 不支持开箱即用。但是您可以使用the Jackson json views 或创建一个自定义注释,该注释将通过the annotation interospector. 为XML 映射器解释为@JsonIgnore

这是一个例子:

public class JacksonXmlAnnotation 
    @Retention(RetentionPolicy.RUNTIME)
    public @interface JsonOnly 
    


@JacksonXmlRootElement(localName = "root")
public class User 
    public final Integer userId;
    public final String name;
    @JsonOnly
    public final Integer groupId;

    public User(Integer userId, String name, Integer groupId) 
        this.userId = userId;
        this.name = name;
        this.groupId = groupId;
    


public class XmlAnnotationIntrospector extends JacksonXmlAnnotationIntrospector 
    @Override
    public boolean hasIgnoreMarker(AnnotatedMember m) 
        return m.hasAnnotation(JsonOnly.class) || super.hasIgnoreMarker(m);
    


public class Example 
    public static void main(String[] args) throws JsonProcessingException 
        User user = new User(1, "John", 23);
        XmlMapper xmlMapper = new XmlMapper();
        xmlMapper.setAnnotationIntrospector(new XmlAnnotationIntrospector());
        ObjectMapper jsonMapper = new ObjectMapper();
        System.out.println(xmlMapper.writerWithDefaultPrettyPrinter().writeValueAsString(user));
        System.out.println(jsonMapper.writerWithDefaultPrettyPrinter().writeValueAsString(user));
    

输出:

<root>
  <userId>1</userId>
  <name>John</name>
</root>

  "userId" : 1,
  "name" : "John",
  "groupId" : 23

【讨论】:

我试过你的方法,它确实可以忽略属性,但是当我使用内省时,它也会忽略所有其他杰克逊注释:“@JacksonXmlRootElement”、“@JacksonXmlProperty”等。 @raspacorp 好收获!我已经更新了我的答案。现在自定义内省器从 Jackson XML 模块扩展了 JacksonXmlAnnotationIntrospector。 当我使用@JsonProperty(value = "change_json_prop_name") 更改默认JSON 属性名称时,@JsonOnly 注释将不起作用。有没有一个函数可以解决这个问题?【参考方案2】:

您可以将JacksonAnnotationIntrospector 与@JsonIgnore(false) 一起使用

用户等级:

    public static class User 
      public final Integer userId;
      public final String name;
      @XmlTransient
      @JsonIgnore(false)
      public final Integer groupId;

      public User(Integer userId, String name, Integer groupId) 
        this.userId = userId;
        this.name = name;
        this.groupId = groupId;
      
    

将注解内省器设置为 ObjectMapper

ObjectMapper jsonMapper = new ObjectMapper();
jsonMapper.setAnnotationIntrospector(new JacksonAnnotationIntrospector());

【讨论】:

以上是关于等效于@JsonIgnore,但仅适用于使用 Jackson 的 xml 字段/属性转换的主要内容,如果未能解决你的问题,请参考以下文章

pipenv install --system 但仅适用于用户

Web 请求失败,但仅适用于 localhost 和使用 System.Net.HttpWebRequest

Excel 导出日期格式出错,但仅适用于某些日期值

使用 Gmail API 发送的邮件中缺少附件,但仅适用于收件人

3 个最新值,但仅适用于特定用户

枚举器“更新”类不包含定义,但仅适用于单元测试方法,而不是在 DAL 项目中使用时