8

I am using Jackson APIs for Mapping my JSON response into a java object. For example,

for the response { name :'karthikeyan',age:'24',gender:'Male'}

@JsonProperty("name")
public String _name;
@JsonProperty("age")
public int _age;
@JsonProperty("gender")
public String _gender;

is the Mix-in and it works fine.(internally we will be mapping this pojo and Mix-in).Now how can i represent the following response in a Mix-in?

{
name :'karthikeyan',
age:'24',
gender:'Male',
interest:
      {
        books:'xxx',
        music:'yyy',
        movie:'zzz'
      }
}

i have tried with the following, but no luck.

@JsonProperty("name")
public String _name;
@JsonProperty("age")
public int _age;
@JsonProperty("gender")
public String _gender;

@JsonProperty("interest")
public InterestPojo interestPojo;  //created same format mix-in and pojo for interest params as well.

but unable to map them exactly, give your comments and thoughts on how to do it ?

Karthikeyan
  • 2,634
  • 5
  • 30
  • 51
  • Can you show your classes and how you call them? I've created similar structure and it generates correct JSON file for me. – Jakub H Feb 26 '14 at 13:51
  • Please refer this [link..](https://github.com/kalakkumkarthikeyan/agorava-empireavenue/tree/master/agorava-empireavenue-cdi/src/main/java/org/agorava/empireavenue/jackson) There you can find the exact code, refer the pojos and mixins of Notifications/NotificationInfo. I need to get the not null object of NotificationInfo inside notifications class. So how can i script dowm my mixin to achieve ? – Karthikeyan Mar 03 '14 at 05:50

1 Answers1

8

I tried the following:

    ObjectMapper mapper = new ObjectMapper();
    System.out.println(mapper.writeValueAsString(new Something("Name", 12, "male", new Nested("books", "Music", "Movie"))));

public class Something {

    @JsonProperty("name")
    public String name;
    @JsonProperty("age")
    public int age;
    @JsonProperty("gender")
    public String gender;
    @JsonProperty("interest")
    public Nested nested;
    //Constructor
}

public class Nested {

    @JsonProperty("books")
    public String books;
    @JsonProperty("music")
    public String music;
    @JsonProperty("movie")
    public String movie;

    //Constructor
}

and the Output is:

{
"name":"Name",
"age":12,
"gender":"male",
"interest":
    {
        "books":"books",
        "music":"Music",
        "movie":"Movie"
    }
}

So everything is working as expected. I already checked if theres a difference if you provide some setters and getters and setting the visibility of the fields on private but that doas not make a difference.

Maybe you want to show us your InterestPojo or your output/stacktrace?

EDIT: Okay i think i got it ;)

I tried the following:

public void start() throws IOException {
    ObjectMapper mapper = new ObjectMapper();
    mapper.getSerializationConfig().addMixInAnnotations(Something.class, Nested.class);
    mapper.getDeserializationConfig().addMixInAnnotations(Something.class, Nested.class);
    System.out.println(mapper.writeValueAsString(new Something("Name", 12, "male", new NestedImpl("name", null))));
}
public final class Something {
    private final String name;
    private int age;
    private String gender;
    // thats your interest thing
    public Nested nested;

    public Something(String name, int age, String gender, Nested nested) {
        this.name = name;
        this.age = age;
        this.gender = gender;
        this.nested = nested;
    }
    String getName() {
        return name;
    }
    Nested getNested() {
        return nested;
    }
}
public abstract class Nested {
    @JsonProperty("name-ext")
    abstract String getName();
    @JsonProperty("interest-ext")
    abstract Nested getNested();
}
public class NestedImpl extends Nested {
    private String name;
    private Nested nested;
    private NestedImpl(String name, Nested nested) {
        this.name = name;
        this.nested = nested;
    }
    @Override
    String getName() {
        return name;
    }
    @Override
    Nested getNested() {
        return nested;
    }
}

Output:

{
    "age":12,
    "gender":"male",
    "name-ext":"Name",
    "interest-ext":
    {
        "name-ext":"name",
        "interest-ext":null
    }
}

Thats not exactly your structure, but I think thats what you want. Am I right?

EDIT2: I Tested the following structure with JSON->Object and Object->JSON.

ObjectMapper mapper = new ObjectMapper();
mapper.getSerializationConfig().addMixInAnnotations(Something.class, Mixin.class);
mapper.getSerializationConfig().addMixInAnnotations(Nested.class, NestedMixin.class);
mapper.getDeserializationConfig().addMixInAnnotations(Something.class, Mixin.class);
mapper.getDeserializationConfig().addMixInAnnotations(Nested.class, NestedMixin.class);

Nested nested = new Nested();
nested.setName("Nested");
nested.setNumber(12);

Something some = new Something();
some.setName("Something");
some.setAge(24);
some.setGender("Male");
some.setNested(nested);

String json = mapper.writeValueAsString(some);
System.out.println(json);
Something some2 = mapper.readValue(json, Something.class);
System.out.println("Object: " + some2);

public abstract class Mixin {

    @JsonProperty("name")
    private String _name;
    @JsonProperty("age")
    private int _age;
    @JsonProperty("gender")
    private String _gender;
    @JsonProperty("interest")
    private Nested nested;
}

public class Something {
    private String _name;
    private int _age;
    private String _gender;
    private Nested nested;

    // You have to provide Setters and Getters!!
}

public abstract class NestedMixin {

    @JsonProperty("nameNested")
    private String name;
    @JsonProperty("numberNested")
    private int number;
}

public class Nested {
    private String name;
    private int number;

    // You have to provide Setters and Getters!!
}

Output: {"age":24,"gender":"Male","name":"Something","interest":{"nameNested":"Nested","numberNested":12}}

Object: Something{name=Something, age=24, gender=Male, nested=Nested{name=Nested, number=12}}

Note: It seems that jackson got problems with inner classes. So if you test that examples in an extra project create extra class-files ;)

EDIT3: If you are using a Module, try the following:

public class JacksonMixinModule extends SimpleModule {
    public JacksonMixinModule() {
        super("JacksonMixinModule", new Version(0, 1, 0, "SNAPSHOT"));
    }
    @Override
    public void setupModule(SetupContext context) {
        super.setupModule(context);
        context.setMixInAnnotations(Something.class, Mixin.class);
        context.setMixInAnnotations(Nested.class, NestedMixin.class);
    }
}

...

ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(new JacksonMixinModule());
Yser
  • 2,086
  • 22
  • 28
  • Actually, i am trying to convert the JSON into Objects by using Jackson Mixins. Please refer [this link.](https://github.com/kalakkumkarthikeyan/agorava-empireavenue/tree/master/agorava-empireavenue-cdi/src/main/java/org/agorava/empireavenue/jackson). There you can find the exact code, refer the pojos and mixins of Notifications/NotificationInfo – Karthikeyan Feb 27 '14 at 06:17
  • No actually, i am looking for JSON to Object conversion, also no luck with your edited snippet, Still i am offering you the bounty score and i want you to go through the code that i mentioned above.help me out to get this done. – Karthikeyan Mar 05 '14 at 11:40
  • Well i edited my answer again. Concerning your code, where do you do the mapping JSON -> Object? – Yser Mar 05 '14 at 15:32
  • Yes, I have issues only with the inner class. Its being NULL all the time. What you given here is working good. But not in my actual code. For your information, i have this [this class](https://github.com/kalakkumkarthikeyan/agorava-empireavenue/blob/master/agorava-empireavenue-cdi/src/main/java/org/agorava/empireavenue/jackson/EmpireAvenueModule.java)to map my pojo and mixins. – Karthikeyan Mar 05 '14 at 15:50
  • Can you kick out that SimpleModule-stuff and try it with the `ObjectMapper#getSerializationConfig()` and `ObjectMapper#getDeserializationConfig()`? I tried that before but it simply doesn't work on the first try. Where do you register that SimpleModule? – Yser Mar 05 '14 at 15:56
  • I figured out you problem, I think ;) Try the following in you module: `@Override public void setupModule(SetupContext context) { super.setupModule(context); context.getSerializationConfig().addMixInAnnotations(Something.class, Mixin.class); context.getSerializationConfig().addMixInAnnotations(Nested.class, NestedMixin.class); context.getDeserializationConfig().addMixInAnnotations(Something.class, Mixin.class); context.getDeserializationConfig().addMixInAnnotations(Nested.class, NestedMixin.class); }` – Yser Mar 05 '14 at 16:12
  • From [this document](http://wiki.fasterxml.com/JacksonMixInAnnotations) i understand the above said is not necessary. Am i wrong ? – Karthikeyan Mar 06 '14 at 04:35
  • Hm, you are right (edited my answer). Okay the last thing i can imagine is that you simply forgot to register the module like this: `ObjectMapper mapper = new ObjectMapper(); mapper.registerModule(new JacksonMixinModule());`. Where do you create a ObjectMapper and register your module? If that is not the case I can not help you without further informations (stacktrace, output, etc.) – Yser Mar 06 '14 at 11:37
  • I am sure that the module is working fine as it works for the rest of mixin mappings.i.e,[In this class](https://github.com/kalakkumkarthikeyan/agorava-empireavenue/blob/master/agorava-empireavenue-cdi/src/main/java/org/agorava/empireavenue/jackson/EmpireAvenueModule.java)every mappings are perfect, including Notifications mapping. Because i am getting the values for two other param [in this class.](https://github.com/kalakkumkarthikeyan/agorava-empireavenue/blob/master/agorava-empireavenue-api/src/main/java/org/agorava/empireavenue/model/Notifications.java). – Karthikeyan Mar 07 '14 at 04:48
  • All that i needed is a valid not null NotificationInfo object. Can you please check [this mixin class](https://github.com/kalakkumkarthikeyan/agorava-empireavenue/blob/master/agorava-empireavenue-cdi/src/main/java/org/agorava/empireavenue/jackson/NotificationsMixin.java) as well ? – Karthikeyan Mar 07 '14 at 04:50
  • While ignoring the NotificationsInfo object in constructors, i can get the rest of param perfect, But in the other case, when i include the NotificationsInfo object, i am getting [this error](http://paste.opensuse.org/59864750), I guess, injecting the NotificationsInfo into Notifications class causes some issues. – Karthikeyan Mar 07 '14 at 04:51
  • okay I would recommend the following: don't work with the `@JsonCreator` constructors and fields within mixins. Instead use abstract getters and setters and define the `@JsonProperty("")` on it (both). The constructors seem to work with std. datatypes in the 3. and following stages but not with yours. so try to avoid these constructors if possible. btw the posted JSON helped me alot may you edit your question and add it there (and add the closing brackets ;)). Note: if you want some exceptions and info messages just comment out the `@JsonIgnoreProperties(ignoreUnknown = true)` temporarily. – Yser Mar 08 '14 at 16:39