I have a data model which I cannot change. The model itself is annotated with GSON annotations.
@SerializedName("first_value")
private String firstValue = null;
The deserialization with Jackson does not work as needed. Jackson cannot match the entry, therefore the value is null.
It would work with
@JsonProperty("first_value")
private String firstValue = null;
Is there any way I can make Jackson use the GSON annotations, or is there a any other solution in which I do not need to change the original models annotations?
I investigated the problem a bit and it seems that the @JsonProperty
annotation is handled with JacksonAnnotationIntrospector
. Extending the latter, making it handle @SerializedName
, seems to do the trick preserving the original behavior (I hope so):
@NoArgsConstructor(access = AccessLevel.PRIVATE)
final class SerializedNameAnnotationIntrospector
extends JacksonAnnotationIntrospector {
@Getter
private static final AnnotationIntrospector instance = new SerializedNameAnnotationIntrospector();
@Override
public PropertyName findNameForDeserialization(final Annotated annotated) {
@Nullable
final SerializedName serializedName = annotated.getAnnotation(SerializedName.class);
if ( serializedName == null ) {
return super.findNameForDeserialization(annotated);
}
// TODO how to handle serializedName.alternate()?
return new PropertyName(serializedName.value());
}
}
public final class SerializedNameAnnotationIntrospectorTest {
private static final AnnotationIntrospector unit = SerializedNameAnnotationIntrospector.getInstance();
@Test
public void test()
throws IOException {
final ObjectMapper objectMapper = new ObjectMapper()
.setAnnotationIntrospector(unit);
final Model model = objectMapper.readValue("{\"first_value\":\"foo\",\"second_value\":\"bar\"}", Model.class);
Assertions.assertEquals("foo", model.firstValue);
Assertions.assertEquals("bar", model.secondValue);
}
private static final class Model {
@SerializedName("first_value")
private final String firstValue = null;
// does not exist in the original model,
// but retains here to verify whether the introspector still works fine
@JsonProperty("second_value")
private final String secondValue = null;
}
}
Please note that I'm not sure how good it works as I'm not a Jackson expert.