I'm working with a project that is using a custom Jackson JsonDeserializer
to deserialize an object with a field containing a third-party type from JSON that cannot be deserialized directly. This deserializer is used by annotating the field with @JsonDeserialize(using = CustomTypeDeserializer.class)
.
public static class OuterType {
@JsonDeserialize(using = CustomTypeDeserializer.class)
private CustomType customType;
public CustomType getCustomType() { return customType; }
public void setCustomType(CustomType customType) { this.customType = customType; }
}
This works fine when the type to be deserialized is a property of another type, since there is a place to put the @JsonDeserialize
annotation. One thing it does not work for is deserializing the type directly.
new ObjectMapper().readValue(json, CustomType.class); // Doesn't work.
It doesn't look like I can use the deserializer directly, as it does not appear to be written in a way that it can directly deserialize values outside of the context of an ObjectMapper
.
Note that the type to be deserialized is a third-party type, and therefore I cannot modify it with Jackson annotations.
Is there a way to deserialize a non-nested type using a custom deserializer?
One approach would be to write a custom Module
containing the deserializer to the module, and add the module to the ObjectMapper
.
public static class CustomTypeModule extends SimpleModule {
public CustomTypeModule() {
addDeserializer(CustomType.class, new CustomTypeDeserializer());
}
}
JsonMapper objectMapper = JsonMapper.builder().addModule(new CustomTypeModule()).build();
CustomType value = objectMapper.readValue(json, CustomType.class);
If you don't want to modify your global application ObjectMapper
(making the module available to all requests), you can apply this to a copy of the ObjectMapper
used just for this operation.
JsonMapper objectMapper = JsonMapper.builder().build();
// ...
JsonMapper customTypeMapper = objectMapper.rebuild().addModule(new CustomTypeModule()).build();
// OR
ObjectMapper customTypeMapper = objectMapper.copy().registerModule(new CustomTypeModule())
CustomType value = customTypeMapper.readValue(json, CustomType.class);