Created
August 6, 2017 06:23
-
-
Save sverhagen/c199d924245a078c287b46546e1ac26c to your computer and use it in GitHub Desktop.
Contextual deserializer for generic wrapper type in Jackson
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.example; | |
import com.fasterxml.jackson.core.JsonParser; | |
import com.fasterxml.jackson.core.ObjectCodec; | |
import com.fasterxml.jackson.databind.BeanProperty; | |
import com.fasterxml.jackson.databind.DeserializationContext; | |
import com.fasterxml.jackson.databind.JavaType; | |
import com.fasterxml.jackson.databind.JsonDeserializer; | |
import com.fasterxml.jackson.databind.JsonMappingException; | |
import com.fasterxml.jackson.databind.ObjectMapper; | |
import com.fasterxml.jackson.databind.deser.ContextualDeserializer; | |
import com.fasterxml.jackson.databind.type.CollectionType; | |
import com.fasterxml.jackson.databind.type.TypeFactory; | |
import java.io.IOException; | |
import java.util.List; | |
import java.util.Map; | |
/** | |
* Since {@link PagedResult} and friends are created via {@link PagedResultCreator}, and have always had non-default | |
* constructors, it is hard to deserialize them within unit tests using Jackson. This deserializer determines requested | |
* type (it implements {@link ContextualDeserializer} so that it gets this information from Jackson, based ultimately on | |
* whatever we pass into e.g. {@code RestAssured... .andReturn().as(ThisType.class)}. It then creates its own | |
* implementation of {@link PagedResult}, i.e. {@link PagedResultImplForTest}. | |
*/ | |
public class PagedResultDeserializer extends JsonDeserializer<PagedResult<?>> | |
implements ContextualDeserializer { | |
private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper(); | |
private JavaType valueType; | |
public PagedResultDeserializer(JavaType valueType) { | |
this.valueType = valueType; | |
} | |
public PagedResultDeserializer() { | |
} | |
@Override | |
public JsonDeserializer<?> createContextual(DeserializationContext ctxt, BeanProperty property) | |
throws JsonMappingException { | |
JavaType pagedResultType = property.getType(); | |
JavaType valueType = pagedResultType.containedType(0); | |
return new PagedResultDeserializer(valueType); | |
} | |
@Override | |
public PagedResult<?> deserialize(JsonParser jsonParser, DeserializationContext ctxt) throws IOException { | |
TypeFactory typeFactory = ctxt.getTypeFactory(); | |
CollectionType itemsListType = typeFactory.constructCollectionType(List.class, valueType); | |
ObjectCodec objectCodec = jsonParser.getCodec(); | |
Map properties = objectCodec.readValue(jsonParser, Map.class); | |
Object items = properties.remove("items"); | |
List<?> itemsList = OBJECT_MAPPER.convertValue(items, itemsListType); | |
return new PagedResultImplForTest<>(properties, itemsList); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment