diff --git a/spring-web-reactive/src/main/java/org/springframework/web/reactive/result/method/annotation/RequestMappingHandlerAdapter.java b/spring-web-reactive/src/main/java/org/springframework/web/reactive/result/method/annotation/RequestMappingHandlerAdapter.java index b6c0ec6848..a049b0dfc7 100644 --- a/spring-web-reactive/src/main/java/org/springframework/web/reactive/result/method/annotation/RequestMappingHandlerAdapter.java +++ b/spring-web-reactive/src/main/java/org/springframework/web/reactive/result/method/annotation/RequestMappingHandlerAdapter.java @@ -17,9 +17,7 @@ package org.springframework.web.reactive.result.method.annotation; import java.lang.reflect.Method; -import java.nio.ByteBuffer; import java.util.ArrayList; -import java.util.Arrays; import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; @@ -34,16 +32,9 @@ import org.springframework.beans.factory.BeanFactoryAware; import org.springframework.beans.factory.InitializingBean; import org.springframework.beans.factory.config.ConfigurableBeanFactory; import org.springframework.core.codec.support.ByteBufferDecoder; -import org.springframework.core.codec.support.ByteBufferEncoder; -import org.springframework.core.codec.support.JacksonJsonDecoder; -import org.springframework.core.codec.support.JacksonJsonEncoder; -import org.springframework.core.codec.support.Jaxb2Decoder; -import org.springframework.core.codec.support.Jaxb2Encoder; -import org.springframework.core.codec.support.JsonObjectDecoder; import org.springframework.core.codec.support.StringDecoder; -import org.springframework.core.codec.support.StringEncoder; import org.springframework.core.convert.ConversionService; -import org.springframework.core.convert.support.DefaultConversionService; +import org.springframework.format.support.DefaultFormattingConversionService; import org.springframework.http.converter.reactive.CodecHttpMessageConverter; import org.springframework.http.converter.reactive.HttpMessageConverter; import org.springframework.ui.ExtendedModelMap; @@ -68,13 +59,20 @@ public class RequestMappingHandlerAdapter implements HandlerAdapter, BeanFactory private final List argumentResolvers = new ArrayList<>(); - private ConversionService conversionService = new DefaultConversionService(); + private final List> messageConverters = new ArrayList<>(); - private final Map, ExceptionHandlerMethodResolver> exceptionHandlerCache = - new ConcurrentHashMap<>(64); + private ConversionService conversionService = new DefaultFormattingConversionService(); private ConfigurableBeanFactory beanFactory; + private final Map, ExceptionHandlerMethodResolver> exceptionHandlerCache = new ConcurrentHashMap<>(64); + + + + public RequestMappingHandlerAdapter() { + this.messageConverters.add(new CodecHttpMessageConverter<>(new ByteBufferDecoder())); + this.messageConverters.add(new CodecHttpMessageConverter<>(new StringDecoder())); + } /** @@ -93,6 +91,18 @@ public class RequestMappingHandlerAdapter implements HandlerAdapter, BeanFactory return this.argumentResolvers; } + public void setMessageConverters(List> messageConverters) { + this.messageConverters.clear(); + this.messageConverters.addAll(messageConverters); + } + + /** + * Provide the message converters to use for argument resolution. + */ + public List> getMessageConverters() { + return this.messageConverters; + } + public void setConversionService(ConversionService conversionService) { this.conversionService = conversionService; } @@ -121,12 +131,12 @@ public class RequestMappingHandlerAdapter implements HandlerAdapter, BeanFactory public void afterPropertiesSet() throws Exception { if (ObjectUtils.isEmpty(this.argumentResolvers)) { - List> converters = Arrays.asList( - new CodecHttpMessageConverter(new ByteBufferEncoder(), new ByteBufferDecoder()), - new CodecHttpMessageConverter(new StringEncoder(), new StringDecoder()), - new CodecHttpMessageConverter(new Jaxb2Encoder(), new Jaxb2Decoder()), - new CodecHttpMessageConverter(new JacksonJsonEncoder(), - new JacksonJsonDecoder(new JsonObjectDecoder()))); +// List> converters = Arrays.asList( +// new CodecHttpMessageConverter(new ByteBufferEncoder(), new ByteBufferDecoder()), +// new CodecHttpMessageConverter(new StringEncoder(), new StringDecoder()), +// new CodecHttpMessageConverter(new Jaxb2Encoder(), new Jaxb2Decoder()), +// new CodecHttpMessageConverter(new JacksonJsonEncoder(), +// new JacksonJsonDecoder(new JsonObjectDecoder()))); // Annotation-based argument resolution ConversionService cs = getConversionService(); @@ -134,7 +144,7 @@ public class RequestMappingHandlerAdapter implements HandlerAdapter, BeanFactory this.argumentResolvers.add(new RequestParamMapMethodArgumentResolver()); this.argumentResolvers.add(new PathVariableMethodArgumentResolver(cs, getBeanFactory())); this.argumentResolvers.add(new PathVariableMapMethodArgumentResolver()); - this.argumentResolvers.add(new RequestBodyArgumentResolver(converters, cs)); + this.argumentResolvers.add(new RequestBodyArgumentResolver(getMessageConverters(), cs)); this.argumentResolvers.add(new RequestHeaderMethodArgumentResolver(cs, getBeanFactory())); this.argumentResolvers.add(new RequestHeaderMapMethodArgumentResolver()); this.argumentResolvers.add(new CookieValueMethodArgumentResolver(cs, getBeanFactory())); diff --git a/spring-web-reactive/src/main/java/org/springframework/web/reactive/result/method/annotation/SessionAttributeMethodArgumentResolver.java b/spring-web-reactive/src/main/java/org/springframework/web/reactive/result/method/annotation/SessionAttributeMethodArgumentResolver.java index 153a6166da..a48b3ddb03 100644 --- a/spring-web-reactive/src/main/java/org/springframework/web/reactive/result/method/annotation/SessionAttributeMethodArgumentResolver.java +++ b/spring-web-reactive/src/main/java/org/springframework/web/reactive/result/method/annotation/SessionAttributeMethodArgumentResolver.java @@ -48,7 +48,6 @@ public class SessionAttributeMethodArgumentResolver extends AbstractNamedValueMe return parameter.hasParameterAnnotation(SessionAttribute.class); } - @Override protected NamedValueInfo createNamedValueInfo(MethodParameter parameter) { SessionAttribute annot = parameter.getParameterAnnotation(SessionAttribute.class); diff --git a/spring-web-reactive/src/main/java/org/springframework/web/reactive/result/view/freemarker/FreeMarkerView.java b/spring-web-reactive/src/main/java/org/springframework/web/reactive/result/view/freemarker/FreeMarkerView.java index 8818d87355..8caaa1c9a0 100644 --- a/spring-web-reactive/src/main/java/org/springframework/web/reactive/result/view/freemarker/FreeMarkerView.java +++ b/spring-web-reactive/src/main/java/org/springframework/web/reactive/result/view/freemarker/FreeMarkerView.java @@ -166,6 +166,7 @@ public class FreeMarkerView extends AbstractUrlBasedView { Locale locale = Locale.getDefault(); // TODO DataBuffer dataBuffer = exchange.getResponse().bufferFactory().allocateBuffer(); try { + // TODO: pass charset Writer writer = new OutputStreamWriter(dataBuffer.asOutputStream()); getTemplate(locale).process(freeMarkerModel, writer); } diff --git a/spring-web-reactive/src/test/java/org/springframework/web/reactive/DispatcherHandlerErrorTests.java b/spring-web-reactive/src/test/java/org/springframework/web/reactive/DispatcherHandlerErrorTests.java index c46460627c..02a1cd75d1 100644 --- a/spring-web-reactive/src/test/java/org/springframework/web/reactive/DispatcherHandlerErrorTests.java +++ b/spring-web-reactive/src/test/java/org/springframework/web/reactive/DispatcherHandlerErrorTests.java @@ -32,6 +32,7 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.codec.support.StringDecoder; import org.springframework.core.codec.support.StringEncoder; +import org.springframework.core.convert.ConversionService; import org.springframework.core.convert.support.DefaultConversionService; import org.springframework.core.io.buffer.DataBuffer; import org.springframework.core.io.buffer.DefaultDataBufferFactory; @@ -230,11 +231,9 @@ public class DispatcherHandlerErrorTests { @Bean public ResponseBodyResultHandler resultHandler() { - List> converters = Collections.singletonList( - new CodecHttpMessageConverter<>(new StringEncoder(), - new StringDecoder())); - return new ResponseBodyResultHandler(converters, - new DefaultConversionService()); + HttpMessageConverter converter = new CodecHttpMessageConverter<>(new StringEncoder()); + ConversionService conversionService = new DefaultConversionService(); + return new ResponseBodyResultHandler(Collections.singletonList(converter), conversionService); } @Bean diff --git a/spring-web-reactive/src/test/java/org/springframework/web/reactive/result/method/annotation/RequestMappingIntegrationTests.java b/spring-web-reactive/src/test/java/org/springframework/web/reactive/result/method/annotation/RequestMappingIntegrationTests.java index c85b85acb7..217c52a6c2 100644 --- a/spring-web-reactive/src/test/java/org/springframework/web/reactive/result/method/annotation/RequestMappingIntegrationTests.java +++ b/spring-web-reactive/src/test/java/org/springframework/web/reactive/result/method/annotation/RequestMappingIntegrationTests.java @@ -44,6 +44,9 @@ import org.springframework.core.codec.support.ByteBufferDecoder; import org.springframework.core.codec.support.ByteBufferEncoder; import org.springframework.core.codec.support.JacksonJsonDecoder; import org.springframework.core.codec.support.JacksonJsonEncoder; +import org.springframework.core.codec.support.Jaxb2Decoder; +import org.springframework.core.codec.support.Jaxb2Encoder; +import org.springframework.core.codec.support.JsonObjectDecoder; import org.springframework.core.codec.support.StringDecoder; import org.springframework.core.codec.support.StringEncoder; import org.springframework.core.convert.ConversionService; @@ -392,10 +395,20 @@ public class RequestMappingIntegrationTests extends AbstractHttpHandlerIntegrati @Bean public RequestMappingHandlerAdapter handlerAdapter() { RequestMappingHandlerAdapter handlerAdapter = new RequestMappingHandlerAdapter(); + handlerAdapter.setMessageConverters(getDefaultMessageConverters()); handlerAdapter.setConversionService(conversionService()); return handlerAdapter; } + private List> getDefaultMessageConverters() { + return Arrays.asList( + new CodecHttpMessageConverter<>(new ByteBufferEncoder(), new ByteBufferDecoder()), + new CodecHttpMessageConverter<>(new StringEncoder(), new StringDecoder()), + new CodecHttpMessageConverter<>(new Jaxb2Encoder(), new Jaxb2Decoder()), + new CodecHttpMessageConverter<>(new JacksonJsonEncoder(), + new JacksonJsonDecoder(new JsonObjectDecoder()))); + } + @Bean public ConversionService conversionService() { // TODO: test failures with DefaultConversionService @@ -407,11 +420,9 @@ public class RequestMappingIntegrationTests extends AbstractHttpHandlerIntegrati @Bean public ResponseBodyResultHandler responseBodyResultHandler() { - List> converters = Arrays.asList( - new ResourceHttpMessageConverter(), - new CodecHttpMessageConverter<>(new ByteBufferEncoder(), new ByteBufferDecoder()), - new CodecHttpMessageConverter<>(new StringEncoder(), new StringDecoder()), - new CodecHttpMessageConverter<>(new JacksonJsonEncoder(), new JacksonJsonDecoder())); + List> converters = new ArrayList<>(); + converters.add(new ResourceHttpMessageConverter()); + converters.addAll(getDefaultMessageConverters()); return new ResponseBodyResultHandler(converters, conversionService()); }