Using two JsonSerializers for single entity in Jackson

367 views Asked by At

I've found a way to implement my own serialization method extending the JsonSerializer<Foo>, overriding the serialize() method and registering the SimpleModule with everything. Here is what I have:

@Provider
@Produces(MediaType.APPLICATION_JSON)
public class JacksonConfig implements ContextResolver<ObjectMapper> {


    @Override
    public ObjectMapper getContext(Class<?> aClass) {
        ObjectMapper mapper = new ObjectMapper();
        mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
        SimpleModule fooModule = new SimpleModule("FooModule",
                                      new Version(0, 1, 0, null, "org.foo.bar", "foo"));
        relationshipModule.addSerializer(Foo.class, new FooJacksonSerializer());
        relationshipModule.addDeserializer(Foo.class, new FooJacksonDeserializer());
        mapper.registerModule(fooModule);
        return mapper;
    }
}

However, is there a way to use two custom serialization strategies and depending on the REST request (I use RestEasy) choose the right one? I.e. changing it programmaticaly on the fly, not when the context is set-up. I'd like to have a concise form of the Foo and the verbose one.

1

There are 1 answers

7
lefloh On BEST ANSWER

You could implement a special ObjectMapper and manually obtain the one you need:

@Provider
@Produces(MediaType.APPLICATION_JSON)
public class JacksonConfig implements ContextResolver<ObjectMapper> {

    private ObjectMapper objectMapper;

    private SpecialObjectMapper specialObjectMapper; // a class extending ObjectMapper

    public JacksonConfig() {
        objectMapper = new ObjectMapper();
        // configuration ...
        specialObjectMapper = new SpecialObjectMapper();
        // configuration with module ...
    }

    @Override
    public ObjectMapper getContext(Class<?> clazz) {
        return clazz == SpecialObjectMapper.class ? specialObjectMapper : objectMapper;
    }

}

In your resource class:

@Context 
private Providers providers;

public String get() {
    ContextResolver<ObjectMapper> contextResolver = 
        providers.getContextResolver(ObjectMapper.class, MediaType.APPLICATION_JSON_TYPE);
    ObjectMapper mapper = someCondition 
        ? contextResolver.getContext(SpecialObjectMapper.class) 
        : contextResolver.getContext(ObjectMapper.class);
    return mapper.writeValueAsString(value);
}

I don't know what your goal is but maybe you can also achieve it with Jackson's JSON Views or define a custom MediaType like application/vnd.com.foo.bar.foo+json and register your serializer only for this type.