6

I'm new to Java and Jackson and a lot of other technologies which I try to use, so I'd appreciate a detailed answer.

Is there a way to prevent one or more fields from being serialized using Jackson into a JSON String_like format, but without using any kind of JSON annotations?

Something like: mapper.getSerializationConfig().something(ignore("displayname")) if you know what I mean. My object is an instance of a class that extends another one, and implements one interface also so on, so the fields come from an hierarchy of classes. I need the JSON representation for that object but containing only certain fields, so I can send that JSON in a mock request through a POST method. I'm using Jackson 2.2.2.

Michał Ziober
  • 37,175
  • 18
  • 99
  • 146
niceman
  • 161
  • 1
  • 3
  • 11
  • If you can edit the main class or the interface, then just use the keyword `transient` in your field declaration. Transient fields won't be serialized. For ex : `public transient int test;` – alain.janinm Jun 05 '13 at 12:20
  • Thanks for your answer but I can't touch the main class. Otherwise I would use the annotation JSonIgnore on the specific fields and everything would be solved. – niceman Jun 05 '13 at 12:40
  • That's what I fear, then you can try to use view like in this example : http://stackoverflow.com/a/8477588/1140748. – alain.janinm Jun 05 '13 at 13:04

1 Answers1

6

If you can't change your classes you can create new abstract class/interface with methods with @JsonIgnore annotation. In this class/interface you can define methods which ObjectMapper should skip during serialization/deserialization process.

Please, see below example:

import java.io.IOException;

import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.databind.ObjectMapper;

public class JacksonProgram {

    public static void main(String[] args) throws IOException {
        Person person = new Person();
        person.setId(1L);
        person.setName("Max");

        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.addMixIn(Person.class, PersonMixIn.class);

        System.out.println(objectMapper.writeValueAsString(person));
    }
}

abstract class Entity {

    private Long id;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }
}

interface Namamble {
    String getName();
}

class Person extends Entity implements Namamble {

    private String name;

    @Override
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

interface PersonMixIn {
    @JsonIgnore
    String getName();
}

EDIT - answer for the comments

You can create such mixin interface:

public static interface UserInformationMixIn {
    @JsonIgnore
    String getField3();
}

and configure ObjectMapper in this way:

objectMapper.addMixInAnnotations(UserInformation.class, UserInformationMixIn.class);

In version 2.5 method addMixInAnnotations was deprecated and addMixIn should be used:

objectMapper.addMixIn(UserInformation.class, UserInformationMixIn.class);

Full example source code:

import java.io.IOException;

import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.databind.ObjectMapper;

public class JacksonProgram {

    public static void main(String[] args) throws IOException {
        UserInformation userInformation = new UserInformation();
        userInformation.setField3("field3");
        userInformation.setField4("field4");
        userInformation.setField5("field5");

        User user = new User();
        user.setField1(userInformation);
        user.setField2("field2");

        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.addMixIn(UserInformation.class, UserInformationMixIn.class);
        objectMapper.addMixIn(User.class, UserInformationMixIn.class);

        System.out.println(objectMapper.writeValueAsString(user));
    }

    public static abstract class Someclass {
        String field5;

        public String getField5() {
            return field5;
        }

        public void setField5(String field5) {
            this.field5 = field5;
        }
    }

    public static class UserInformation extends Someclass {
        String field3;
        String field4;

        public String getField3() {
            return field3;
        }

        public void setField3(String field3) {
            this.field3 = field3;
        }

        public String getField4() {
            return field4;
        }

        public void setField4(String field4) {
            this.field4 = field4;
        }
    }

    public static class User {
        UserInformation field1;
        String field2;

        public UserInformation getField1() {
            return field1;
        }

        public void setField1(UserInformation field1) {
            this.field1 = field1;
        }

        public String getField2() {
            return field2;
        }

        public void setField2(String field2) {
            this.field2 = field2;
        }
    }

public static interface UserInformationMixIn {
    @JsonIgnore
    String getField3();

    @JsonIgnore
    String getField2();

    @JsonIgnore
    String getField5();
}
}

Helpful link:

Michał Ziober
  • 37,175
  • 18
  • 99
  • 146
  • Thank you mykhaylo, I'll try to follow your example. – niceman Jun 05 '13 at 14:26
  • abstract class Someclass { String field5; } class UserInformation extends SomeClass { String field3; String field4; } class User { UserInformation field1; String field2; } – niceman Jun 06 '13 at 09:35
  • Sorry for the formatting, how can I serialize the field1 but without the field3 using mixin classes? It's a little even more complicated class structure but if you answer me to the question I could adapt easily. Thank you again. – niceman Jun 06 '13 at 09:37
  • Please, see my additional example. I hope it will help you. – Michał Ziober Jun 06 '13 at 09:53
  • thank you and sorry for bothering... The problem is I need to skip the field2 and field5 also, apart from the field3... Any sugestions? How should I put those 3 fields in the same mixin class? – niceman Jun 06 '13 at 10:59
  • I've changed my answer. The solution is easy. You have to add all "get' methods which you want to delete from JSON into mixin class and tell ObjectMapper that these classes should be merged with your MixIn definition. Please, read this documentation: http://wiki.fasterxml.com/JacksonMixInAnnotations – Michał Ziober Jun 06 '13 at 11:17
  • Thank you very much sir, it worked perfectly. As I only use this site since yesterday, is there anything I can do, like close the question or something like that, or give you some kind of points? Thank you again, I was looking for the answer for 3 days. – niceman Jun 06 '13 at 11:43
  • I'm glad I could help you. You can up-vote my answer and checked it as an answer for your question. – Michał Ziober Jun 06 '13 at 11:59
  • 2
    I checked it but I need 15 points of reputation to be able to up-vote it, sorry. Maybe I can do it later, when I get more reputation points. Many thanks again. – niceman Jun 06 '13 at 12:12
  • Really nice, for me this means that the logic layer containing pojos can be totally unaware of us using Json for our rest interface. – Sebastian Dec 03 '13 at 14:52
  • addMixInAnnotations is deprecated now, we have to use addMixIn instead – maxeh Apr 16 '19 at 14:22
  • 1
    @Max, take a look on [addMixIn](https://fasterxml.github.io/jackson-databind/javadoc/2.9/com/fasterxml/jackson/databind/ObjectMapper.html#addMixIn-java.lang.Class-java.lang.Class-) method instead. – Michał Ziober Apr 16 '19 at 14:32