Skip to content

Commit c1defb5

Browse files
garyrussellartembilan
authored andcommitted
AbstractJackson2MessageConv.: assume supported CT
For the JSON and XML converters, assume the content type is supported if missing or default. Add option to revert to previous behavior.
1 parent 05ef5a9 commit c1defb5

File tree

5 files changed

+57
-6
lines changed

5 files changed

+57
-6
lines changed

spring-amqp/src/main/java/org/springframework/amqp/support/converter/AbstractJackson2MessageConverter.java

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,8 @@ public abstract class AbstractJackson2MessageConverter extends AbstractMessageCo
8585

8686
private boolean standardCharset;
8787

88+
private boolean assumeSupportedContentType = true;
89+
8890
/**
8991
* Construct with the provided {@link ObjectMapper} instance.
9092
* @param objectMapper the {@link ObjectMapper} to use.
@@ -218,6 +220,19 @@ public void setUseProjectionForInterfaces(boolean useProjectionForInterfaces) {
218220
}
219221
}
220222

223+
/**
224+
* By default the supported content type is assumed when there is no contentType
225+
* property or it is set to the default ('application/octet-stream'). Set to 'false'
226+
* to revert to the previous behavior of returning an unconverted 'byte[]' when this
227+
* condition exists.
228+
* @param assumeSupportedContentType set false to not assume the content type is
229+
* supported.
230+
* @since 2.2
231+
*/
232+
public void setAssumeSupportedContentType(boolean assumeSupportedContentType) {
233+
this.assumeSupportedContentType = assumeSupportedContentType;
234+
}
235+
221236
@Override
222237
public Object fromMessage(Message message) throws MessageConversionException {
223238
return fromMessage(message, null);
@@ -233,7 +248,8 @@ public Object fromMessage(Message message, @Nullable Object conversionHint) thro
233248
MessageProperties properties = message.getMessageProperties();
234249
if (properties != null) {
235250
String contentType = properties.getContentType();
236-
if (contentType != null && contentType.contains(this.supportedContentType.getSubtype())) {
251+
if ((this.assumeSupportedContentType && (contentType == null || contentType.equals(MessageProperties.DEFAULT_CONTENT_TYPE)))
252+
|| (contentType != null && contentType.contains(this.supportedContentType.getSubtype()))) {
237253
String encoding = properties.getContentEncoding();
238254
if (encoding == null) {
239255
encoding = getDefaultCharset();

spring-amqp/src/test/java/org/springframework/amqp/support/converter/Jackson2JsonMessageConverterTests.java

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -189,8 +189,9 @@ public void testNoJsonContentType() {
189189
byte[] bytes = "{\"name\" : \"foo\" }".getBytes();
190190
MessageProperties messageProperties = new MessageProperties();
191191
Message message = new Message(bytes, messageProperties);
192-
Object foo = jsonConverterWithDefaultType.fromMessage(message);
193-
assertThat(new String((byte[]) foo)).isEqualTo(new String(bytes));
192+
this.jsonConverterWithDefaultType.setAssumeSupportedContentType(false);
193+
Object foo = this.jsonConverterWithDefaultType.fromMessage(message);
194+
assertThat(foo).isEqualTo(bytes);
194195
}
195196

196197
@Test
@@ -280,6 +281,27 @@ public void testProjection() {
280281
assertThat(((Sample) fromMessage).getName()).isEqualTo("SomeName");
281282
}
282283

284+
@Test
285+
public void testMissingContentType() {
286+
byte[] bytes = "{\"name\" : \"foo\" }".getBytes();
287+
MessageProperties messageProperties = new MessageProperties();
288+
Message message = new Message(bytes, messageProperties);
289+
Jackson2JsonMessageConverter j2Converter = new Jackson2JsonMessageConverter();
290+
DefaultClassMapper classMapper = new DefaultClassMapper();
291+
classMapper.setDefaultType(Foo.class);
292+
j2Converter.setClassMapper(classMapper);
293+
Object foo = j2Converter.fromMessage(message);
294+
assertThat(foo).isInstanceOf(Foo.class);
295+
296+
messageProperties.setContentType(null);
297+
foo = j2Converter.fromMessage(message);
298+
assertThat(foo).isInstanceOf(Foo.class);
299+
300+
j2Converter.setAssumeSupportedContentType(false);
301+
foo = j2Converter.fromMessage(message);
302+
assertThat(foo).isSameAs(bytes);
303+
}
304+
283305
public static class Foo {
284306

285307
private String name = "foo";

spring-amqp/src/test/java/org/springframework/amqp/support/converter/Jackson2XmlMessageConverterTests.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -187,8 +187,9 @@ public void testNoJsonContentType() {
187187
byte[] bytes = "<root><name>foo</name><root/>".getBytes();
188188
MessageProperties messageProperties = new MessageProperties();
189189
Message message = new Message(bytes, messageProperties);
190-
Object foo = xmlConverterWithDefaultType.fromMessage(message);
191-
assertThat(new String(bytes)).isEqualTo(new String((byte[]) foo));
190+
this.xmlConverterWithDefaultType.setAssumeSupportedContentType(false);
191+
Object foo = this.xmlConverterWithDefaultType.fromMessage(message);
192+
assertThat(foo).isEqualTo(bytes);
192193
}
193194

194195
@Test

src/reference/asciidoc/amqp.adoc

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3398,7 +3398,9 @@ for convenience.)
33983398
If you inject a custom type mapper, you should set the property on the mapper instead.
33993399

34003400
NOTE: When converting from the `Message`, an incoming `MessageProperties.getContentType()` must be JSON-compliant (`contentType.contains("json")` is used to check).
3401-
Otherwise, a `WARN` log message `Could not convert incoming message with content-type [...]`, is emitted and `message.getBody()` is returned as is -- as a `byte[]`.
3401+
Starting with version 2.2, `application/json` is assumed if there is no `contentType` property, or it has the default value `application/octet-stream`.
3402+
To revert to the previous behavior (return an unconverted `byte[]`), set the converter's `assumeSupportedContentType` property to `false`.
3403+
If the content type is not supported, a `WARN` log message `Could not convert incoming message with content-type [...]`, is emitted and `message.getBody()` is returned as is -- as a `byte[]`.
34023404
So, to meet the `Jackson2JsonMessageConverter` requirements on the consumer side, the producer must add the `contentType` message property -- for example, as `application/json` or `text/x-json` or by using the `Jackson2JsonMessageConverter`, which sets the header automatically.
34033405
The following listing shows a number of converter calls:
34043406

@@ -3521,6 +3523,7 @@ The following example shows how to configure a `MarshallingMessageConverter`:
35213523
----
35223524
====
35233525

3526+
[[jackson2xml]]
35243527
===== `Jackson2XmlMessageConverter`
35253528

35263529
This class was introduced in version 2.1 and can be used to convert messages from and to XML.
@@ -3547,6 +3550,9 @@ The following example configures a `Jackson2JsonMessageConverter`:
35473550
----
35483551
See <<json-message-converter>> for more information.
35493552

3553+
NOTE: Starting with version 2.2, `application/xml` is assumed if there is no `contentType` property, or it has the default value `application/octet-stream`.
3554+
To revert to the previous behavior (return an unconverted `byte[]`), set the converter's `assumeSupportedContentType` property to `false`.
3555+
35503556
===== `ContentTypeDelegatingMessageConverter`
35513557

35523558
This class was introduced in version 1.4.2 and allows delegation to a specific `MessageConverter` based on the content type property in the `MessageProperties`.

src/reference/asciidoc/whats-new.adoc

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,12 @@ See <<choose-container>> for more information.
3333
Spring Data Projection interfaces are now supported by the `Jackson2JsonMessageConverter`.
3434
See <<data-projection>> for more information.
3535

36+
The `Jackson2JsonMessageConverter` now assumes the content is JSON if there is no `contentType` property, or it is the default (`application/octet-string`).
37+
See <<Jackson2JsonMessageConverter-from-message>> for more information.
38+
39+
Similarly. the `Jackson2XmlMessageConverter` now assumes the content is XML if there is no `contentType` property, or it is the default (`application/octet-string`).
40+
See <<jackson2xml>> for more information.
41+
3642
===== AMQP Logging Appenders Changes
3743

3844
The Log4J and Logback `AmqpAppender` s now support a `verifyHostname` SSL option.

0 commit comments

Comments
 (0)