DATAREST-597 - Improved AlpsJsonHttpMessageConverter for Spring 4.2 compatibility.
AlpsJsonHttpMessageConverter now implements ResponseBodyAdvice to apply the potentially necessary conversion from RootResourceInformation to Alps to make sure we also get it applied on latest Spring 4.2 snapshots that invoke a newly introduced method to handle generic types in Jackson marshaling.
This commit is contained in:
@@ -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<Object> {
|
||||
|
||||
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<? extends HttpMessageConverter<?>> 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<? extends HttpMessageConverter<?>> converterType) {
|
||||
return converterType.equals(AlpsJsonHttpMessageConverter.class);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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.<ResponseBodyAdvice<?>> asList(alpsJsonHttpMessageConverter()));
|
||||
}
|
||||
|
||||
return handlerAdapter;
|
||||
}
|
||||
|
||||
@@ -589,7 +594,7 @@ public class RepositoryRestMvcConfiguration extends HateoasAwareSpringDataWebCon
|
||||
List<HttpMessageConverter<?>> messageConverters = new ArrayList<HttpMessageConverter<?>>();
|
||||
|
||||
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()
|
||||
|
||||
@@ -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<MappingJackson2HttpMessageConverter> converters = context.getBeansOfType(
|
||||
MappingJackson2HttpMessageConverter.class).values();
|
||||
Collection<MappingJackson2HttpMessageConverter> 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))));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user