Polishing

This commit is contained in:
Juergen Hoeller
2020-09-25 11:26:01 +02:00
parent 392ad09990
commit 6e4fcb69f0
14 changed files with 84 additions and 93 deletions

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2019 the original author or authors.
* Copyright 2002-2020 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.
@@ -92,7 +92,7 @@ public abstract class AbstractMessageConverter implements SmartMessageConverter
}
/**
* Allows sub-classes to add more supported mime types.
* Allows subclasses to add more supported mime types.
* @since 5.2.2
*/
protected void addSupportedMimeTypes(MimeType... supportedMimeTypes) {
@@ -167,21 +167,6 @@ public abstract class AbstractMessageConverter implements SmartMessageConverter
}
/**
* Returns the default content type for the payload. Called when
* {@link #toMessage(Object, MessageHeaders)} is invoked without message headers or
* without a content type header.
* <p>By default, this returns the first element of the {@link #getSupportedMimeTypes()
* supportedMimeTypes}, if any. Can be overridden in sub-classes.
* @param payload the payload being converted to message
* @return the content type, or {@code null} if not known
*/
@Nullable
protected MimeType getDefaultContentType(Object payload) {
List<MimeType> mimeTypes = getSupportedMimeTypes();
return (!mimeTypes.isEmpty() ? mimeTypes.get(0) : null);
}
@Override
@Nullable
public final Object fromMessage(Message<?> message, Class<?> targetClass) {
@@ -197,10 +182,6 @@ public abstract class AbstractMessageConverter implements SmartMessageConverter
return convertFromInternal(message, targetClass, conversionHint);
}
protected boolean canConvertFrom(Message<?> message, Class<?> targetClass) {
return (supports(targetClass) && supportsMimeType(message.getHeaders()));
}
@Override
@Nullable
public final Message<?> toMessage(Object payload, @Nullable MessageHeaders headers) {
@@ -240,6 +221,11 @@ public abstract class AbstractMessageConverter implements SmartMessageConverter
return builder.build();
}
protected boolean canConvertFrom(Message<?> message, Class<?> targetClass) {
return (supports(targetClass) && supportsMimeType(message.getHeaders()));
}
protected boolean canConvertTo(Object payload, @Nullable MessageHeaders headers) {
return (supports(payload.getClass()) && supportsMimeType(headers));
}
@@ -265,6 +251,22 @@ public abstract class AbstractMessageConverter implements SmartMessageConverter
return (headers != null && this.contentTypeResolver != null ? this.contentTypeResolver.resolve(headers) : null);
}
/**
* Return the default content type for the payload. Called when
* {@link #toMessage(Object, MessageHeaders)} is invoked without
* message headers or without a content type header.
* <p>By default, this returns the first element of the
* {@link #getSupportedMimeTypes() supportedMimeTypes}, if any.
* Can be overridden in subclasses.
* @param payload the payload being converted to a message
* @return the content type, or {@code null} if not known
*/
@Nullable
protected MimeType getDefaultContentType(Object payload) {
List<MimeType> mimeTypes = getSupportedMimeTypes();
return (!mimeTypes.isEmpty() ? mimeTypes.get(0) : null);
}
/**
* Whether the given class is supported by this converter.

View File

@@ -41,6 +41,7 @@ import org.springframework.lang.Nullable;
import org.springframework.messaging.Message;
import org.springframework.messaging.MessageHeaders;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import org.springframework.util.MimeType;
/**
@@ -139,6 +140,7 @@ public class MappingJackson2MessageConverter extends AbstractMessageConverter {
}
}
@Override
protected boolean canConvertFrom(Message<?> message, @Nullable Class<?> targetClass) {
if (targetClass == null || !supportsMimeType(message.getHeaders())) {
@@ -210,7 +212,7 @@ public class MappingJackson2MessageConverter extends AbstractMessageConverter {
Object payload = message.getPayload();
Class<?> view = getSerializationView(conversionHint);
try {
if (targetClass.isInstance(payload)) {
if (ClassUtils.isAssignableValue(targetClass, payload)) {
return payload;
}
else if (payload instanceof byte[]) {
@@ -246,7 +248,7 @@ public class MappingJackson2MessageConverter extends AbstractMessageConverter {
Type genericParameterType = param.getNestedGenericParameterType();
Class<?> contextClass = param.getContainingClass();
Type type = GenericTypeResolver.resolveType(genericParameterType, contextClass);
return this.objectMapper.getTypeFactory().constructType(type);
return this.objectMapper.constructType(type);
}
return this.objectMapper.constructType(targetClass);
}
@@ -331,7 +333,7 @@ public class MappingJackson2MessageConverter extends AbstractMessageConverter {
* @return the JSON encoding to use (never {@code null})
*/
protected JsonEncoding getJsonEncoding(@Nullable MimeType contentType) {
if (contentType != null && (contentType.getCharset() != null)) {
if (contentType != null && contentType.getCharset() != null) {
Charset charset = contentType.getCharset();
for (JsonEncoding encoding : JsonEncoding.values()) {
if (charset.name().equals(encoding.getJavaName())) {

View File

@@ -46,6 +46,8 @@ import org.springframework.util.MimeType;
*
* @author Arjen Poutsma
* @since 4.2
* @see Marshaller
* @see Unmarshaller
*/
public class MarshallingMessageConverter extends AbstractMessageConverter {
@@ -61,7 +63,8 @@ public class MarshallingMessageConverter extends AbstractMessageConverter {
* {@link #setUnmarshaller(Unmarshaller)} to be invoked separately.
*/
public MarshallingMessageConverter() {
this(new MimeType("application", "xml"), new MimeType("text", "xml"), new MimeType("application", "*+xml"));
this(new MimeType("application", "xml"), new MimeType("text", "xml"),
new MimeType("application", "*+xml"));
}
/**
@@ -160,7 +163,7 @@ public class MarshallingMessageConverter extends AbstractMessageConverter {
return new StreamSource(new ByteArrayInputStream((byte[]) payload));
}
else {
return new StreamSource(new StringReader((String) payload));
return new StreamSource(new StringReader(payload.toString()));
}
}

View File

@@ -120,9 +120,9 @@ public class ProtobufMessageConverter extends AbstractMessageConverter {
@Override
protected boolean canConvertTo(Object payload, @Nullable MessageHeaders headers) {
MimeType mimeType = getMimeType(headers);
MimeType contentType = getMimeType(headers);
return (super.canConvertTo(payload, headers) ||
this.protobufFormatSupport != null && this.protobufFormatSupport.supportsWriteOnly(mimeType));
this.protobufFormatSupport != null && this.protobufFormatSupport.supportsWriteOnly(contentType));
}
@Override

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2019 the original author or authors.
* Copyright 2002-2020 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.
@@ -48,10 +48,9 @@ public class MappingJackson2MessageConverterTests {
@Test
public void defaultConstructor() {
MappingJackson2MessageConverter converter = new MappingJackson2MessageConverter();
assertThat(converter.getSupportedMimeTypes())
.contains(new MimeType("application", "json"));
assertThat(converter.getSupportedMimeTypes()).contains(new MimeType("application", "json"));
assertThat(converter.getObjectMapper().getDeserializationConfig()
.isEnabled(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES)).isFalse();
.isEnabled(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES)).isFalse();
}
@Test // SPR-12724
@@ -60,7 +59,7 @@ public class MappingJackson2MessageConverterTests {
MappingJackson2MessageConverter converter = new MappingJackson2MessageConverter(mimetype);
assertThat(converter.getSupportedMimeTypes()).contains(mimetype);
assertThat(converter.getObjectMapper().getDeserializationConfig()
.isEnabled(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES)).isFalse();
.isEnabled(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES)).isFalse();
}
@Test // SPR-12724
@@ -70,19 +69,14 @@ public class MappingJackson2MessageConverterTests {
MappingJackson2MessageConverter converter = new MappingJackson2MessageConverter(jsonMimetype, xmlMimetype);
assertThat(converter.getSupportedMimeTypes()).contains(jsonMimetype, xmlMimetype);
assertThat(converter.getObjectMapper().getDeserializationConfig()
.isEnabled(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES)).isFalse();
.isEnabled(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES)).isFalse();
}
@Test
public void fromMessage() {
MappingJackson2MessageConverter converter = new MappingJackson2MessageConverter();
String payload = "{" +
"\"bytes\":\"AQI=\"," +
"\"array\":[\"Foo\",\"Bar\"]," +
"\"number\":42," +
"\"string\":\"Foo\"," +
"\"bool\":true," +
"\"fraction\":42.0}";
String payload = "{\"bytes\":\"AQI=\",\"array\":[\"Foo\",\"Bar\"]," +
"\"number\":42,\"string\":\"Foo\",\"bool\":true,\"fraction\":42.0}";
Message<?> message = MessageBuilder.withPayload(payload.getBytes(StandardCharsets.UTF_8)).build();
MyBean actual = (MyBean) converter.fromMessage(message, MyBean.class);
@@ -97,8 +91,8 @@ public class MappingJackson2MessageConverterTests {
@Test
public void fromMessageUntyped() {
MappingJackson2MessageConverter converter = new MappingJackson2MessageConverter();
String payload = "{\"bytes\":\"AQI=\",\"array\":[\"Foo\",\"Bar\"],"
+ "\"number\":42,\"string\":\"Foo\",\"bool\":true,\"fraction\":42.0}";
String payload = "{\"bytes\":\"AQI=\",\"array\":[\"Foo\",\"Bar\"]," +
"\"number\":42,\"string\":\"Foo\",\"bool\":true,\"fraction\":42.0}";
Message<?> message = MessageBuilder.withPayload(payload.getBytes(StandardCharsets.UTF_8)).build();
@SuppressWarnings("unchecked")
HashMap<String, Object> actual = (HashMap<String, Object>) converter.fromMessage(message, HashMap.class);
@@ -111,7 +105,7 @@ public class MappingJackson2MessageConverterTests {
assertThat(actual.get("bytes")).isEqualTo("AQI=");
}
@Test // gh-22386
@Test // gh-22386
public void fromMessageMatchingInstance() {
MyBean myBean = new MyBean();
MappingJackson2MessageConverter converter = new MappingJackson2MessageConverter();
@@ -137,7 +131,7 @@ public class MappingJackson2MessageConverterTests {
assertThat(myBean.getString()).isEqualTo("string");
}
@Test // SPR-16252
@Test // SPR-16252
public void fromMessageToList() throws Exception {
MappingJackson2MessageConverter converter = new MappingJackson2MessageConverter();
String payload = "[1, 2, 3, 4, 5, 6, 7, 8, 9]";
@@ -151,7 +145,7 @@ public class MappingJackson2MessageConverterTests {
assertThat(actual).isEqualTo(Arrays.asList(1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 9L));
}
@Test // SPR-16486
@Test // SPR-16486
public void fromMessageToMessageWithPojo() throws Exception {
MappingJackson2MessageConverter converter = new MappingJackson2MessageConverter();
String payload = "{\"string\":\"foo\"}";
@@ -198,7 +192,7 @@ public class MappingJackson2MessageConverterTests {
String payload = "H\u00e9llo W\u00f6rld";
Message<?> message = converter.toMessage(payload, headers);
assertThat(new String((byte[]) message.getPayload(), StandardCharsets.UTF_16BE)).isEqualTo(("\"" + payload + "\""));
assertThat(new String((byte[]) message.getPayload(), StandardCharsets.UTF_16BE)).isEqualTo("\"" + payload + "\"");
assertThat(message.getHeaders().get(MessageHeaders.CONTENT_TYPE)).isEqualTo(contentType);
}
@@ -214,7 +208,7 @@ public class MappingJackson2MessageConverterTests {
String payload = "H\u00e9llo W\u00f6rld";
Message<?> message = converter.toMessage(payload, headers);
assertThat(message.getPayload()).isEqualTo(("\"" + payload + "\""));
assertThat(message.getPayload()).isEqualTo("\"" + payload + "\"");
assertThat(message.getHeaders().get(MessageHeaders.CONTENT_TYPE)).isEqualTo(contentType);
}
@@ -254,9 +248,12 @@ public class MappingJackson2MessageConverterTests {
public void jsonViewPayload(@JsonView(MyJacksonView2.class) JacksonViewBean payload) {
}
void handleList(List<Long> payload) {}
void handleList(List<Long> payload) {
}
void handleMessage(Message<MyBean> message) {
}
void handleMessage(Message<MyBean> message) {}
public static class MyBean {