Equivalent of @JsonIgnore but that works only for xml field/property conversion using Jackson

10,142

Solution 1

Jackson doesn't support this out of the box. But you can use the Jackson json views or create a custom annotation which will be interpreted for the XML mapper as @JsonIgnore via the annotation interospector.

Here is an example:

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));
    }
}

Output:

<root>
  <userId>1</userId>
  <name>John</name>
</root>
{
  "userId" : 1,
  "name" : "John",
  "groupId" : 23
}

Solution 2

You can use JacksonAnnotationIntrospector with @JsonIgnore(false)

User class:

    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;
      }
    }

Set annotation introspector to ObjectMapper

ObjectMapper jsonMapper = new ObjectMapper();
jsonMapper.setAnnotationIntrospector(new JacksonAnnotationIntrospector());
Share:
10,142
raspacorp
Author by

raspacorp

I work as a Software developer using Java and related technologies, interested in dynamic languages and web frameworks, I enjoy working with Spring Boot. Recently improving my table tennis game.

Updated on July 25, 2022

Comments

  • raspacorp
    raspacorp almost 2 years

    I have a class that I am serializing/deserializing from/to both JSON, XML using Jackson.

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

    I want to ignore groupId when doing xml processing, so my XMLs won't include it:

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

    But the JSONs will:

    {
      "userId":"...",
      "name":"...",
      "groupId":"..."
    }
    

    I know that @JsonIgnore will work in both, but I want to ignore it only in the xml.

    I know about the mix-in annotations that can be used to do this (https://stackoverflow.com/a/22906823/2487263), but I think there should be a simple annotation that does this, but cannot find it. Jackson documentation (at least for me) is not as good as I would like when trying to find these kind of things.