Rename ResponseBodyInterceptor to ResponseBodyAdvice
Issue: SPR-10859
This commit is contained in:
parent
2655c507e0
commit
c9d0ebd730
|
@ -19,7 +19,7 @@ package org.springframework.web.servlet.config;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
|
|
||||||
import org.springframework.web.servlet.mvc.method.annotation.JsonViewResponseBodyInterceptor;
|
import org.springframework.web.servlet.mvc.method.annotation.JsonViewResponseBodyAdvice;
|
||||||
import org.springframework.http.converter.json.GsonHttpMessageConverter;
|
import org.springframework.http.converter.json.GsonHttpMessageConverter;
|
||||||
import org.w3c.dom.Element;
|
import org.w3c.dom.Element;
|
||||||
|
|
||||||
|
@ -201,7 +201,7 @@ class AnnotationDrivenBeanDefinitionParser implements BeanDefinitionParser {
|
||||||
handlerAdapterDef.getPropertyValues().add("contentNegotiationManager", contentNegotiationManager);
|
handlerAdapterDef.getPropertyValues().add("contentNegotiationManager", contentNegotiationManager);
|
||||||
handlerAdapterDef.getPropertyValues().add("webBindingInitializer", bindingDef);
|
handlerAdapterDef.getPropertyValues().add("webBindingInitializer", bindingDef);
|
||||||
handlerAdapterDef.getPropertyValues().add("messageConverters", messageConverters);
|
handlerAdapterDef.getPropertyValues().add("messageConverters", messageConverters);
|
||||||
addResponseBodyInterceptors(handlerAdapterDef);
|
addResponseBodyAdvice(handlerAdapterDef);
|
||||||
|
|
||||||
if (element.hasAttribute("ignore-default-model-on-redirect")) {
|
if (element.hasAttribute("ignore-default-model-on-redirect")) {
|
||||||
Boolean ignoreDefaultModel = Boolean.valueOf(element.getAttribute("ignore-default-model-on-redirect"));
|
Boolean ignoreDefaultModel = Boolean.valueOf(element.getAttribute("ignore-default-model-on-redirect"));
|
||||||
|
@ -253,7 +253,7 @@ class AnnotationDrivenBeanDefinitionParser implements BeanDefinitionParser {
|
||||||
exceptionHandlerExceptionResolver.getPropertyValues().add("contentNegotiationManager", contentNegotiationManager);
|
exceptionHandlerExceptionResolver.getPropertyValues().add("contentNegotiationManager", contentNegotiationManager);
|
||||||
exceptionHandlerExceptionResolver.getPropertyValues().add("messageConverters", messageConverters);
|
exceptionHandlerExceptionResolver.getPropertyValues().add("messageConverters", messageConverters);
|
||||||
exceptionHandlerExceptionResolver.getPropertyValues().add("order", 0);
|
exceptionHandlerExceptionResolver.getPropertyValues().add("order", 0);
|
||||||
addResponseBodyInterceptors(exceptionHandlerExceptionResolver);
|
addResponseBodyAdvice(exceptionHandlerExceptionResolver);
|
||||||
|
|
||||||
String methodExceptionResolverName =
|
String methodExceptionResolverName =
|
||||||
parserContext.getReaderContext().registerWithGeneratedName(exceptionHandlerExceptionResolver);
|
parserContext.getReaderContext().registerWithGeneratedName(exceptionHandlerExceptionResolver);
|
||||||
|
@ -288,10 +288,10 @@ class AnnotationDrivenBeanDefinitionParser implements BeanDefinitionParser {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void addResponseBodyInterceptors(RootBeanDefinition beanDef) {
|
protected void addResponseBodyAdvice(RootBeanDefinition beanDef) {
|
||||||
if (jackson2Present) {
|
if (jackson2Present) {
|
||||||
beanDef.getPropertyValues().add("responseBodyInterceptors",
|
beanDef.getPropertyValues().add("responseBodyAdvice",
|
||||||
new RootBeanDefinition(JsonViewResponseBodyInterceptor.class));
|
new RootBeanDefinition(JsonViewResponseBodyAdvice.class));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,6 @@
|
||||||
package org.springframework.web.servlet.config.annotation;
|
package org.springframework.web.servlet.config.annotation;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
@ -76,10 +75,10 @@ import org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter;
|
||||||
import org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter;
|
import org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter;
|
||||||
import org.springframework.web.servlet.mvc.annotation.ResponseStatusExceptionResolver;
|
import org.springframework.web.servlet.mvc.annotation.ResponseStatusExceptionResolver;
|
||||||
import org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver;
|
import org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver;
|
||||||
import org.springframework.web.servlet.mvc.method.annotation.JsonViewResponseBodyInterceptor;
|
import org.springframework.web.servlet.mvc.method.annotation.JsonViewResponseBodyAdvice;
|
||||||
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter;
|
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter;
|
||||||
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;
|
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;
|
||||||
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyInterceptor;
|
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;
|
||||||
import org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver;
|
import org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver;
|
||||||
import org.springframework.web.servlet.resource.ResourceUrlProvider;
|
import org.springframework.web.servlet.resource.ResourceUrlProvider;
|
||||||
import org.springframework.web.servlet.resource.ResourceUrlProviderExposingInterceptor;
|
import org.springframework.web.servlet.resource.ResourceUrlProviderExposingInterceptor;
|
||||||
|
@ -425,9 +424,9 @@ public class WebMvcConfigurationSupport implements ApplicationContextAware, Serv
|
||||||
adapter.setCustomReturnValueHandlers(returnValueHandlers);
|
adapter.setCustomReturnValueHandlers(returnValueHandlers);
|
||||||
|
|
||||||
if (jackson2Present) {
|
if (jackson2Present) {
|
||||||
List<ResponseBodyInterceptor<?>> interceptors = new ArrayList<ResponseBodyInterceptor<?>>();
|
List<ResponseBodyAdvice<?>> interceptors = new ArrayList<ResponseBodyAdvice<?>>();
|
||||||
interceptors.add(new JsonViewResponseBodyInterceptor());
|
interceptors.add(new JsonViewResponseBodyAdvice());
|
||||||
adapter.setResponseBodyInterceptors(interceptors);
|
adapter.setResponseBodyAdvice(interceptors);
|
||||||
}
|
}
|
||||||
|
|
||||||
AsyncSupportConfigurer configurer = new AsyncSupportConfigurer();
|
AsyncSupportConfigurer configurer = new AsyncSupportConfigurer();
|
||||||
|
@ -712,9 +711,9 @@ public class WebMvcConfigurationSupport implements ApplicationContextAware, Serv
|
||||||
exceptionHandlerExceptionResolver.setContentNegotiationManager(mvcContentNegotiationManager());
|
exceptionHandlerExceptionResolver.setContentNegotiationManager(mvcContentNegotiationManager());
|
||||||
exceptionHandlerExceptionResolver.setMessageConverters(getMessageConverters());
|
exceptionHandlerExceptionResolver.setMessageConverters(getMessageConverters());
|
||||||
if (jackson2Present) {
|
if (jackson2Present) {
|
||||||
List<ResponseBodyInterceptor<?>> interceptors = new ArrayList<ResponseBodyInterceptor<?>>();
|
List<ResponseBodyAdvice<?>> interceptors = new ArrayList<ResponseBodyAdvice<?>>();
|
||||||
interceptors.add(new JsonViewResponseBodyInterceptor());
|
interceptors.add(new JsonViewResponseBodyAdvice());
|
||||||
exceptionHandlerExceptionResolver.setResponseBodyInterceptors(interceptors);
|
exceptionHandlerExceptionResolver.setResponseBodyAdvice(interceptors);
|
||||||
}
|
}
|
||||||
exceptionHandlerExceptionResolver.afterPropertiesSet();
|
exceptionHandlerExceptionResolver.afterPropertiesSet();
|
||||||
|
|
||||||
|
|
|
@ -29,7 +29,7 @@ import javax.servlet.http.HttpServletRequest;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A convenient base class for a {@code ResponseBodyInterceptor} to instruct the
|
* A convenient base class for a {@code ResponseBodyAdvice} to instruct the
|
||||||
* {@link org.springframework.http.converter.json.MappingJackson2HttpMessageConverter
|
* {@link org.springframework.http.converter.json.MappingJackson2HttpMessageConverter
|
||||||
* MappingJackson2HttpMessageConverter} to serialize with JSONP formatting.
|
* MappingJackson2HttpMessageConverter} to serialize with JSONP formatting.
|
||||||
*
|
*
|
||||||
|
@ -43,12 +43,12 @@ import java.util.Collection;
|
||||||
* @author Rossen Stoyanchev
|
* @author Rossen Stoyanchev
|
||||||
* @since 4.1
|
* @since 4.1
|
||||||
*/
|
*/
|
||||||
public abstract class AbstractJsonpResponseBodyInterceptor extends AbstractMappingJacksonResponseBodyInterceptor {
|
public abstract class AbstractJsonpResponseBodyAdvice extends AbstractMappingJacksonResponseBodyAdvice {
|
||||||
|
|
||||||
private final String[] jsonpQueryParamNames;
|
private final String[] jsonpQueryParamNames;
|
||||||
|
|
||||||
|
|
||||||
protected AbstractJsonpResponseBodyInterceptor(Collection<String> queryParamNames) {
|
protected AbstractJsonpResponseBodyAdvice(Collection<String> queryParamNames) {
|
||||||
Assert.isTrue(!CollectionUtils.isEmpty(queryParamNames), "At least one query param name is required");
|
Assert.isTrue(!CollectionUtils.isEmpty(queryParamNames), "At least one query param name is required");
|
||||||
this.jsonpQueryParamNames = queryParamNames.toArray(new String[queryParamNames.size()]);
|
this.jsonpQueryParamNames = queryParamNames.toArray(new String[queryParamNames.size()]);
|
||||||
}
|
}
|
|
@ -25,7 +25,7 @@ import org.springframework.http.server.ServerHttpRequest;
|
||||||
import org.springframework.http.server.ServerHttpResponse;
|
import org.springframework.http.server.ServerHttpResponse;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A convenient base class for {@code ResponseBodyInterceptor} implementations
|
* A convenient base class for {@code ResponseBodyAdvice} implementations
|
||||||
* that customize the response before JSON serialization with
|
* that customize the response before JSON serialization with
|
||||||
* {@link org.springframework.http.converter.json.MappingJackson2HttpMessageConverter
|
* {@link org.springframework.http.converter.json.MappingJackson2HttpMessageConverter
|
||||||
* MappingJackson2HttpMessageConverter}.
|
* MappingJackson2HttpMessageConverter}.
|
||||||
|
@ -33,11 +33,11 @@ import org.springframework.http.server.ServerHttpResponse;
|
||||||
* @author Rossen Stoyanchev
|
* @author Rossen Stoyanchev
|
||||||
* @since 4.1
|
* @since 4.1
|
||||||
*/
|
*/
|
||||||
public abstract class AbstractMappingJacksonResponseBodyInterceptor
|
public abstract class AbstractMappingJacksonResponseBodyAdvice
|
||||||
implements ResponseBodyInterceptor<Object> {
|
implements ResponseBodyAdvice<Object> {
|
||||||
|
|
||||||
|
|
||||||
protected AbstractMappingJacksonResponseBodyInterceptor() {
|
protected AbstractMappingJacksonResponseBodyAdvice() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -31,7 +31,6 @@ import org.springframework.http.MediaType;
|
||||||
import org.springframework.http.converter.HttpMessageConverter;
|
import org.springframework.http.converter.HttpMessageConverter;
|
||||||
import org.springframework.http.server.ServletServerHttpRequest;
|
import org.springframework.http.server.ServletServerHttpRequest;
|
||||||
import org.springframework.http.server.ServletServerHttpResponse;
|
import org.springframework.http.server.ServletServerHttpResponse;
|
||||||
import org.springframework.util.ClassUtils;
|
|
||||||
import org.springframework.util.CollectionUtils;
|
import org.springframework.util.CollectionUtils;
|
||||||
import org.springframework.web.HttpMediaTypeNotAcceptableException;
|
import org.springframework.web.HttpMediaTypeNotAcceptableException;
|
||||||
import org.springframework.web.accept.ContentNegotiationManager;
|
import org.springframework.web.accept.ContentNegotiationManager;
|
||||||
|
@ -55,7 +54,7 @@ public abstract class AbstractMessageConverterMethodProcessor extends AbstractMe
|
||||||
|
|
||||||
private final ContentNegotiationManager contentNegotiationManager;
|
private final ContentNegotiationManager contentNegotiationManager;
|
||||||
|
|
||||||
private final ResponseBodyInterceptorChain interceptorChain;
|
private final ResponseBodyAdviceChain adviceChain;
|
||||||
|
|
||||||
|
|
||||||
protected AbstractMessageConverterMethodProcessor(List<HttpMessageConverter<?>> messageConverters) {
|
protected AbstractMessageConverterMethodProcessor(List<HttpMessageConverter<?>> messageConverters) {
|
||||||
|
@ -68,11 +67,11 @@ public abstract class AbstractMessageConverterMethodProcessor extends AbstractMe
|
||||||
}
|
}
|
||||||
|
|
||||||
protected AbstractMessageConverterMethodProcessor(List<HttpMessageConverter<?>> messageConverters,
|
protected AbstractMessageConverterMethodProcessor(List<HttpMessageConverter<?>> messageConverters,
|
||||||
ContentNegotiationManager manager, List<Object> responseBodyInterceptors) {
|
ContentNegotiationManager manager, List<Object> responseBodyAdvice) {
|
||||||
|
|
||||||
super(messageConverters);
|
super(messageConverters);
|
||||||
this.contentNegotiationManager = (manager != null ? manager : new ContentNegotiationManager());
|
this.contentNegotiationManager = (manager != null ? manager : new ContentNegotiationManager());
|
||||||
this.interceptorChain = new ResponseBodyInterceptorChain(responseBodyInterceptors);
|
this.adviceChain = new ResponseBodyAdviceChain(responseBodyAdvice);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -149,7 +148,7 @@ public abstract class AbstractMessageConverterMethodProcessor extends AbstractMe
|
||||||
selectedMediaType = selectedMediaType.removeQualityValue();
|
selectedMediaType = selectedMediaType.removeQualityValue();
|
||||||
for (HttpMessageConverter<?> messageConverter : this.messageConverters) {
|
for (HttpMessageConverter<?> messageConverter : this.messageConverters) {
|
||||||
if (messageConverter.canWrite(returnValueClass, selectedMediaType)) {
|
if (messageConverter.canWrite(returnValueClass, selectedMediaType)) {
|
||||||
returnValue = this.interceptorChain.invoke(returnValue, returnType, selectedMediaType,
|
returnValue = this.adviceChain.invoke(returnValue, returnType, selectedMediaType,
|
||||||
(Class<HttpMessageConverter<?>>) messageConverter.getClass(), inputMessage, outputMessage);
|
(Class<HttpMessageConverter<?>>) messageConverter.getClass(), inputMessage, outputMessage);
|
||||||
((HttpMessageConverter<T>) messageConverter).write(returnValue, selectedMediaType, outputMessage);
|
((HttpMessageConverter<T>) messageConverter).write(returnValue, selectedMediaType, outputMessage);
|
||||||
if (logger.isDebugEnabled()) {
|
if (logger.isDebugEnabled()) {
|
||||||
|
|
|
@ -79,7 +79,7 @@ public class ExceptionHandlerExceptionResolver extends AbstractHandlerMethodExce
|
||||||
|
|
||||||
private ContentNegotiationManager contentNegotiationManager = new ContentNegotiationManager();
|
private ContentNegotiationManager contentNegotiationManager = new ContentNegotiationManager();
|
||||||
|
|
||||||
private final List<Object> responseBodyInterceptors = new ArrayList<Object>();
|
private final List<Object> responseBodyAdvice = new ArrayList<Object>();
|
||||||
|
|
||||||
|
|
||||||
private final Map<Class<?>, ExceptionHandlerMethodResolver> exceptionHandlerCache =
|
private final Map<Class<?>, ExceptionHandlerMethodResolver> exceptionHandlerCache =
|
||||||
|
@ -110,15 +110,15 @@ public class ExceptionHandlerExceptionResolver extends AbstractHandlerMethodExce
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add one or more interceptors to be invoked after the execution of a controller
|
* Add one or more components to be invoked after the execution of a controller
|
||||||
* method annotated with {@code @ResponseBody} or returning {@code ResponseEntity}
|
* method annotated with {@code @ResponseBody} or returning {@code ResponseEntity}
|
||||||
* but before the body is written to the response with the selected
|
* but before the body is written to the response with the selected
|
||||||
* {@code HttpMessageConverter}.
|
* {@code HttpMessageConverter}.
|
||||||
*/
|
*/
|
||||||
public void setResponseBodyInterceptors(List<ResponseBodyInterceptor<?>> responseBodyInterceptors) {
|
public void setResponseBodyAdvice(List<ResponseBodyAdvice<?>> responseBodyAdvice) {
|
||||||
this.responseBodyInterceptors.clear();
|
this.responseBodyAdvice.clear();
|
||||||
if (responseBodyInterceptors != null) {
|
if (responseBodyAdvice != null) {
|
||||||
this.responseBodyInterceptors.addAll(responseBodyInterceptors);
|
this.responseBodyAdvice.addAll(responseBodyAdvice);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -250,7 +250,7 @@ public class ExceptionHandlerExceptionResolver extends AbstractHandlerMethodExce
|
||||||
@Override
|
@Override
|
||||||
public void afterPropertiesSet() {
|
public void afterPropertiesSet() {
|
||||||
|
|
||||||
// Do this first, it may add ResponseBody interceptors
|
// Do this first, it may add ResponseBodyAdvice beans
|
||||||
initExceptionHandlerAdviceCache();
|
initExceptionHandlerAdviceCache();
|
||||||
|
|
||||||
if (this.argumentResolvers == null) {
|
if (this.argumentResolvers == null) {
|
||||||
|
@ -271,18 +271,18 @@ public class ExceptionHandlerExceptionResolver extends AbstractHandlerMethodExce
|
||||||
logger.debug("Looking for exception mappings: " + getApplicationContext());
|
logger.debug("Looking for exception mappings: " + getApplicationContext());
|
||||||
}
|
}
|
||||||
|
|
||||||
List<ControllerAdviceBean> beans = ControllerAdviceBean.findAnnotatedBeans(getApplicationContext());
|
List<ControllerAdviceBean> adviceBeans = ControllerAdviceBean.findAnnotatedBeans(getApplicationContext());
|
||||||
Collections.sort(beans, new OrderComparator());
|
Collections.sort(adviceBeans, new OrderComparator());
|
||||||
|
|
||||||
for (ControllerAdviceBean bean : beans) {
|
for (ControllerAdviceBean adviceBean : adviceBeans) {
|
||||||
ExceptionHandlerMethodResolver resolver = new ExceptionHandlerMethodResolver(bean.getBeanType());
|
ExceptionHandlerMethodResolver resolver = new ExceptionHandlerMethodResolver(adviceBean.getBeanType());
|
||||||
if (resolver.hasExceptionMappings()) {
|
if (resolver.hasExceptionMappings()) {
|
||||||
this.exceptionHandlerAdviceCache.put(bean, resolver);
|
this.exceptionHandlerAdviceCache.put(adviceBean, resolver);
|
||||||
logger.info("Detected @ExceptionHandler methods in " + bean);
|
logger.info("Detected @ExceptionHandler methods in " + adviceBean);
|
||||||
}
|
}
|
||||||
if (ResponseBodyInterceptor.class.isAssignableFrom(bean.getBeanType())) {
|
if (ResponseBodyAdvice.class.isAssignableFrom(adviceBean.getBeanType())) {
|
||||||
this.responseBodyInterceptors.add(bean);
|
this.responseBodyAdvice.add(adviceBean);
|
||||||
logger.info("Detected ResponseBodyInterceptor implementation in " + bean);
|
logger.info("Detected ResponseBodyAdvice implementation in " + adviceBean);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -318,12 +318,12 @@ public class ExceptionHandlerExceptionResolver extends AbstractHandlerMethodExce
|
||||||
handlers.add(new ModelMethodProcessor());
|
handlers.add(new ModelMethodProcessor());
|
||||||
handlers.add(new ViewMethodReturnValueHandler());
|
handlers.add(new ViewMethodReturnValueHandler());
|
||||||
handlers.add(new HttpEntityMethodProcessor(
|
handlers.add(new HttpEntityMethodProcessor(
|
||||||
getMessageConverters(), this.contentNegotiationManager, this.responseBodyInterceptors));
|
getMessageConverters(), this.contentNegotiationManager, this.responseBodyAdvice));
|
||||||
|
|
||||||
// Annotation-based return value types
|
// Annotation-based return value types
|
||||||
handlers.add(new ModelAttributeMethodProcessor(false));
|
handlers.add(new ModelAttributeMethodProcessor(false));
|
||||||
handlers.add(new RequestResponseBodyMethodProcessor(
|
handlers.add(new RequestResponseBodyMethodProcessor(
|
||||||
getMessageConverters(), this.contentNegotiationManager, this.responseBodyInterceptors));
|
getMessageConverters(), this.contentNegotiationManager, this.responseBodyAdvice));
|
||||||
|
|
||||||
// Multi-purpose return value types
|
// Multi-purpose return value types
|
||||||
handlers.add(new ViewNameMethodReturnValueHandler());
|
handlers.add(new ViewNameMethodReturnValueHandler());
|
||||||
|
|
|
@ -61,8 +61,8 @@ public class HttpEntityMethodProcessor extends AbstractMessageConverterMethodPro
|
||||||
}
|
}
|
||||||
|
|
||||||
public HttpEntityMethodProcessor(List<HttpMessageConverter<?>> messageConverters,
|
public HttpEntityMethodProcessor(List<HttpMessageConverter<?>> messageConverters,
|
||||||
ContentNegotiationManager contentNegotiationManager, List<Object> responseBodyInterceptors) {
|
ContentNegotiationManager contentNegotiationManager, List<Object> responseBodyAdvice) {
|
||||||
super(messageConverters, contentNegotiationManager, responseBodyInterceptors);
|
super(messageConverters, contentNegotiationManager, responseBodyAdvice);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -26,7 +26,7 @@ import org.springframework.http.server.ServerHttpResponse;
|
||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A {@code ResponseBodyInterceptor} implementation that adds support for
|
* A {@code ResponseBodyAdvice} implementation that adds support for
|
||||||
* Jackson's {@code @JsonView} annotation declared on a Spring MVC
|
* Jackson's {@code @JsonView} annotation declared on a Spring MVC
|
||||||
* {@code @RequestMapping} or {@code @ExceptionHandler} method. The serialization
|
* {@code @RequestMapping} or {@code @ExceptionHandler} method. The serialization
|
||||||
* view specified in the annotation will be passed in to the
|
* view specified in the annotation will be passed in to the
|
||||||
|
@ -38,7 +38,7 @@ import org.springframework.util.Assert;
|
||||||
*
|
*
|
||||||
* @see com.fasterxml.jackson.databind.ObjectMapper#writerWithView(Class)
|
* @see com.fasterxml.jackson.databind.ObjectMapper#writerWithView(Class)
|
||||||
*/
|
*/
|
||||||
public class JsonViewResponseBodyInterceptor extends AbstractMappingJacksonResponseBodyInterceptor {
|
public class JsonViewResponseBodyAdvice extends AbstractMappingJacksonResponseBodyAdvice {
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
|
@ -132,7 +132,7 @@ public class RequestMappingHandlerAdapter extends AbstractHandlerMethodAdapter
|
||||||
|
|
||||||
private List<HttpMessageConverter<?>> messageConverters;
|
private List<HttpMessageConverter<?>> messageConverters;
|
||||||
|
|
||||||
private List<Object> responseBodyInterceptors = new ArrayList<Object>();
|
private List<Object> responseBodyAdvice = new ArrayList<Object>();
|
||||||
|
|
||||||
private WebBindingInitializer webBindingInitializer;
|
private WebBindingInitializer webBindingInitializer;
|
||||||
|
|
||||||
|
@ -334,15 +334,15 @@ public class RequestMappingHandlerAdapter extends AbstractHandlerMethodAdapter
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add one or more interceptors to be invoked after the execution of a controller
|
* Add one or more components to modify the response after the execution of a
|
||||||
* method annotated with {@code @ResponseBody} or returning {@code ResponseEntity}
|
* controller method annotated with {@code @ResponseBody}, or a method returning
|
||||||
* but before the body is written to the response with the selected
|
* {@code ResponseEntity} and before the body is written to the response with
|
||||||
* {@code HttpMessageConverter}.
|
* the selected {@code HttpMessageConverter}.
|
||||||
*/
|
*/
|
||||||
public void setResponseBodyInterceptors(List<ResponseBodyInterceptor<?>> responseBodyInterceptors) {
|
public void setResponseBodyAdvice(List<ResponseBodyAdvice<?>> responseBodyAdvice) {
|
||||||
this.responseBodyInterceptors.clear();
|
this.responseBodyAdvice.clear();
|
||||||
if (responseBodyInterceptors != null) {
|
if (responseBodyAdvice != null) {
|
||||||
this.responseBodyInterceptors.addAll(responseBodyInterceptors);
|
this.responseBodyAdvice.addAll(responseBodyAdvice);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -498,7 +498,7 @@ public class RequestMappingHandlerAdapter extends AbstractHandlerMethodAdapter
|
||||||
@Override
|
@Override
|
||||||
public void afterPropertiesSet() {
|
public void afterPropertiesSet() {
|
||||||
|
|
||||||
// Do this first, it may add ResponseBody interceptors
|
// Do this first, it may add ResponseBody advice beans
|
||||||
initControllerAdviceCache();
|
initControllerAdviceCache();
|
||||||
|
|
||||||
if (this.argumentResolvers == null) {
|
if (this.argumentResolvers == null) {
|
||||||
|
@ -526,7 +526,7 @@ public class RequestMappingHandlerAdapter extends AbstractHandlerMethodAdapter
|
||||||
List<ControllerAdviceBean> beans = ControllerAdviceBean.findAnnotatedBeans(getApplicationContext());
|
List<ControllerAdviceBean> beans = ControllerAdviceBean.findAnnotatedBeans(getApplicationContext());
|
||||||
Collections.sort(beans, new OrderComparator());
|
Collections.sort(beans, new OrderComparator());
|
||||||
|
|
||||||
List<Object> interceptorBeans = new ArrayList<Object>();
|
List<Object> responseBodyAdviceBeans = new ArrayList<Object>();
|
||||||
|
|
||||||
for (ControllerAdviceBean bean : beans) {
|
for (ControllerAdviceBean bean : beans) {
|
||||||
Set<Method> attrMethods = HandlerMethodSelector.selectMethods(bean.getBeanType(), MODEL_ATTRIBUTE_METHODS);
|
Set<Method> attrMethods = HandlerMethodSelector.selectMethods(bean.getBeanType(), MODEL_ATTRIBUTE_METHODS);
|
||||||
|
@ -539,14 +539,14 @@ public class RequestMappingHandlerAdapter extends AbstractHandlerMethodAdapter
|
||||||
this.initBinderAdviceCache.put(bean, binderMethods);
|
this.initBinderAdviceCache.put(bean, binderMethods);
|
||||||
logger.info("Detected @InitBinder methods in " + bean);
|
logger.info("Detected @InitBinder methods in " + bean);
|
||||||
}
|
}
|
||||||
if (ResponseBodyInterceptor.class.isAssignableFrom(bean.getBeanType())) {
|
if (ResponseBodyAdvice.class.isAssignableFrom(bean.getBeanType())) {
|
||||||
interceptorBeans.add(bean);
|
responseBodyAdviceBeans.add(bean);
|
||||||
logger.info("Detected ResponseBodyInterceptor implementation in " + bean);
|
logger.info("Detected ResponseBodyAdvice bean in " + bean);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!interceptorBeans.isEmpty()) {
|
if (!responseBodyAdviceBeans.isEmpty()) {
|
||||||
this.responseBodyInterceptors.addAll(0, interceptorBeans);
|
this.responseBodyAdvice.addAll(0, responseBodyAdviceBeans);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -638,7 +638,7 @@ public class RequestMappingHandlerAdapter extends AbstractHandlerMethodAdapter
|
||||||
handlers.add(new ModelMethodProcessor());
|
handlers.add(new ModelMethodProcessor());
|
||||||
handlers.add(new ViewMethodReturnValueHandler());
|
handlers.add(new ViewMethodReturnValueHandler());
|
||||||
handlers.add(new HttpEntityMethodProcessor(
|
handlers.add(new HttpEntityMethodProcessor(
|
||||||
getMessageConverters(), this.contentNegotiationManager, this.responseBodyInterceptors));
|
getMessageConverters(), this.contentNegotiationManager, this.responseBodyAdvice));
|
||||||
handlers.add(new HttpHeadersReturnValueHandler());
|
handlers.add(new HttpHeadersReturnValueHandler());
|
||||||
handlers.add(new CallableMethodReturnValueHandler());
|
handlers.add(new CallableMethodReturnValueHandler());
|
||||||
handlers.add(new DeferredResultMethodReturnValueHandler());
|
handlers.add(new DeferredResultMethodReturnValueHandler());
|
||||||
|
@ -648,7 +648,7 @@ public class RequestMappingHandlerAdapter extends AbstractHandlerMethodAdapter
|
||||||
// Annotation-based return value types
|
// Annotation-based return value types
|
||||||
handlers.add(new ModelAttributeMethodProcessor(false));
|
handlers.add(new ModelAttributeMethodProcessor(false));
|
||||||
handlers.add(new RequestResponseBodyMethodProcessor(
|
handlers.add(new RequestResponseBodyMethodProcessor(
|
||||||
getMessageConverters(), this.contentNegotiationManager, this.responseBodyInterceptors));
|
getMessageConverters(), this.contentNegotiationManager, this.responseBodyAdvice));
|
||||||
|
|
||||||
// Multi-purpose return value types
|
// Multi-purpose return value types
|
||||||
handlers.add(new ViewNameMethodReturnValueHandler());
|
handlers.add(new ViewNameMethodReturnValueHandler());
|
||||||
|
|
|
@ -73,8 +73,8 @@ public class RequestResponseBodyMethodProcessor extends AbstractMessageConverter
|
||||||
}
|
}
|
||||||
|
|
||||||
public RequestResponseBodyMethodProcessor(List<HttpMessageConverter<?>> messageConverters,
|
public RequestResponseBodyMethodProcessor(List<HttpMessageConverter<?>> messageConverters,
|
||||||
ContentNegotiationManager contentNegotiationManager, List<Object> responseBodyInterceptors) {
|
ContentNegotiationManager contentNegotiationManager, List<Object> responseBodyAdvice) {
|
||||||
super(messageConverters, contentNegotiationManager, responseBodyInterceptors);
|
super(messageConverters, contentNegotiationManager, responseBodyAdvice);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -27,13 +27,18 @@ import org.springframework.http.server.ServerHttpResponse;
|
||||||
* or an {@code ResponseEntity} controller method but before the body is written
|
* or an {@code ResponseEntity} controller method but before the body is written
|
||||||
* with an {@code HttpMessageConverter}.
|
* with an {@code HttpMessageConverter}.
|
||||||
*
|
*
|
||||||
|
* <p>Implementations may be may be registered directly with
|
||||||
|
* {@code RequestMappingHandlerAdapter} and {@code ExceptionHandlerExceptionResolver}
|
||||||
|
* or more likely annotated with {@code @ControllerAdvice} in which case they
|
||||||
|
* will be auto-detected by both.
|
||||||
|
*
|
||||||
* @author Rossen Stoyanchev
|
* @author Rossen Stoyanchev
|
||||||
* @since 4.1
|
* @since 4.1
|
||||||
*/
|
*/
|
||||||
public interface ResponseBodyInterceptor<T> {
|
public interface ResponseBodyAdvice<T> {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Whether this interceptor supports the given controller method return type
|
* Whether this component supports the given controller method return type
|
||||||
* and the selected {@code HttpMessageConverter} type.
|
* and the selected {@code HttpMessageConverter} type.
|
||||||
*
|
*
|
||||||
* @param returnType the return type
|
* @param returnType the return type
|
|
@ -28,20 +28,20 @@ import org.springframework.web.method.ControllerAdviceBean;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Invokes a a list of ResponseBodyInterceptor's.
|
* Invokes a a list of {@link ResponseBodyAdvice} beans.
|
||||||
*
|
*
|
||||||
* @author Rossen Stoyanchev
|
* @author Rossen Stoyanchev
|
||||||
* @since 4.1
|
* @since 4.1
|
||||||
*/
|
*/
|
||||||
class ResponseBodyInterceptorChain {
|
class ResponseBodyAdviceChain {
|
||||||
|
|
||||||
private static Log logger = LogFactory.getLog(ResponseBodyInterceptorChain.class);
|
private static Log logger = LogFactory.getLog(ResponseBodyAdviceChain.class);
|
||||||
|
|
||||||
private final List<Object> interceptors;
|
private final List<Object> advice;
|
||||||
|
|
||||||
|
|
||||||
public ResponseBodyInterceptorChain(List<Object> interceptors) {
|
public ResponseBodyAdviceChain(List<Object> advice) {
|
||||||
this.interceptors = interceptors;
|
this.advice = advice;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -50,31 +50,31 @@ class ResponseBodyInterceptorChain {
|
||||||
MediaType selectedContentType, Class<? extends HttpMessageConverter<?>> selectedConverterType,
|
MediaType selectedContentType, Class<? extends HttpMessageConverter<?>> selectedConverterType,
|
||||||
ServerHttpRequest request, ServerHttpResponse response) {
|
ServerHttpRequest request, ServerHttpResponse response) {
|
||||||
|
|
||||||
if (this.interceptors != null) {
|
if (this.advice != null) {
|
||||||
if (logger.isDebugEnabled()) {
|
if (logger.isDebugEnabled()) {
|
||||||
logger.debug("Invoking ResponseBody interceptor chain for body=" + body);
|
logger.debug("Invoking ResponseBodyAdvice chain for body=" + body);
|
||||||
}
|
}
|
||||||
for (Object interceptor : this.interceptors) {
|
for (Object advice : this.advice) {
|
||||||
if (interceptor instanceof ControllerAdviceBean) {
|
if (advice instanceof ControllerAdviceBean) {
|
||||||
ControllerAdviceBean adviceBean = (ControllerAdviceBean) interceptor;
|
ControllerAdviceBean adviceBean = (ControllerAdviceBean) advice;
|
||||||
if (!adviceBean.isApplicableToBeanType(returnType.getContainingClass())) {
|
if (!adviceBean.isApplicableToBeanType(returnType.getContainingClass())) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
interceptor = adviceBean.resolveBean();
|
advice = adviceBean.resolveBean();
|
||||||
}
|
}
|
||||||
if (interceptor instanceof ResponseBodyInterceptor) {
|
if (advice instanceof ResponseBodyAdvice) {
|
||||||
ResponseBodyInterceptor<T> typedInterceptor = (ResponseBodyInterceptor<T>) interceptor;
|
ResponseBodyAdvice<T> typedAdvice = (ResponseBodyAdvice<T>) advice;
|
||||||
if (typedInterceptor.supports(returnType, selectedConverterType)) {
|
if (typedAdvice.supports(returnType, selectedConverterType)) {
|
||||||
body = typedInterceptor.beforeBodyWrite(body, returnType,
|
body = typedAdvice.beforeBodyWrite(body, returnType,
|
||||||
selectedContentType, selectedConverterType, request, response);
|
selectedContentType, selectedConverterType, request, response);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
throw new IllegalStateException("Expected a ResponseBodyInterceptor: " + interceptor);
|
throw new IllegalStateException("Expected ResponseBodyAdvice: " + advice);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (logger.isDebugEnabled()) {
|
if (logger.isDebugEnabled()) {
|
||||||
logger.debug("After interceptor chain body=" + body);
|
logger.debug("After ResponseBodyAdvice chain body=" + body);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return body;
|
return body;
|
|
@ -38,11 +38,11 @@ import org.springframework.web.method.support.HandlerMethodArgumentResolver;
|
||||||
import org.springframework.web.method.support.HandlerMethodReturnValueHandler;
|
import org.springframework.web.method.support.HandlerMethodReturnValueHandler;
|
||||||
import org.springframework.web.method.support.ModelAndViewContainer;
|
import org.springframework.web.method.support.ModelAndViewContainer;
|
||||||
import org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping;
|
import org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping;
|
||||||
import org.springframework.web.servlet.mvc.method.annotation.JsonViewResponseBodyInterceptor;
|
import org.springframework.web.servlet.mvc.method.annotation.JsonViewResponseBodyAdvice;
|
||||||
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter;
|
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter;
|
||||||
import org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver;
|
import org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver;
|
||||||
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;
|
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;
|
||||||
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyInterceptor;
|
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;
|
||||||
import org.springframework.web.servlet.mvc.method.annotation.ServletWebArgumentResolverAdapter;
|
import org.springframework.web.servlet.mvc.method.annotation.ServletWebArgumentResolverAdapter;
|
||||||
import org.springframework.web.util.UrlPathHelper;
|
import org.springframework.web.util.UrlPathHelper;
|
||||||
|
|
||||||
|
@ -95,8 +95,8 @@ public class AnnotationDrivenBeanDefinitionParserTests {
|
||||||
loadBeanDefinitions("mvc-config-message-converters.xml");
|
loadBeanDefinitions("mvc-config-message-converters.xml");
|
||||||
verifyMessageConverters(appContext.getBean(RequestMappingHandlerAdapter.class), true);
|
verifyMessageConverters(appContext.getBean(RequestMappingHandlerAdapter.class), true);
|
||||||
verifyMessageConverters(appContext.getBean(ExceptionHandlerExceptionResolver.class), true);
|
verifyMessageConverters(appContext.getBean(ExceptionHandlerExceptionResolver.class), true);
|
||||||
verifyResponseBodyInterceptors(appContext.getBean(RequestMappingHandlerAdapter.class));
|
verifyResponseBodyAdvice(appContext.getBean(RequestMappingHandlerAdapter.class));
|
||||||
verifyResponseBodyInterceptors(appContext.getBean(ExceptionHandlerExceptionResolver.class));
|
verifyResponseBodyAdvice(appContext.getBean(ExceptionHandlerExceptionResolver.class));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -167,13 +167,13 @@ public class AnnotationDrivenBeanDefinitionParserTests {
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
private void verifyResponseBodyInterceptors(Object bean) {
|
private void verifyResponseBodyAdvice(Object bean) {
|
||||||
assertNotNull(bean);
|
assertNotNull(bean);
|
||||||
Object value = new DirectFieldAccessor(bean).getPropertyValue("responseBodyInterceptors");
|
Object value = new DirectFieldAccessor(bean).getPropertyValue("responseBodyAdvice");
|
||||||
assertNotNull(value);
|
assertNotNull(value);
|
||||||
assertTrue(value instanceof List);
|
assertTrue(value instanceof List);
|
||||||
List<ResponseBodyInterceptor> converters = (List<ResponseBodyInterceptor>) value;
|
List<ResponseBodyAdvice> converters = (List<ResponseBodyAdvice>) value;
|
||||||
assertTrue(converters.get(0) instanceof JsonViewResponseBodyInterceptor);
|
assertTrue(converters.get(0) instanceof JsonViewResponseBodyAdvice);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,7 +52,7 @@ import org.springframework.web.servlet.handler.ConversionServiceExposingIntercep
|
||||||
import org.springframework.web.servlet.handler.HandlerExceptionResolverComposite;
|
import org.springframework.web.servlet.handler.HandlerExceptionResolverComposite;
|
||||||
import org.springframework.web.servlet.mvc.annotation.ResponseStatusExceptionResolver;
|
import org.springframework.web.servlet.mvc.annotation.ResponseStatusExceptionResolver;
|
||||||
import org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver;
|
import org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver;
|
||||||
import org.springframework.web.servlet.mvc.method.annotation.JsonViewResponseBodyInterceptor;
|
import org.springframework.web.servlet.mvc.method.annotation.JsonViewResponseBodyAdvice;
|
||||||
import org.springframework.web.servlet.mvc.method.annotation.MvcUriComponentsBuilder;
|
import org.springframework.web.servlet.mvc.method.annotation.MvcUriComponentsBuilder;
|
||||||
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter;
|
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter;
|
||||||
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;
|
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;
|
||||||
|
@ -161,9 +161,9 @@ public class WebMvcConfigurationSupportTests {
|
||||||
assertTrue(validator instanceof LocalValidatorFactoryBean);
|
assertTrue(validator instanceof LocalValidatorFactoryBean);
|
||||||
|
|
||||||
DirectFieldAccessor fieldAccessor = new DirectFieldAccessor(adapter);
|
DirectFieldAccessor fieldAccessor = new DirectFieldAccessor(adapter);
|
||||||
List<Object> interceptors = (List<Object>) fieldAccessor.getPropertyValue("responseBodyInterceptors");
|
List<Object> interceptors = (List<Object>) fieldAccessor.getPropertyValue("responseBodyAdvice");
|
||||||
assertEquals(1, interceptors.size());
|
assertEquals(1, interceptors.size());
|
||||||
assertEquals(JsonViewResponseBodyInterceptor.class, interceptors.get(0).getClass());
|
assertEquals(JsonViewResponseBodyAdvice.class, interceptors.get(0).getClass());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -192,9 +192,9 @@ public class WebMvcConfigurationSupportTests {
|
||||||
assertNotNull(eher.getApplicationContext());
|
assertNotNull(eher.getApplicationContext());
|
||||||
|
|
||||||
DirectFieldAccessor fieldAccessor = new DirectFieldAccessor(eher);
|
DirectFieldAccessor fieldAccessor = new DirectFieldAccessor(eher);
|
||||||
List<Object> interceptors = (List<Object>) fieldAccessor.getPropertyValue("responseBodyInterceptors");
|
List<Object> interceptors = (List<Object>) fieldAccessor.getPropertyValue("responseBodyAdvice");
|
||||||
assertEquals(1, interceptors.size());
|
assertEquals(1, interceptors.size());
|
||||||
assertEquals(JsonViewResponseBodyInterceptor.class, interceptors.get(0).getClass());
|
assertEquals(JsonViewResponseBodyAdvice.class, interceptors.get(0).getClass());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -19,7 +19,6 @@ package org.springframework.web.servlet.mvc.method.annotation;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
@ -235,7 +234,7 @@ public class RequestMappingHandlerAdapterTests {
|
||||||
// SPR-10859
|
// SPR-10859
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void responseBodyInterceptor() throws Exception {
|
public void responseBodyAdvice() throws Exception {
|
||||||
List<HttpMessageConverter<?>> converters = new ArrayList<>();
|
List<HttpMessageConverter<?>> converters = new ArrayList<>();
|
||||||
converters.add(new MappingJackson2HttpMessageConverter());
|
converters.add(new MappingJackson2HttpMessageConverter());
|
||||||
this.handlerAdapter.setMessageConverters(converters);
|
this.handlerAdapter.setMessageConverters(converters);
|
||||||
|
@ -339,7 +338,7 @@ public class RequestMappingHandlerAdapterTests {
|
||||||
}
|
}
|
||||||
|
|
||||||
@ControllerAdvice
|
@ControllerAdvice
|
||||||
private static class ResponseCodeSuppressingAdvice extends AbstractMappingJacksonResponseBodyInterceptor {
|
private static class ResponseCodeSuppressingAdvice extends AbstractMappingJacksonResponseBodyAdvice {
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
@Override
|
@Override
|
||||||
|
@ -357,7 +356,7 @@ public class RequestMappingHandlerAdapterTests {
|
||||||
}
|
}
|
||||||
|
|
||||||
@ControllerAdvice
|
@ControllerAdvice
|
||||||
private static class JsonpAdvice extends AbstractJsonpResponseBodyInterceptor {
|
private static class JsonpAdvice extends AbstractJsonpResponseBodyAdvice {
|
||||||
|
|
||||||
public JsonpAdvice() {
|
public JsonpAdvice() {
|
||||||
super(Arrays.asList("c"));
|
super(Arrays.asList("c"));
|
||||||
|
|
|
@ -299,7 +299,7 @@ public class RequestResponseBodyMethodProcessorTests {
|
||||||
converters.add(new MappingJackson2HttpMessageConverter());
|
converters.add(new MappingJackson2HttpMessageConverter());
|
||||||
|
|
||||||
RequestResponseBodyMethodProcessor processor = new RequestResponseBodyMethodProcessor(
|
RequestResponseBodyMethodProcessor processor = new RequestResponseBodyMethodProcessor(
|
||||||
converters, null, Arrays.asList(new JsonViewResponseBodyInterceptor()));
|
converters, null, Arrays.asList(new JsonViewResponseBodyAdvice()));
|
||||||
|
|
||||||
Object returnValue = new JacksonViewController().handleResponseBody();
|
Object returnValue = new JacksonViewController().handleResponseBody();
|
||||||
processor.handleReturnValue(returnValue, methodReturnType, this.mavContainer, this.webRequest);
|
processor.handleReturnValue(returnValue, methodReturnType, this.mavContainer, this.webRequest);
|
||||||
|
@ -320,7 +320,7 @@ public class RequestResponseBodyMethodProcessorTests {
|
||||||
converters.add(new MappingJackson2HttpMessageConverter());
|
converters.add(new MappingJackson2HttpMessageConverter());
|
||||||
|
|
||||||
HttpEntityMethodProcessor processor = new HttpEntityMethodProcessor(
|
HttpEntityMethodProcessor processor = new HttpEntityMethodProcessor(
|
||||||
converters, null, Arrays.asList(new JsonViewResponseBodyInterceptor()));
|
converters, null, Arrays.asList(new JsonViewResponseBodyAdvice()));
|
||||||
|
|
||||||
Object returnValue = new JacksonViewController().handleResponseEntity();
|
Object returnValue = new JacksonViewController().handleResponseEntity();
|
||||||
processor.handleReturnValue(returnValue, methodReturnType, this.mavContainer, this.webRequest);
|
processor.handleReturnValue(returnValue, methodReturnType, this.mavContainer, this.webRequest);
|
||||||
|
|
|
@ -42,12 +42,12 @@ import static org.mockito.Mockito.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Unit tests for
|
* Unit tests for
|
||||||
* {@link org.springframework.web.servlet.mvc.method.annotation.ResponseBodyInterceptorChain}.
|
* {@link ResponseBodyAdviceChain}.
|
||||||
*
|
*
|
||||||
* @author Rossen Stoyanchev
|
* @author Rossen Stoyanchev
|
||||||
* @since 4.1
|
* @since 4.1
|
||||||
*/
|
*/
|
||||||
public class ResponseBodyInterceptorChainTests {
|
public class ResponseBodyAdviceChainTests {
|
||||||
|
|
||||||
private String body;
|
private String body;
|
||||||
|
|
||||||
|
@ -73,15 +73,15 @@ public class ResponseBodyInterceptorChainTests {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void responseBodyInterceptor() {
|
public void responseBodyAdvice() {
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
ResponseBodyInterceptor<String> interceptor = Mockito.mock(ResponseBodyInterceptor.class);
|
ResponseBodyAdvice<String> advice = Mockito.mock(ResponseBodyAdvice.class);
|
||||||
ResponseBodyInterceptorChain chain = new ResponseBodyInterceptorChain(Arrays.asList(interceptor));
|
ResponseBodyAdviceChain chain = new ResponseBodyAdviceChain(Arrays.asList(advice));
|
||||||
|
|
||||||
String expected = "body++";
|
String expected = "body++";
|
||||||
when(interceptor.supports(this.returnType, this.converterType)).thenReturn(true);
|
when(advice.supports(this.returnType, this.converterType)).thenReturn(true);
|
||||||
when(interceptor.beforeBodyWrite(eq(this.body), eq(this.returnType), eq(this.contentType),
|
when(advice.beforeBodyWrite(eq(this.body), eq(this.returnType), eq(this.contentType),
|
||||||
eq(this.converterType), same(this.request), same(this.response))).thenReturn(expected);
|
eq(this.converterType), same(this.request), same(this.response))).thenReturn(expected);
|
||||||
|
|
||||||
String actual = chain.invoke(this.body, this.returnType,
|
String actual = chain.invoke(this.body, this.returnType,
|
||||||
|
@ -93,8 +93,8 @@ public class ResponseBodyInterceptorChainTests {
|
||||||
@Test
|
@Test
|
||||||
public void controllerAdvice() {
|
public void controllerAdvice() {
|
||||||
|
|
||||||
Object interceptor = new ControllerAdviceBean(new MyControllerAdvice());
|
Object adviceBean = new ControllerAdviceBean(new MyControllerAdvice());
|
||||||
ResponseBodyInterceptorChain chain = new ResponseBodyInterceptorChain(Arrays.asList(interceptor));
|
ResponseBodyAdviceChain chain = new ResponseBodyAdviceChain(Arrays.asList(adviceBean));
|
||||||
|
|
||||||
String actual = chain.invoke(this.body, this.returnType,
|
String actual = chain.invoke(this.body, this.returnType,
|
||||||
this.contentType, this.converterType, this.request, this.response);
|
this.contentType, this.converterType, this.request, this.response);
|
||||||
|
@ -105,8 +105,8 @@ public class ResponseBodyInterceptorChainTests {
|
||||||
@Test
|
@Test
|
||||||
public void controllerAdviceNotApplicable() {
|
public void controllerAdviceNotApplicable() {
|
||||||
|
|
||||||
Object interceptor = new ControllerAdviceBean(new TargetedControllerAdvice());
|
Object adviceBean = new ControllerAdviceBean(new TargetedControllerAdvice());
|
||||||
ResponseBodyInterceptorChain chain = new ResponseBodyInterceptorChain(Arrays.asList(interceptor));
|
ResponseBodyAdviceChain chain = new ResponseBodyAdviceChain(Arrays.asList(adviceBean));
|
||||||
|
|
||||||
String actual = chain.invoke(this.body, this.returnType,
|
String actual = chain.invoke(this.body, this.returnType,
|
||||||
this.contentType, this.converterType, this.request, this.response);
|
this.contentType, this.converterType, this.request, this.response);
|
||||||
|
@ -116,7 +116,7 @@ public class ResponseBodyInterceptorChainTests {
|
||||||
|
|
||||||
|
|
||||||
@ControllerAdvice
|
@ControllerAdvice
|
||||||
private static class MyControllerAdvice implements ResponseBodyInterceptor<String> {
|
private static class MyControllerAdvice implements ResponseBodyAdvice<String> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType) {
|
public boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType) {
|
||||||
|
@ -134,7 +134,7 @@ public class ResponseBodyInterceptorChainTests {
|
||||||
}
|
}
|
||||||
|
|
||||||
@ControllerAdvice(annotations = Controller.class)
|
@ControllerAdvice(annotations = Controller.class)
|
||||||
private static class TargetedControllerAdvice implements ResponseBodyInterceptor<String> {
|
private static class TargetedControllerAdvice implements ResponseBodyAdvice<String> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType) {
|
public boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType) {
|
Loading…
Reference in New Issue