Add @JsonView deserialization support for request bodies
Jackson 2.5.0 or later is required. Issue: SPR-12501
This commit is contained in:
@@ -73,6 +73,7 @@ import org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter;
|
||||
import org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter;
|
||||
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.JsonViewRequestBodyAdvice;
|
||||
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.RequestMappingHandlerAdapter;
|
||||
@@ -221,6 +222,7 @@ class AnnotationDrivenBeanDefinitionParser implements BeanDefinitionParser {
|
||||
handlerAdapterDef.getPropertyValues().add("contentNegotiationManager", contentNegotiationManager);
|
||||
handlerAdapterDef.getPropertyValues().add("webBindingInitializer", bindingDef);
|
||||
handlerAdapterDef.getPropertyValues().add("messageConverters", messageConverters);
|
||||
addRequestBodyAdvice(handlerAdapterDef);
|
||||
addResponseBodyAdvice(handlerAdapterDef);
|
||||
|
||||
if (element.hasAttribute("ignore-default-model-on-redirect")) {
|
||||
@@ -308,6 +310,13 @@ class AnnotationDrivenBeanDefinitionParser implements BeanDefinitionParser {
|
||||
return null;
|
||||
}
|
||||
|
||||
protected void addRequestBodyAdvice(RootBeanDefinition beanDef) {
|
||||
if (jackson2Present) {
|
||||
beanDef.getPropertyValues().add("requestBodyAdvice",
|
||||
new RootBeanDefinition(JsonViewRequestBodyAdvice.class));
|
||||
}
|
||||
}
|
||||
|
||||
protected void addResponseBodyAdvice(RootBeanDefinition beanDef) {
|
||||
if (jackson2Present) {
|
||||
beanDef.getPropertyValues().add("responseBodyAdvice",
|
||||
|
||||
@@ -83,7 +83,9 @@ import org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter;
|
||||
import org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter;
|
||||
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.JsonViewRequestBodyAdvice;
|
||||
import org.springframework.web.servlet.mvc.method.annotation.JsonViewResponseBodyAdvice;
|
||||
import org.springframework.web.servlet.mvc.method.annotation.RequestBodyAdvice;
|
||||
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.ResponseBodyAdvice;
|
||||
@@ -478,9 +480,13 @@ public class WebMvcConfigurationSupport implements ApplicationContextAware, Serv
|
||||
adapter.setCustomReturnValueHandlers(returnValueHandlers);
|
||||
|
||||
if (jackson2Present) {
|
||||
List<ResponseBodyAdvice<?>> interceptors = new ArrayList<ResponseBodyAdvice<?>>();
|
||||
interceptors.add(new JsonViewResponseBodyAdvice());
|
||||
adapter.setResponseBodyAdvice(interceptors);
|
||||
List<RequestBodyAdvice> requestBodyAdvices = new ArrayList<RequestBodyAdvice>();
|
||||
requestBodyAdvices.add(new JsonViewRequestBodyAdvice());
|
||||
adapter.setRequestBodyAdvice(requestBodyAdvices);
|
||||
|
||||
List<ResponseBodyAdvice<?>> responseBodyAdvices = new ArrayList<ResponseBodyAdvice<?>>();
|
||||
responseBodyAdvices.add(new JsonViewResponseBodyAdvice());
|
||||
adapter.setResponseBodyAdvice(responseBodyAdvices);
|
||||
}
|
||||
|
||||
AsyncSupportConfigurer configurer = new AsyncSupportConfigurer();
|
||||
|
||||
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
* Copyright 2002-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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.web.servlet.mvc.method.annotation;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Type;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonView;
|
||||
|
||||
import org.springframework.core.MethodParameter;
|
||||
import org.springframework.http.HttpInputMessage;
|
||||
import org.springframework.http.converter.HttpMessageConverter;
|
||||
import org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter;
|
||||
import org.springframework.http.converter.json.MappingJacksonInputMessage;
|
||||
|
||||
/**
|
||||
* A {@code RequestBodyAdvice} implementation that adds support for
|
||||
* Jackson's {@code @JsonView} annotation declared on a Spring MVC
|
||||
* {@code @HttpEntity} and {@code @RequestBody} method parameters.
|
||||
*
|
||||
* <p>The deserialization view specified in the annotation will be passed in to
|
||||
* the {@code MappingJackson2HttpMessageConverter} which will then use it to
|
||||
* deserialize the request body with.
|
||||
*
|
||||
* <p>Note that despite {@code @JsonView} allowing for more than one class to
|
||||
* be specified, the use for a request body advice is only supported with
|
||||
* exactly one class argument. Consider the use of a composite interface.
|
||||
*
|
||||
* <p>Jackson 2.5.0 or later is required.
|
||||
*
|
||||
* @author Sebastien Deleuze
|
||||
* @since 4.2
|
||||
* @see com.fasterxml.jackson.databind.ObjectMapper#readerWithView(Class)
|
||||
*/
|
||||
public class JsonViewRequestBodyAdvice extends RequestBodyAdviceAdapter {
|
||||
|
||||
@Override
|
||||
public boolean supports(MethodParameter methodParameter, Type targetType,
|
||||
Class<? extends HttpMessageConverter<?>> converterType) {
|
||||
return (AbstractJackson2HttpMessageConverter.class.isAssignableFrom(converterType) &&
|
||||
methodParameter.getParameterAnnotation(JsonView.class) != null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public HttpInputMessage beforeBodyRead(HttpInputMessage inputMessage, MethodParameter methodParameter,
|
||||
Type targetType, Class<? extends HttpMessageConverter<?>> selectedConverterType) throws IOException {
|
||||
JsonView annotation = methodParameter.getParameterAnnotation(JsonView.class);
|
||||
Class<?>[] classes = annotation.value();
|
||||
if (classes.length != 1) {
|
||||
throw new IllegalArgumentException(
|
||||
"@JsonView only supported for request body advice with exactly 1 class argument: " + methodParameter);
|
||||
}
|
||||
return new MappingJacksonInputMessage(inputMessage.getBody(), inputMessage.getHeaders(), classes[0]);
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user