diff --git a/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/json/JacksonSerializers.java b/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/json/JacksonSerializers.java index 26a9f5ee6..96b857533 100644 --- a/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/json/JacksonSerializers.java +++ b/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/json/JacksonSerializers.java @@ -27,8 +27,12 @@ import org.springframework.util.Assert; import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.BeanProperty; import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.JsonDeserializer; +import com.fasterxml.jackson.databind.JsonMappingException; import com.fasterxml.jackson.databind.SerializerProvider; +import com.fasterxml.jackson.databind.deser.ContextualDeserializer; import com.fasterxml.jackson.databind.deser.std.StdDeserializer; import com.fasterxml.jackson.databind.module.SimpleDeserializers; import com.fasterxml.jackson.databind.module.SimpleModule; @@ -122,11 +126,12 @@ public class JacksonSerializers extends SimpleModule { * @author Oliver Gierke */ @SuppressWarnings("rawtypes") - public static class EnumTranslatingDeserializer extends StdDeserializer { + public static class EnumTranslatingDeserializer extends StdDeserializerimplements ContextualDeserializer { private static final long serialVersionUID = 5305284644923180079L; private final EnumTranslator translator; + private final BeanProperty property; /** * Creates a new {@link EnumTranslatingDeserializer} using the given {@link EnumTranslator}. @@ -134,11 +139,34 @@ public class JacksonSerializers extends SimpleModule { * @param translator must not be {@literal null}. */ public EnumTranslatingDeserializer(EnumTranslator translator) { + this(translator, null); + } + + /** + * Creates a new {@link EnumTranslatingDeserializer} using the given {@link EnumTranslator} and {@link BeanProperty} + * . + * + * @param translator must not be {@literal null}. + * @param property can be {@literal null}. + */ + public EnumTranslatingDeserializer(EnumTranslator translator, BeanProperty property) { super(Enum.class); Assert.notNull(translator, "EnumTranslator must not be null!"); + this.translator = translator; + this.property = property; + } + + /* + * (non-Javadoc) + * @see com.fasterxml.jackson.databind.deser.ContextualDeserializer#createContextual(com.fasterxml.jackson.databind.DeserializationContext, com.fasterxml.jackson.databind.BeanProperty) + */ + @Override + public JsonDeserializer createContextual(DeserializationContext ctxt, BeanProperty property) + throws JsonMappingException { + return new EnumTranslatingDeserializer(translator, property); } /* @@ -148,7 +176,12 @@ public class JacksonSerializers extends SimpleModule { @Override @SuppressWarnings("unchecked") public Enum deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException { - return translator.fromText((Class>) ctxt.getContextualType().getRawClass(), p.getText()); + + if (property == null) { + throw new IllegalStateException("Can only translate enum with property information!"); + } + + return translator.fromText((Class>) property.getType().getRawClass(), p.getText()); } } } diff --git a/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/json/PersistentEntitySerializationTests.java b/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/json/PersistentEntitySerializationTests.java index 11fa91562..f81695bb2 100644 --- a/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/json/PersistentEntitySerializationTests.java +++ b/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/json/PersistentEntitySerializationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2014 the original author or authors. + * Copyright 2012-2015 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -27,6 +27,10 @@ import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.support.MessageSourceAccessor; +import org.springframework.context.support.StaticMessageSource; import org.springframework.data.mapping.PersistentEntity; import org.springframework.data.projection.ProjectionFactory; import org.springframework.data.projection.SpelAwareProxyProjectionFactory; @@ -40,6 +44,7 @@ import org.springframework.data.rest.webmvc.jpa.PersonRepository; import org.springframework.data.rest.webmvc.jpa.UserExcerpt; import org.springframework.data.rest.webmvc.mongodb.Address; import org.springframework.data.rest.webmvc.mongodb.User; +import org.springframework.data.rest.webmvc.mongodb.User.Gender; import org.springframework.data.rest.webmvc.util.TestUtils; import org.springframework.hateoas.Link; import org.springframework.hateoas.LinkDiscoverer; @@ -67,7 +72,7 @@ import com.jayway.jsonpath.JsonPath; * @author Oliver Gierke */ @RunWith(SpringJUnit4ClassRunner.class) -@ContextConfiguration(classes = RepositoryTestsConfig.class) +@ContextConfiguration(classes = { RepositoryTestsConfig.class, PersistentEntitySerializationTests.TestConfig.class }) @Transactional public class PersistentEntitySerializationTests { @@ -78,6 +83,20 @@ public class PersistentEntitySerializationTests { @Autowired PersonRepository people; @Autowired OrderRepository orders; + @Configuration + static class TestConfig extends RepositoryTestsConfig { + + @Bean + @Override + public ObjectMapper objectMapper() { + + ObjectMapper objectMapper = super.objectMapper(); + objectMapper.registerModule( + new JacksonSerializers(new EnumTranslator(new MessageSourceAccessor(new StaticMessageSource())))); + return objectMapper; + } + } + LinkDiscoverer linkDiscoverer; ProjectionFactory projectionFactory; @@ -277,4 +296,12 @@ public class PersistentEntitySerializationTests { assertThat(JsonPath.read(result, "$_links.processed"), is(notNullValue())); } + + /** + * @see DATAREST-654 + */ + @Test + public void deserializesTranslatedEnumProperty() throws Exception { + assertThat(mapper.readValue("{ \"gender\" : \"Male\" }", User.class).gender, is(Gender.MALE)); + } }