diff --git a/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/alps/AlpsJsonHttpMessageConverter.java b/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/alps/AlpsJsonHttpMessageConverter.java index b53ba8440..2ebc703e2 100644 --- a/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/alps/AlpsJsonHttpMessageConverter.java +++ b/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/alps/AlpsJsonHttpMessageConverter.java @@ -15,19 +15,20 @@ */ package org.springframework.data.rest.webmvc.alps; -import java.io.IOException; import java.lang.reflect.Type; import java.util.Arrays; +import org.springframework.core.MethodParameter; import org.springframework.core.convert.converter.Converter; import org.springframework.data.rest.webmvc.RootResourceInformation; import org.springframework.hateoas.alps.Alps; -import org.springframework.http.HttpOutputMessage; import org.springframework.http.MediaType; import org.springframework.http.converter.HttpMessageConverter; -import org.springframework.http.converter.HttpMessageNotWritableException; import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; +import org.springframework.http.server.ServerHttpRequest; +import org.springframework.http.server.ServerHttpResponse; import org.springframework.util.Assert; +import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice; import com.fasterxml.jackson.annotation.JsonInclude.Include; import com.fasterxml.jackson.databind.ObjectMapper; @@ -38,7 +39,8 @@ import com.fasterxml.jackson.databind.ObjectMapper; * * @author Oliver Gierke */ -public class AlpsJsonHttpMessageConverter extends MappingJackson2HttpMessageConverter { +public class AlpsJsonHttpMessageConverter extends MappingJackson2HttpMessageConverter + implements ResponseBodyAdvice { private static final MediaType ALPS_MEDIA_TYPE = MediaType.parseMediaType("application/alps+json"); @@ -83,15 +85,22 @@ public class AlpsJsonHttpMessageConverter extends MappingJackson2HttpMessageConv /* * (non-Javadoc) - * @see org.springframework.http.converter.json.MappingJackson2HttpMessageConverter#writeInternal(java.lang.Object, org.springframework.http.HttpOutputMessage) + * @see org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice#beforeBodyWrite(java.lang.Object, org.springframework.core.MethodParameter, org.springframework.http.MediaType, java.lang.Class, org.springframework.http.server.ServerHttpRequest, org.springframework.http.server.ServerHttpResponse) */ @Override - protected void writeInternal(Object object, HttpOutputMessage outputMessage) throws IOException, - HttpMessageNotWritableException { + public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType, + Class> selectedConverterType, ServerHttpRequest request, + ServerHttpResponse response) { - Object toWrite = object instanceof RootResourceInformation ? converter.convert((RootResourceInformation) object) - : object; + return body instanceof RootResourceInformation ? converter.convert((RootResourceInformation) body) : body; + } - super.writeInternal(toWrite, outputMessage); + /* + * (non-Javadoc) + * @see org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice#supports(org.springframework.core.MethodParameter, java.lang.Class) + */ + @Override + public boolean supports(MethodParameter returnType, Class> converterType) { + return converterType.equals(AlpsJsonHttpMessageConverter.class); } } diff --git a/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/config/RepositoryRestMvcConfiguration.java b/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/config/RepositoryRestMvcConfiguration.java index 97f24ee1b..515293b31 100644 --- a/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/config/RepositoryRestMvcConfiguration.java +++ b/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/config/RepositoryRestMvcConfiguration.java @@ -122,6 +122,7 @@ import org.springframework.web.servlet.HandlerMapping; import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; import org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver; import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter; +import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice; import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.Module; @@ -496,6 +497,10 @@ public class RepositoryRestMvcConfiguration extends HateoasAwareSpringDataWebCon handlerAdapter.setWebBindingInitializer(initializer); handlerAdapter.setMessageConverters(messageConverters); + if (config().metadataConfiguration().alpsEnabled()) { + handlerAdapter.setResponseBodyAdvice(Arrays.> asList(alpsJsonHttpMessageConverter())); + } + return handlerAdapter; } @@ -589,7 +594,7 @@ public class RepositoryRestMvcConfiguration extends HateoasAwareSpringDataWebCon List> messageConverters = new ArrayList>(); if (config().metadataConfiguration().alpsEnabled()) { - messageConverters.add(new AlpsJsonHttpMessageConverter(alpsConverter())); + messageConverters.add(alpsJsonHttpMessageConverter()); } if (config().getDefaultMediaType().equals(MediaTypes.HAL_JSON)) { @@ -609,6 +614,11 @@ public class RepositoryRestMvcConfiguration extends HateoasAwareSpringDataWebCon return messageConverters; } + @Bean + public AlpsJsonHttpMessageConverter alpsJsonHttpMessageConverter() { + return new AlpsJsonHttpMessageConverter(alpsConverter()); + } + /* * (non-Javadoc) * @see org.springframework.data.web.config.HateoasAwareSpringDataWebConfiguration#pageableResolver() diff --git a/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/config/RepositoryRestMvConfigurationIntegrationTests.java b/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/config/RepositoryRestMvConfigurationIntegrationTests.java index b970bfaa7..7bc9834c2 100644 --- a/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/config/RepositoryRestMvConfigurationIntegrationTests.java +++ b/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/config/RepositoryRestMvConfigurationIntegrationTests.java @@ -40,6 +40,7 @@ import org.springframework.data.geo.Point; import org.springframework.data.rest.core.config.RepositoryRestConfiguration; import org.springframework.data.rest.webmvc.RepositoryLinksResource; import org.springframework.data.rest.webmvc.RestMediaTypes; +import org.springframework.data.rest.webmvc.alps.AlpsJsonHttpMessageConverter; import org.springframework.data.rest.webmvc.json.PersistentEntityJackson2Module; import org.springframework.data.web.HateoasPageableHandlerMethodArgumentResolver; import org.springframework.data.web.PageableHandlerMethodArgumentResolver; @@ -153,11 +154,12 @@ public class RepositoryRestMvConfigurationIntegrationTests { @Test public void registeredHttpMessageConvertersAreTypeConstrained() { - Collection converters = context.getBeansOfType( - MappingJackson2HttpMessageConverter.class).values(); + Collection converters = context + .getBeansOfType(MappingJackson2HttpMessageConverter.class).values(); for (HttpMessageConverter converter : converters) { - assertThat(converter, is(instanceOf(TypeConstrainedMappingJackson2HttpMessageConverter.class))); + assertThat(converter, is(anyOf(instanceOf(TypeConstrainedMappingJackson2HttpMessageConverter.class), + instanceOf(AlpsJsonHttpMessageConverter.class)))); } }