You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
In what version(s) of Spring AMQP are you seeing this issue?
For example:
3.2.4
Describe the bug
Example uses CBORMapper from jackson-dataformat-cbor
To Reproduce
Use RabbitTemplate#convertAndSend() to serialize an object and send it to a queue
Use @RabbitListener to read message from queue and deserialize to object
Expected behavior
Serializing and sending works.
Deserializing does not work because convertBytesToObject converts the payload to UTF-8 string before handing it to the ObjectMapper, causing Can not create parser for non-byte-based source.
I could get deserialization to work if I add a ;charset=ascii to the MimeType, as that causes the raw payload to be handed to the ObjectMapper. Unfortunately this hack causes serialization to fail, because it now calls ObjectMapper#writeValueAsString which is not supported for CBOR.
This is basically asking for it to work out of the box, or being able to override convertBytesToObject (currently private) and a new method convertObjectToBytes (so that I don't have to override and copy the contents of createMessage)
So, if it is UTF-8 (technically no MimeType provided for the Jackson2JsonMessageConverter), then we write content as byte[].
On the deserialization we have a different logic:
private Object convertBytesToObject(byte[] body, String encoding, JavaType targetJavaType) throws IOException {
if (this.supportedCTCharset != null) { // Jackson will determine encoding
return this.objectMapper.readValue(body, targetJavaType);
}
String contentAsString = new String(body, encoding);
return this.objectMapper.readValue(contentAsString, targetJavaType);
}
I guess we can improve that with the this.charsetIsUtf8 flag as well.
But at the same time I don't deny making convertBytesToObject() as protected and have that CborMessageConverter.
I can try to contribute a fix. However, it's not clear to me, what the preferred solution would be.
I'm wondering if we want to use this.objectMapper.getFactory().canHandleBinaryNatively() to determine if we always work with byte arrays instead of doing string conversion/encoding stuff.
/**
* Introspection method that higher-level functionality may call
* to see whether underlying data format can read and write binary
* data natively; that is, embeded it as-is without using encodings
* such as Base64.
*<p>
* Default implementation returns <code>false</code> as JSON does not
* support native access: all binary content must use Base64 encoding.
* Most binary formats (like Smile and Avro) support native binary content.
*
* @return Whether format supported by this factory
* supports native binary content
*
* @since 2.3
*/
@Override
public boolean canHandleBinaryNatively() {
So, this one is for case where a property of our data object is a byte[] itself.
Doesn't look like this has anything to do with (de)serialization itself.
In what version(s) of Spring AMQP are you seeing this issue?
For example:
3.2.4
Describe the bug
Example uses CBORMapper from jackson-dataformat-cbor
To Reproduce
RabbitTemplate#convertAndSend()
to serialize an object and send it to a queue@RabbitListener
to read message from queue and deserialize to objectExpected behavior
Serializing and sending works.
Deserializing does not work because
convertBytesToObject
converts the payload to UTF-8 string before handing it to the ObjectMapper, causingCan not create parser for non-byte-based source
.I could get deserialization to work if I add a
;charset=ascii
to the MimeType, as that causes the raw payload to be handed to the ObjectMapper. Unfortunately this hack causes serialization to fail, because it now callsObjectMapper#writeValueAsString
which is not supported for CBOR.This is basically asking for it to work out of the box, or being able to override
convertBytesToObject
(currently private) and a new methodconvertObjectToBytes
(so that I don't have to override and copy the contents ofcreateMessage
)Sample
The text was updated successfully, but these errors were encountered: