4

I've got two classes:

public class Bar {
    private String identifier;
    private String otherStuff;

    public Bar(){}

    public Bar(String identifier, String otherStuff) {
        this.identifier = identifier;
        this.otherStuff = otherStuff;
    }

    // Getters and Setters
}

and

public class Foo {
    private String foo;

    @JsonSerialize(using=BarsMapSerializer.class)
    @JsonDeserialize(using=BarsMapDeserializer.class)
    private Map<String, Bar> barsMap;

    public Foo(){}
    public Foo(String foo, Map<String, Bar> barsMap) {
        this.foo = foo;
        this.barsMap = barsMap;
    }

    // Getters and Setters
}

When I sserialize Foo with code:

public static void main(String[] args) throws Exception {
    Map<String, Bar> barsMap = new LinkedHashMap<>();
    barsMap.put("b1", new Bar("bar1", "nevermind1"));
    barsMap.put("b2", new Bar("bar2", "nevermind2"));
    barsMap.put("b3", new Bar("bar3", "nevermind3"));
    Foo foo = new Foo("foo", barsMap);

    ObjectMapper mapper = new ObjectMapper();
    String jsonString = mapper.writeValueAsString(foo);
    System.out.println(jsonString);
}

the otput is:

{"foo":"foo","barsMap":{"b1":"bar1","b2":"bar2","b3":"bar3"}}

For most cases it's ok, but in some cases I want to have full Bar object in my json, like bellow:

{"foo":"foo","barsMap":{"b1":{"identifier":"bar1", "otherStuff":"nevermind1"},"b2":{"identifier":"bar2", "otherStuff":"nevermind2"},"b3":{"identifier":"bar3", "otherStuff":nevermind3"}}}

Is it possible to achieve this without writing custom serializer? I know that I can add annotation using mix-in mechanism, but basically I need to ignore existing one in some cases.

adjablon
  • 502
  • 4
  • 9
  • You can use MixIn mechanism and use two different `ObjectMapper`s. One `ObjectMapper` you will use in situation when you need this custom serializer and second `ObjectMapper` you can use when you do not need it. Please, check this question: http://stackoverflow.com/questions/22691765/different-json-configuration-in-a-spring-application-for-rest-and-ajax-serializa/22701578 – Michał Ziober Apr 03 '14 at 11:47
  • @MichałZiober In most cases I need custom serializer, that's why annotations are in my `Foo` class. I've tried Mixin mechanism and I could add some serializer with it, but I need to ignore existing one. – adjablon Apr 03 '14 at 12:14
  • 1
    I understand the problem. Mainly you want to serialize this class using custom serializer but sometimes you want to serialize it using default serializer. If yes, you have only one solution: you have to create two `ObjectMapper`s objects and in first enable custom serializer (using MixIn feature), in second you shouldn't do that. You can also try to use `MapperFeature.USE_ANNOTATIONS` feature. In one `ObjectMapper` you can enable it and this object should not read annotations, so custom serializer will not be used. – Michał Ziober Apr 03 '14 at 21:19
  • What is the status of your problem? Did you solve it? – Michał Ziober Apr 05 '14 at 23:47
  • @MichałZiober I've resolved my problem using mix-in mechanism as You suggested. But I did it in different way. You can check my answer. Thank You for helping me. – adjablon Apr 07 '14 at 12:07
  • I'm glad I could help. Please upvote my answer for this http://stackoverflow.com/questions/22691765/different-json-configuration-in-a-spring-application-for-rest-and-ajax-serializa/22701578 question if it was helpfull for you. – Michał Ziober Apr 07 '14 at 12:32

1 Answers1

2

I've resolved my problem using mix-in mechanism.

public interface FooMixin {
    @JsonSerialize
    Map<String, Bar> getBarsMap();
    @JsonDeserialize
    void setBarsMap(Map<String, Bar> barsMap);
}

With this interface mixed in, class Foo is serialized as with default serializer. As You can see You need to add JsonSerialize / JsonDeserialize annotations without specify any class.

Below code shows usage of this interface:

mapper = new ObjectMapper();
mapper.addMixInAnnotations(Foo.class, FooMixin.class);
jsonString = mapper.writeValueAsString(foo);
System.out.println(jsonString);
adjablon
  • 502
  • 4
  • 9