Skip to content

Instantly share code, notes, and snippets.

@xhanin
Created October 23, 2015 15:42
Show Gist options
  • Save xhanin/4beac9b8bf9a1091a4fe to your computer and use it in GitHub Desktop.
Save xhanin/4beac9b8bf9a1091a4fe to your computer and use it in GitHub Desktop.
jackson deserializer unwrapping a data field
import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.JsonToken;
import com.fasterxml.jackson.databind.BeanDescription;
import com.fasterxml.jackson.databind.DeserializationConfig;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.deser.BeanDeserializerModifier;
import com.fasterxml.jackson.databind.deser.ResolvableDeserializer;
import com.fasterxml.jackson.databind.deser.std.StdDeserializer;
import com.fasterxml.jackson.databind.module.SimpleModule;
import org.junit.Test;
import java.io.IOException;
import static org.assertj.core.api.Assertions.assertThat;
public class JacksonDeserializerTest {
@Test
public void should_deserialize_data() throws Exception {
ObjectMapper mapper = new ObjectMapper();
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
SimpleModule simpleModule = new SimpleModule();
simpleModule.setDeserializerModifier(new BeanDeserializerModifier() {
@Override public JsonDeserializer<?> modifyDeserializer(DeserializationConfig config, BeanDescription beanDesc, JsonDeserializer<?> deserializer)
{
if (beanDesc.getBeanClass() == MyEntity.class)
return new MyDeserializer((JsonDeserializer<MyEntity>) deserializer);
return deserializer;
}
});
mapper.registerModule(simpleModule);
MyEntity myEntity = mapper.readValue(
"{\"name\": \"test\", \"data\": { \"myfield\": \"test2\" } }", MyEntity.class);
assertThat(myEntity.getName()).isEqualTo("test");
assertThat(myEntity.getMyfield()).isEqualTo("test2");
}
public static class MyDeserializer extends StdDeserializer<MyEntity> implements ResolvableDeserializer {
private final JsonDeserializer<MyEntity> defaultDeserializer;
public MyDeserializer(JsonDeserializer<MyEntity> defaultDeserializer) {
super(MyEntity.class);
this.defaultDeserializer = defaultDeserializer;
}
@Override
public MyEntity deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException {
JsonToken token = jp.getCurrentToken();
if (token == JsonToken.START_OBJECT) {
jp.nextToken();
MyEntity e = new MyEntity();
if (!"name".equals(jp.getCurrentName())) {
throw new JsonParseException("expected name", jp.getCurrentLocation());
}
e.setName(jp.nextTextValue());
jp.nextToken();
if (!"data".equals(jp.getCurrentName())) {
throw new JsonParseException("expected data", jp.getCurrentLocation());
}
jp.nextToken();
defaultDeserializer.deserialize(jp, ctxt, e);
jp.nextToken();
return e;
}
return null;
}
@Override public void resolve(DeserializationContext ctxt) throws JsonMappingException
{
((ResolvableDeserializer) defaultDeserializer).resolve(ctxt);
}
}
public static class MyEntity {
private String name;
private String myfield;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getMyfield() {
return myfield;
}
public void setMyfield(String myfield) {
this.myfield = myfield;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment