Skip to content

Commit 5f4e838

Browse files
committed
Jackson-based message converters do not log warning for serializer not found
Issue: SPR-14163
1 parent 7e55b08 commit 5f4e838

3 files changed

Lines changed: 53 additions & 39 deletions

File tree

spring-messaging/src/main/java/org/springframework/messaging/converter/MappingJackson2MessageConverter.java

Lines changed: 28 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2015 the original author or authors.
2+
* Copyright 2002-2016 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -20,6 +20,7 @@
2020
import java.io.IOException;
2121
import java.io.StringWriter;
2222
import java.io.Writer;
23+
import java.lang.reflect.Type;
2324
import java.nio.charset.Charset;
2425
import java.util.Arrays;
2526
import java.util.concurrent.atomic.AtomicReference;
@@ -30,6 +31,7 @@
3031
import com.fasterxml.jackson.core.util.DefaultPrettyPrinter;
3132
import com.fasterxml.jackson.databind.DeserializationFeature;
3233
import com.fasterxml.jackson.databind.JavaType;
34+
import com.fasterxml.jackson.databind.JsonMappingException;
3335
import com.fasterxml.jackson.databind.MapperFeature;
3436
import com.fasterxml.jackson.databind.ObjectMapper;
3537
import com.fasterxml.jackson.databind.SerializationFeature;
@@ -136,50 +138,56 @@ private void configurePrettyPrint() {
136138

137139
@Override
138140
protected boolean canConvertFrom(Message<?> message, Class<?> targetClass) {
139-
if (targetClass == null) {
141+
if (targetClass == null || !supportsMimeType(message.getHeaders())) {
140142
return false;
141143
}
142144
JavaType javaType = this.objectMapper.constructType(targetClass);
143145
if (!logger.isWarnEnabled()) {
144-
return (this.objectMapper.canDeserialize(javaType) && supportsMimeType(message.getHeaders()));
146+
return this.objectMapper.canDeserialize(javaType);
145147
}
146148
AtomicReference<Throwable> causeRef = new AtomicReference<Throwable>();
147-
if (this.objectMapper.canDeserialize(javaType, causeRef) && supportsMimeType(message.getHeaders())) {
149+
if (this.objectMapper.canDeserialize(javaType, causeRef)) {
148150
return true;
149151
}
150-
Throwable cause = causeRef.get();
151-
if (cause != null) {
152-
String msg = "Failed to evaluate deserialization for type " + javaType;
153-
if (logger.isDebugEnabled()) {
154-
logger.warn(msg, cause);
155-
}
156-
else {
157-
logger.warn(msg + ": " + cause);
158-
}
159-
}
152+
logWarningIfNecessary(javaType, causeRef.get());
160153
return false;
161154
}
162155

163156
@Override
164157
protected boolean canConvertTo(Object payload, MessageHeaders headers) {
158+
if (payload == null || !supportsMimeType(headers)) {
159+
return false;
160+
}
165161
if (!logger.isWarnEnabled()) {
166-
return (this.objectMapper.canSerialize(payload.getClass()) && supportsMimeType(headers));
162+
return this.objectMapper.canSerialize(payload.getClass());
167163
}
168164
AtomicReference<Throwable> causeRef = new AtomicReference<Throwable>();
169-
if (this.objectMapper.canSerialize(payload.getClass(), causeRef) && supportsMimeType(headers)) {
165+
if (this.objectMapper.canSerialize(payload.getClass(), causeRef)) {
170166
return true;
171167
}
172-
Throwable cause = causeRef.get();
173-
if (cause != null) {
174-
String msg = "Failed to evaluate serialization for type [" + payload.getClass() + "]";
168+
logWarningIfNecessary(payload.getClass(), causeRef.get());
169+
return false;
170+
}
171+
172+
/**
173+
* Determine whether to log the given exception coming from a
174+
* {@link ObjectMapper#canDeserialize} / {@link ObjectMapper#canSerialize} check.
175+
* @param type the class that Jackson tested for (de-)serializability
176+
* @param cause the Jackson-thrown exception to evaluate
177+
* (typically a {@link JsonMappingException})
178+
* @since 4.3
179+
*/
180+
protected void logWarningIfNecessary(Type type, Throwable cause) {
181+
if (cause != null && !(cause instanceof JsonMappingException && cause.getMessage().startsWith("Can not find"))) {
182+
String msg = "Failed to evaluate Jackson " + (type instanceof JavaType ? "de" : "") +
183+
"serialization for type [" + type + "]";
175184
if (logger.isDebugEnabled()) {
176185
logger.warn(msg, cause);
177186
}
178187
else {
179188
logger.warn(msg + ": " + cause);
180189
}
181190
}
182-
return false;
183191
}
184192

185193
@Override

spring-web/src/main/java/org/springframework/http/converter/json/AbstractJackson2HttpMessageConverter.java

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
import com.fasterxml.jackson.core.JsonProcessingException;
2828
import com.fasterxml.jackson.core.util.DefaultPrettyPrinter;
2929
import com.fasterxml.jackson.databind.JavaType;
30+
import com.fasterxml.jackson.databind.JsonMappingException;
3031
import com.fasterxml.jackson.databind.ObjectMapper;
3132
import com.fasterxml.jackson.databind.ObjectWriter;
3233
import com.fasterxml.jackson.databind.SerializationFeature;
@@ -148,16 +149,7 @@ public boolean canRead(Type type, Class<?> contextClass, MediaType mediaType) {
148149
if (this.objectMapper.canDeserialize(javaType, causeRef)) {
149150
return true;
150151
}
151-
Throwable cause = causeRef.get();
152-
if (cause != null) {
153-
String msg = "Failed to evaluate deserialization for type " + javaType;
154-
if (logger.isDebugEnabled()) {
155-
logger.warn(msg, cause);
156-
}
157-
else {
158-
logger.warn(msg + ": " + cause);
159-
}
160-
}
152+
logWarningIfNecessary(javaType, causeRef.get());
161153
return false;
162154
}
163155

@@ -173,17 +165,29 @@ public boolean canWrite(Class<?> clazz, MediaType mediaType) {
173165
if (this.objectMapper.canSerialize(clazz, causeRef)) {
174166
return true;
175167
}
176-
Throwable cause = causeRef.get();
177-
if (cause != null) {
178-
String msg = "Failed to evaluate serialization for type [" + clazz + "]";
168+
logWarningIfNecessary(clazz, causeRef.get());
169+
return false;
170+
}
171+
172+
/**
173+
* Determine whether to log the given exception coming from a
174+
* {@link ObjectMapper#canDeserialize} / {@link ObjectMapper#canSerialize} check.
175+
* @param type the class that Jackson tested for (de-)serializability
176+
* @param cause the Jackson-thrown exception to evaluate
177+
* (typically a {@link JsonMappingException})
178+
* @since 4.3
179+
*/
180+
protected void logWarningIfNecessary(Type type, Throwable cause) {
181+
if (cause != null && !(cause instanceof JsonMappingException && cause.getMessage().startsWith("Can not find"))) {
182+
String msg = "Failed to evaluate Jackson " + (type instanceof JavaType ? "de" : "") +
183+
"serialization for type [" + type + "]";
179184
if (logger.isDebugEnabled()) {
180185
logger.warn(msg, cause);
181186
}
182187
else {
183188
logger.warn(msg + ": " + cause);
184189
}
185190
}
186-
return false;
187191
}
188192

189193
@Override

spring-web/src/test/java/org/springframework/http/converter/json/MappingJackson2HttpMessageConverterTests.java

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2015 the original author or authors.
2+
* Copyright 2002-2016 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -31,7 +31,6 @@
3131
import com.fasterxml.jackson.databind.ser.FilterProvider;
3232
import com.fasterxml.jackson.databind.ser.impl.SimpleBeanPropertyFilter;
3333
import com.fasterxml.jackson.databind.ser.impl.SimpleFilterProvider;
34-
3534
import org.junit.Test;
3635

3736
import org.springframework.core.ParameterizedTypeReference;
@@ -68,9 +67,7 @@ public void canWrite() {
6867
assertTrue(converter.canWrite(Map.class, new MediaType("application", "json")));
6968
}
7069

71-
// SPR-7905
72-
73-
@Test
70+
@Test // SPR-7905
7471
public void canReadAndWriteMicroformats() {
7572
assertTrue(converter.canRead(MyBean.class, new MediaType("application", "vnd.test-micro-type+json")));
7673
assertTrue(converter.canWrite(MyBean.class, new MediaType("application", "vnd.test-micro-type+json")));
@@ -439,9 +436,12 @@ public void setName(String name) {
439436
}
440437
}
441438

439+
442440
private interface MyJacksonView1 {};
441+
443442
private interface MyJacksonView2 {};
444443

444+
445445
@SuppressWarnings("unused")
446446
private static class JacksonViewBean {
447447

@@ -478,11 +478,13 @@ public void setWithoutView(String withoutView) {
478478
}
479479
}
480480

481+
481482
@JsonFilter("myJacksonFilter")
482483
@SuppressWarnings("unused")
483484
private static class JacksonFilteredBean {
484485

485486
private String property1;
487+
486488
private String property2;
487489

488490
public String getProperty1() {

0 commit comments

Comments
 (0)