简体   繁体   中英

Make Jackson use GSON Annotations

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM