Search code examples
jerseyjacksondropwizardjersey-client

Options for custom serializers / deserializers with Dropwizard?


What's a good way to have custom (de)serializers that can be registered externally with dropwizard?

I was having problems with (de)serializing a composite object. I tried using @JsonUnwrapped to get the JSON I wanted, but had problems with it for deserializing - it needs special constructors that take strings and requires the composite object to have knowledge on constructing the encapsulated objects. Also, I'd like a way of not having to use Jackson annotations on my value objects.

For example, I have:

public class SubmissionModule extends SimpleModule {
    public SubmissionModule() {
        addDeserializer(SubmissionDetails.class, new SubmissionDeserializer());
        addSerializer(SubmissionDetails.class, new SubmissionSerializer());
    }

    public class SubmissionSerializer extends JsonSerializer<SubmissionDetails> {
        @Override
        public void serialize(SubmissionDetails value, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonProcessingException {
            jgen.writeStartObject();
            jgen.writeStringField("id", "" + value.getId());
            jgen.writeStringField("title", value.getTitle());
            jgen.writeStringField("abstract", value.getAbstract());
            jgen.writeEndObject();
        }
    }

    public class SubmissionDeserializer extends JsonDeserializer<SubmissionDetails> {
        @Override
        public SubmissionDetails deserialize(final JsonParser jp, final DeserializationContext ctxt) throws IOException, JsonProcessingException {
            JsonNode node = jp.getCodec().readTree(jp);
            return aSubmissionWithId(SubmissionId.from(node.get("id").asText()))
                    .title(node.get("title").asText())
                    .abstract_(node.get("abstract").asText()).create();
        }
    }
}

which I've registered in DropWizard like so: bootstrap.getObjectMapper().registerModule(new SubmissionModule());

but I can't figure out if it's possible to register the (de)serializers with the Jersey Client (or the client available when using ResourceTestRule).

Any ideas?


Solution

  • "but I can't figure out if it's possible to register the (de)serializers with the Jersey Client (or the client available when using ResourceTestRule). "

    Check out the source code for ResourceTestRule. There's a method setMapper(ObjectMapper)

    You can do something like

    ObjectMapper mapper = Jackson.newObjectMapper();
    mapper.registerModule(new SubmissionModule());
    @ClassRule
    public static final ResourceTestRule RULE 
               = new ResourceTestRule.Builder().setMapper(mapper).addResource(...).build();