Refactor @JsonView support w/ ResponseBodyInterceptor
The newly added support for ResponseBodyInterceptor is a good fit for the (also recently added) support for the Jackson @JsonView annotation. This change refactors the original implementation of @JsonView support for @ResponseBody and ResponseEntity controller methods this time implemented as an ResponseBodyInterceptor. Issue: SPR-7156
This commit is contained in:
@@ -1,62 +0,0 @@
|
||||
/*
|
||||
* Copyright 2002-2014 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.http.converter;
|
||||
|
||||
import org.springframework.core.MethodParameter;
|
||||
import org.springframework.http.HttpInputMessage;
|
||||
import org.springframework.http.HttpOutputMessage;
|
||||
import org.springframework.http.MediaType;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* An HttpMessageConverter that supports converting the value returned from a
|
||||
* method by incorporating {@link org.springframework.core.MethodParameter}
|
||||
* information into the conversion. Such a converter can for example take into
|
||||
* account information from method-level annotations.
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
* @since 4.1
|
||||
*/
|
||||
public interface MethodParameterHttpMessageConverter<T> extends HttpMessageConverter<T> {
|
||||
|
||||
/**
|
||||
* This method mirrors {@link HttpMessageConverter#canRead(Class, MediaType)}
|
||||
* with an additional {@code MethodParameter}.
|
||||
*/
|
||||
boolean canRead(Class<?> clazz, MediaType mediaType, MethodParameter parameter);
|
||||
|
||||
/**
|
||||
* This method mirrors {@link HttpMessageConverter#canWrite(Class, MediaType)}
|
||||
* with an additional {@code MethodParameter}.
|
||||
*/
|
||||
boolean canWrite(Class<?> clazz, MediaType mediaType, MethodParameter parameter);
|
||||
|
||||
/**
|
||||
* This method mirrors {@link HttpMessageConverter#read(Class, HttpInputMessage)}
|
||||
* with an additional {@code MethodParameter}.
|
||||
*/
|
||||
T read(Class<? extends T> clazz, HttpInputMessage inputMessage, MethodParameter parameter)
|
||||
throws IOException, HttpMessageNotReadableException;
|
||||
|
||||
/**
|
||||
* This method mirrors {@link HttpMessageConverter#write(Object, MediaType, HttpOutputMessage)}
|
||||
* with an additional {@code MethodParameter}.
|
||||
*/
|
||||
void write(T t, MediaType contentType, HttpOutputMessage outputMessage, MethodParameter parameter)
|
||||
throws IOException, HttpMessageNotWritableException;
|
||||
|
||||
}
|
||||
@@ -21,7 +21,6 @@ import java.lang.reflect.Type;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonView;
|
||||
import com.fasterxml.jackson.core.JsonEncoding;
|
||||
import com.fasterxml.jackson.core.JsonGenerator;
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
@@ -30,7 +29,6 @@ import com.fasterxml.jackson.databind.JavaType;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.SerializationFeature;
|
||||
|
||||
import org.springframework.core.MethodParameter;
|
||||
import org.springframework.http.HttpInputMessage;
|
||||
import org.springframework.http.HttpOutputMessage;
|
||||
import org.springframework.http.MediaType;
|
||||
@@ -38,7 +36,6 @@ import org.springframework.http.converter.AbstractHttpMessageConverter;
|
||||
import org.springframework.http.converter.GenericHttpMessageConverter;
|
||||
import org.springframework.http.converter.HttpMessageNotReadableException;
|
||||
import org.springframework.http.converter.HttpMessageNotWritableException;
|
||||
import org.springframework.http.converter.MethodParameterHttpMessageConverter;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ClassUtils;
|
||||
|
||||
@@ -60,7 +57,7 @@ import org.springframework.util.ClassUtils;
|
||||
* @since 3.1.2
|
||||
*/
|
||||
public class MappingJackson2HttpMessageConverter extends AbstractHttpMessageConverter<Object>
|
||||
implements GenericHttpMessageConverter<Object>, MethodParameterHttpMessageConverter<Object> {
|
||||
implements GenericHttpMessageConverter<Object> {
|
||||
|
||||
public static final Charset DEFAULT_CHARSET = Charset.forName("UTF-8");
|
||||
|
||||
@@ -150,11 +147,6 @@ public class MappingJackson2HttpMessageConverter extends AbstractHttpMessageConv
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canRead(Class<?> clazz, MediaType mediaType, MethodParameter parameter) {
|
||||
return canRead(clazz, mediaType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canRead(Class<?> clazz, MediaType mediaType) {
|
||||
return canRead(clazz, null, mediaType);
|
||||
@@ -205,11 +197,6 @@ public class MappingJackson2HttpMessageConverter extends AbstractHttpMessageConv
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canWrite(Class<?> clazz, MediaType mediaType, MethodParameter parameter) {
|
||||
return canWrite(clazz, mediaType);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean supports(Class<?> clazz) {
|
||||
// should not be called, since we override canRead/Write instead
|
||||
@@ -224,11 +211,6 @@ public class MappingJackson2HttpMessageConverter extends AbstractHttpMessageConv
|
||||
return readJavaType(javaType, inputMessage);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object read(Class<?> clazz, HttpInputMessage inputMessage, MethodParameter parameter) throws IOException, HttpMessageNotReadableException {
|
||||
return super.read(clazz, inputMessage);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object read(Type type, Class<?> contextClass, HttpInputMessage inputMessage)
|
||||
throws IOException, HttpMessageNotReadableException {
|
||||
@@ -267,8 +249,8 @@ public class MappingJackson2HttpMessageConverter extends AbstractHttpMessageConv
|
||||
if (this.jsonPrefix != null) {
|
||||
jsonGenerator.writeRaw(this.jsonPrefix);
|
||||
}
|
||||
if (object instanceof MappingJacksonValueHolder) {
|
||||
MappingJacksonValueHolder valueHolder = (MappingJacksonValueHolder) object;
|
||||
if (object instanceof MappingJacksonValue) {
|
||||
MappingJacksonValue valueHolder = (MappingJacksonValue) object;
|
||||
object = valueHolder.getValue();
|
||||
Class<?> serializationView = valueHolder.getSerializationView();
|
||||
this.objectMapper.writerWithView(serializationView).writeValue(jsonGenerator, object);
|
||||
@@ -282,20 +264,6 @@ public class MappingJackson2HttpMessageConverter extends AbstractHttpMessageConv
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(Object object, MediaType contentType, HttpOutputMessage outputMessage, MethodParameter parameter)
|
||||
throws IOException, HttpMessageNotWritableException {
|
||||
|
||||
JsonView annot = parameter.getMethodAnnotation(JsonView.class);
|
||||
if (annot != null && annot.value().length != 0) {
|
||||
MappingJacksonValueHolder serializationValue = new MappingJacksonValueHolder(object, annot.value()[0]);
|
||||
super.write(serializationValue, contentType, outputMessage);
|
||||
}
|
||||
else {
|
||||
super.write(object, contentType, outputMessage);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the Jackson {@link JavaType} for the specified type and context class.
|
||||
* <p>The default implementation returns {@code typeFactory.constructType(type, contextClass)},
|
||||
@@ -339,16 +307,16 @@ public class MappingJackson2HttpMessageConverter extends AbstractHttpMessageConv
|
||||
|
||||
@Override
|
||||
protected MediaType getDefaultContentType(Object object) throws IOException {
|
||||
if (object instanceof MappingJacksonValueHolder) {
|
||||
object = ((MappingJacksonValueHolder) object).getValue();
|
||||
if (object instanceof MappingJacksonValue) {
|
||||
object = ((MappingJacksonValue) object).getValue();
|
||||
}
|
||||
return super.getDefaultContentType(object);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Long getContentLength(Object object, MediaType contentType) throws IOException {
|
||||
if (object instanceof MappingJacksonValueHolder) {
|
||||
object = ((MappingJacksonValueHolder) object).getValue();
|
||||
if (object instanceof MappingJacksonValue) {
|
||||
object = ((MappingJacksonValue) object).getValue();
|
||||
}
|
||||
return super.getContentLength(object, contentType);
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@ package org.springframework.http.converter.json;
|
||||
*
|
||||
* @see com.fasterxml.jackson.annotation.JsonView
|
||||
*/
|
||||
public class MappingJacksonValueHolder {
|
||||
public class MappingJacksonValue {
|
||||
|
||||
private final Object value;
|
||||
|
||||
@@ -37,7 +37,7 @@ public class MappingJacksonValueHolder {
|
||||
* @param value the Object to be serialized
|
||||
* @param serializationView the view to be applied
|
||||
*/
|
||||
public MappingJacksonValueHolder(Object value, Class<?> serializationView) {
|
||||
public MappingJacksonValue(Object value, Class<?> serializationView) {
|
||||
this.value = value;
|
||||
this.serializationView = serializationView;
|
||||
}
|
||||
Reference in New Issue
Block a user