Support byte array payloads in ProtobufMessageConverter

Prior to this commit, the `ProtobufMessageConverter` used in messaging
would try and serialize the message payload by calling "toString()" on
it in order to pass it to the Protobuf JSON encoder.
While this works for `String` payloads, this fails for `byte[]` types.

This commit ensures that such `byte[]` are first converted to `String`
instances using the given charset first.

Fixes gh-27408
This commit is contained in:
Brian Clozel 2024-06-25 21:16:50 +02:00
parent d133ab60ee
commit 6dd5c85ed0
2 changed files with 13 additions and 7 deletions

View File

@ -1,5 +1,5 @@
/*
* Copyright 2002-2022 the original author or authors.
* Copyright 2002-2024 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.
@ -265,8 +265,13 @@ public class ProtobufMessageConverter extends AbstractMessageConverter {
throws IOException, MessageConversionException {
if (contentType.isCompatibleWith(APPLICATION_JSON)) {
if (message.getPayload() instanceof byte[] bytes) {
this.parser.merge(new String(bytes, charset), builder);
}
else {
this.parser.merge(message.getPayload().toString(), builder);
}
}
else {
throw new MessageConversionException(
"protobuf-java-util does not support parsing " + contentType);

View File

@ -1,5 +1,5 @@
/*
* Copyright 2002-2023 the original author or authors.
* Copyright 2002-2024 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.
@ -16,6 +16,7 @@
package org.springframework.messaging.converter;
import java.nio.charset.StandardCharsets;
import java.util.Map;
import org.junit.jupiter.api.Test;
@ -49,14 +50,14 @@ class ProtobufMessageConverterTests {
private Message<byte[]> messageWithoutContentType = MessageBuilder.withPayload(this.testMsg.toByteArray()).build();
private final Message<String> messageJson = MessageBuilder.withPayload("""
private final Message<byte[]> messageJson = MessageBuilder.withPayload("""
{
"foo": "Foo",
"blah": {
"blah": 123
}
}
""")
""".getBytes(StandardCharsets.UTF_8))
.setHeader(CONTENT_TYPE, APPLICATION_JSON)
.build();
@ -113,10 +114,10 @@ class ProtobufMessageConverterTests {
Message<?> message = converter.toMessage(testMsg, new MessageHeaders(Map.of(CONTENT_TYPE, APPLICATION_JSON)));
assertThat(message).isNotNull();
assertThat(message.getHeaders().get(CONTENT_TYPE)).isEqualTo(APPLICATION_JSON);
JSONAssert.assertEquals(messageJson.getPayload(), message.getPayload().toString(), true);
JSONAssert.assertEquals(new String(messageJson.getPayload()), message.getPayload().toString(), true);
//convertFrom
assertThat(converter.fromMessage(message, Msg.class)).isEqualTo(testMsg);
assertThat(converter.fromMessage(messageJson, Msg.class)).isEqualTo(testMsg);
}
}