Tested against Jackson 2.2 and 2.3; compatible with Jackson 2.0 and higher.
+ *
* @author Rossen Stoyanchev
+ * @author Juergen Hoeller
* @since 4.0
*/
public class MappingJackson2MessageConverter extends AbstractMessageConverter {
+ // Check for Jackson 2.3's overloaded canDeserialize/canSerialize variants with cause reference
+ private static final boolean jackson23Available =
+ ClassUtils.hasMethod(ObjectMapper.class, "canDeserialize", JavaType.class, AtomicReference.class);
+
+
private ObjectMapper objectMapper = new ObjectMapper();
private Boolean prettyPrint;
@@ -76,13 +86,35 @@ public class MappingJackson2MessageConverter extends AbstractMessageConverter {
if (targetClass == null) {
return false;
}
- JavaType type = this.objectMapper.constructType(targetClass);
- return (this.objectMapper.canDeserialize(type) && supportsMimeType(message.getHeaders()));
+ JavaType javaType = this.objectMapper.constructType(targetClass);
+ if (!jackson23Available || !logger.isWarnEnabled()) {
+ return (this.objectMapper.canDeserialize(javaType) && supportsMimeType(message.getHeaders()));
+ }
+ AtomicReference causeRef = new AtomicReference();
+ if (this.objectMapper.canDeserialize(javaType, causeRef) && supportsMimeType(message.getHeaders())) {
+ return true;
+ }
+ Throwable cause = causeRef.get();
+ if (cause != null) {
+ logger.warn("Failed to evaluate deserialization for type: " + javaType);
+ }
+ return false;
}
@Override
protected boolean canConvertTo(Object payload, MessageHeaders headers) {
- return (this.objectMapper.canSerialize(payload.getClass()) && supportsMimeType(headers));
+ if (!jackson23Available || !logger.isWarnEnabled()) {
+ return (this.objectMapper.canSerialize(payload.getClass()) && supportsMimeType(headers));
+ }
+ AtomicReference causeRef = new AtomicReference();
+ if (this.objectMapper.canSerialize(payload.getClass(), causeRef) && supportsMimeType(headers)) {
+ return true;
+ }
+ Throwable cause = causeRef.get();
+ if (cause != null) {
+ logger.warn("Failed to evaluate serialization for type: " + payload.getClass());
+ }
+ return false;
}
@Override
@@ -143,7 +175,6 @@ public class MappingJackson2MessageConverter extends AbstractMessageConverter {
/**
* Determine the JSON encoding to use for the given content type.
- *
* @param contentType the MIME type from the MessageHeaders, if any
* @return the JSON encoding to use (never {@code null})
*/
diff --git a/spring-web/src/main/java/org/springframework/http/converter/json/MappingJackson2HttpMessageConverter.java b/spring-web/src/main/java/org/springframework/http/converter/json/MappingJackson2HttpMessageConverter.java
index 17c1aa3f3ce..1fd65398420 100644
--- a/spring-web/src/main/java/org/springframework/http/converter/json/MappingJackson2HttpMessageConverter.java
+++ b/spring-web/src/main/java/org/springframework/http/converter/json/MappingJackson2HttpMessageConverter.java
@@ -19,6 +19,15 @@ package org.springframework.http.converter.json;
import java.io.IOException;
import java.lang.reflect.Type;
import java.nio.charset.Charset;
+import java.util.concurrent.atomic.AtomicReference;
+
+import com.fasterxml.jackson.core.JsonEncoding;
+import com.fasterxml.jackson.core.JsonGenerator;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.core.util.DefaultPrettyPrinter;
+import com.fasterxml.jackson.databind.JavaType;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.SerializationFeature;
import org.springframework.http.HttpInputMessage;
import org.springframework.http.HttpOutputMessage;
@@ -28,14 +37,7 @@ import org.springframework.http.converter.GenericHttpMessageConverter;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.http.converter.HttpMessageNotWritableException;
import org.springframework.util.Assert;
-
-import com.fasterxml.jackson.core.JsonEncoding;
-import com.fasterxml.jackson.core.JsonGenerator;
-import com.fasterxml.jackson.core.JsonProcessingException;
-import com.fasterxml.jackson.core.util.DefaultPrettyPrinter;
-import com.fasterxml.jackson.databind.JavaType;
-import com.fasterxml.jackson.databind.ObjectMapper;
-import com.fasterxml.jackson.databind.SerializationFeature;
+import org.springframework.util.ClassUtils;
/**
* Implementation of {@link org.springframework.http.converter.HttpMessageConverter HttpMessageConverter} that
@@ -46,11 +48,12 @@ import com.fasterxml.jackson.databind.SerializationFeature;
*
By default, this converter supports {@code application/json}. This can be overridden by setting the
* {@link #setSupportedMediaTypes supportedMediaTypes} property.
*
- *
Tested against Jackson 2.2; compatible with Jackson 2.0 and higher.
+ *
Tested against Jackson 2.2 and 2.3; compatible with Jackson 2.0 and higher.
*
* @author Arjen Poutsma
* @author Keith Donald
* @author Rossen Stoyanchev
+ * @author Juergen Hoeller
* @since 3.1.2
*/
public class MappingJackson2HttpMessageConverter extends AbstractHttpMessageConverter