|
|
|
@ -23,12 +23,12 @@ import java.io.OutputStreamWriter; |
|
|
|
import java.lang.reflect.Method; |
|
|
|
import java.lang.reflect.Method; |
|
|
|
import java.nio.charset.Charset; |
|
|
|
import java.nio.charset.Charset; |
|
|
|
import java.nio.charset.StandardCharsets; |
|
|
|
import java.nio.charset.StandardCharsets; |
|
|
|
import java.util.Arrays; |
|
|
|
|
|
|
|
import java.util.Map; |
|
|
|
import java.util.Map; |
|
|
|
|
|
|
|
|
|
|
|
import com.google.protobuf.ExtensionRegistry; |
|
|
|
import com.google.protobuf.ExtensionRegistry; |
|
|
|
import com.google.protobuf.Message; |
|
|
|
import com.google.protobuf.Message; |
|
|
|
import com.google.protobuf.util.JsonFormat; |
|
|
|
import com.google.protobuf.util.JsonFormat; |
|
|
|
|
|
|
|
|
|
|
|
import org.springframework.lang.Nullable; |
|
|
|
import org.springframework.lang.Nullable; |
|
|
|
import org.springframework.messaging.MessageHeaders; |
|
|
|
import org.springframework.messaging.MessageHeaders; |
|
|
|
import org.springframework.util.ClassUtils; |
|
|
|
import org.springframework.util.ClassUtils; |
|
|
|
@ -77,59 +77,23 @@ public class ProtobufMessageConverter extends AbstractMessageConverter { |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* Construct a new {@code ProtobufMessageConverter}. |
|
|
|
* Constructor with a default instance of {@link ExtensionRegistry}. |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
public ProtobufMessageConverter() { |
|
|
|
public ProtobufMessageConverter() { |
|
|
|
this((ProtobufFormatSupport) null, (ExtensionRegistry) null); |
|
|
|
this(null, null); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* Construct a new {@code ProtobufMessageConverter} with a registry that specifies |
|
|
|
* Constructor with a given {@code ExtensionRegistry}. |
|
|
|
* protocol message extensions. |
|
|
|
|
|
|
|
* |
|
|
|
|
|
|
|
* @param extensionRegistry the registry to populate |
|
|
|
|
|
|
|
*/ |
|
|
|
*/ |
|
|
|
public ProtobufMessageConverter(@Nullable ExtensionRegistry extensionRegistry) { |
|
|
|
public ProtobufMessageConverter(ExtensionRegistry extensionRegistry) { |
|
|
|
this(null, extensionRegistry); |
|
|
|
this(null, extensionRegistry); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
ProtobufMessageConverter(@Nullable ProtobufFormatSupport formatSupport, |
|
|
|
* Construct a new {@code ProtobufMessageConverter} with the given |
|
|
|
@Nullable ExtensionRegistry extensionRegistry) { |
|
|
|
* {@code JsonFormat.Parser} and {@code JsonFormat.Printer} configuration. |
|
|
|
|
|
|
|
* |
|
|
|
|
|
|
|
* @param parser the JSON parser configuration |
|
|
|
|
|
|
|
* @param printer the JSON printer configuration |
|
|
|
|
|
|
|
*/ |
|
|
|
|
|
|
|
public ProtobufMessageConverter(@Nullable JsonFormat.Parser parser, @Nullable JsonFormat.Printer printer) { |
|
|
|
|
|
|
|
this(new ProtobufJavaUtilSupport(parser, printer), (ExtensionRegistry) null); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
super(PROTOBUF, TEXT_PLAIN); |
|
|
|
* Construct a new {@code ProtobufMessageConverter} with the given |
|
|
|
|
|
|
|
* {@code JsonFormat.Parser} and {@code JsonFormat.Printer} configuration, also |
|
|
|
|
|
|
|
* accepting a registry that specifies protocol message extensions. |
|
|
|
|
|
|
|
* |
|
|
|
|
|
|
|
* @param parser the JSON parser configuration |
|
|
|
|
|
|
|
* @param printer the JSON printer configuration |
|
|
|
|
|
|
|
* @param extensionRegistry the registry to populate |
|
|
|
|
|
|
|
*/ |
|
|
|
|
|
|
|
public ProtobufMessageConverter(@Nullable JsonFormat.Parser parser, |
|
|
|
|
|
|
|
@Nullable JsonFormat.Printer printer, @Nullable ExtensionRegistry extensionRegistry) { |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
this(new ProtobufJavaUtilSupport(parser, printer), extensionRegistry); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
|
|
* Construct a new {@code ProtobufMessageConverter} with the given |
|
|
|
|
|
|
|
* {@code ProtobufFormatSupport} configuration, also |
|
|
|
|
|
|
|
* accepting a registry that specifies protocol message extensions. |
|
|
|
|
|
|
|
* |
|
|
|
|
|
|
|
* @param formatSupport support third party |
|
|
|
|
|
|
|
* @param extensionRegistry the registry to populate |
|
|
|
|
|
|
|
*/ |
|
|
|
|
|
|
|
public ProtobufMessageConverter(@Nullable ProtobufFormatSupport formatSupport, |
|
|
|
|
|
|
|
@Nullable ExtensionRegistry extensionRegistry) { |
|
|
|
|
|
|
|
super(PROTOBUF); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (formatSupport != null) { |
|
|
|
if (formatSupport != null) { |
|
|
|
this.protobufFormatSupport = formatSupport; |
|
|
|
this.protobufFormatSupport = formatSupport; |
|
|
|
@ -142,12 +106,13 @@ public class ProtobufMessageConverter extends AbstractMessageConverter { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (this.protobufFormatSupport != null) { |
|
|
|
if (this.protobufFormatSupport != null) { |
|
|
|
setSupportedMimeTypes(Arrays.asList(protobufFormatSupport.supportedMediaTypes())); |
|
|
|
addSupportedMimeTypes(this.protobufFormatSupport.supportedMediaTypes()); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
this.extensionRegistry = (extensionRegistry == null ? ExtensionRegistry.newInstance() : extensionRegistry); |
|
|
|
this.extensionRegistry = (extensionRegistry == null ? ExtensionRegistry.newInstance() : extensionRegistry); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
@Override |
|
|
|
protected boolean supports(Class<?> clazz) { |
|
|
|
protected boolean supports(Class<?> clazz) { |
|
|
|
return Message.class.isAssignableFrom(clazz); |
|
|
|
return Message.class.isAssignableFrom(clazz); |
|
|
|
@ -161,7 +126,9 @@ public class ProtobufMessageConverter extends AbstractMessageConverter { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
@Override |
|
|
|
protected Object convertFromInternal(org.springframework.messaging.Message<?> message, Class<?> targetClass, @Nullable Object conversionHint) { |
|
|
|
protected Object convertFromInternal(org.springframework.messaging.Message<?> message, |
|
|
|
|
|
|
|
Class<?> targetClass, @Nullable Object conversionHint) { |
|
|
|
|
|
|
|
|
|
|
|
MimeType contentType = getMimeType(message.getHeaders()); |
|
|
|
MimeType contentType = getMimeType(message.getHeaders()); |
|
|
|
final Object payload = message.getPayload(); |
|
|
|
final Object payload = message.getPayload(); |
|
|
|
|
|
|
|
|
|
|
|
@ -175,18 +142,16 @@ public class ProtobufMessageConverter extends AbstractMessageConverter { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
Message.Builder builder = getMessageBuilder(targetClass); |
|
|
|
Message.Builder builder = getMessageBuilder(targetClass); |
|
|
|
|
|
|
|
|
|
|
|
try { |
|
|
|
try { |
|
|
|
if (PROTOBUF.isCompatibleWith(contentType)) { |
|
|
|
if (PROTOBUF.isCompatibleWith(contentType)) { |
|
|
|
builder.mergeFrom((byte[]) payload, this.extensionRegistry); |
|
|
|
builder.mergeFrom((byte[]) payload, this.extensionRegistry); |
|
|
|
} |
|
|
|
} |
|
|
|
else if (protobufFormatSupport != null) { |
|
|
|
else if (this.protobufFormatSupport != null) { |
|
|
|
this.protobufFormatSupport.merge( |
|
|
|
this.protobufFormatSupport.merge(message, charset, contentType, this.extensionRegistry, builder); |
|
|
|
message, charset, contentType, this.extensionRegistry, builder); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
catch (IOException e) { |
|
|
|
catch (IOException ex) { |
|
|
|
throw new MessageConversionException(message, "Could not read proto message" + e.getMessage(), e); |
|
|
|
throw new MessageConversionException(message, "Could not read proto message" + ex.getMessage(), ex); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
return builder.build(); |
|
|
|
return builder.build(); |
|
|
|
@ -194,13 +159,14 @@ public class ProtobufMessageConverter extends AbstractMessageConverter { |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
@Override |
|
|
|
protected Object convertToInternal(Object payload, @Nullable MessageHeaders headers, @Nullable Object conversionHint) { |
|
|
|
protected Object convertToInternal( |
|
|
|
|
|
|
|
Object payload, @Nullable MessageHeaders headers, @Nullable Object conversionHint) { |
|
|
|
|
|
|
|
|
|
|
|
final Message message = (Message) payload; |
|
|
|
final Message message = (Message) payload; |
|
|
|
|
|
|
|
|
|
|
|
MimeType contentType = getMimeType(headers); |
|
|
|
MimeType contentType = getMimeType(headers); |
|
|
|
if (contentType == null) { |
|
|
|
if (contentType == null) { |
|
|
|
contentType = PROTOBUF; |
|
|
|
contentType = PROTOBUF; |
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
Charset charset = contentType.getCharset(); |
|
|
|
Charset charset = contentType.getCharset(); |
|
|
|
@ -220,14 +186,13 @@ public class ProtobufMessageConverter extends AbstractMessageConverter { |
|
|
|
payload = new String(outputStream.toByteArray(), charset); |
|
|
|
payload = new String(outputStream.toByteArray(), charset); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
catch (IOException e) { |
|
|
|
catch (IOException ex) { |
|
|
|
throw new MessageConversionException("Could not write proto message" + e.getMessage(), e); |
|
|
|
throw new MessageConversionException("Could not write proto message" + ex.getMessage(), ex); |
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
return payload; |
|
|
|
return payload; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* Create a new {@code Message.Builder} instance for the given class. |
|
|
|
* Create a new {@code Message.Builder} instance for the given class. |
|
|
|
* <p>This method uses a ConcurrentReferenceHashMap for caching method lookups. |
|
|
|
* <p>This method uses a ConcurrentReferenceHashMap for caching method lookups. |
|
|
|
@ -257,9 +222,9 @@ public class ProtobufMessageConverter extends AbstractMessageConverter { |
|
|
|
|
|
|
|
|
|
|
|
boolean supportsWriteOnly(@Nullable MimeType mediaType); |
|
|
|
boolean supportsWriteOnly(@Nullable MimeType mediaType); |
|
|
|
|
|
|
|
|
|
|
|
void merge(org.springframework.messaging.Message<?> message, Charset charset, MimeType contentType, |
|
|
|
void merge(org.springframework.messaging.Message<?> message, |
|
|
|
ExtensionRegistry extensionRegistry, Message.Builder builder) |
|
|
|
Charset charset, MimeType contentType, ExtensionRegistry extensionRegistry, |
|
|
|
throws IOException, MessageConversionException; |
|
|
|
Message.Builder builder) throws IOException, MessageConversionException; |
|
|
|
|
|
|
|
|
|
|
|
void print(Message message, OutputStream output, MimeType contentType, Charset charset) |
|
|
|
void print(Message message, OutputStream output, MimeType contentType, Charset charset) |
|
|
|
throws IOException, MessageConversionException; |
|
|
|
throws IOException, MessageConversionException; |
|
|
|
@ -283,7 +248,7 @@ public class ProtobufMessageConverter extends AbstractMessageConverter { |
|
|
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
@Override |
|
|
|
public MimeType[] supportedMediaTypes() { |
|
|
|
public MimeType[] supportedMediaTypes() { |
|
|
|
return new MimeType[]{PROTOBUF, TEXT_PLAIN, APPLICATION_JSON}; |
|
|
|
return new MimeType[]{APPLICATION_JSON}; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
@Override |
|
|
|
@ -292,8 +257,8 @@ public class ProtobufMessageConverter extends AbstractMessageConverter { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
@Override |
|
|
|
public void merge(org.springframework.messaging.Message<?> message, Charset charset, MimeType contentType, |
|
|
|
public void merge(org.springframework.messaging.Message<?> message, Charset charset, |
|
|
|
ExtensionRegistry extensionRegistry, Message.Builder builder) |
|
|
|
MimeType contentType, ExtensionRegistry extensionRegistry, Message.Builder builder) |
|
|
|
throws IOException, MessageConversionException { |
|
|
|
throws IOException, MessageConversionException { |
|
|
|
|
|
|
|
|
|
|
|
if (contentType.isCompatibleWith(APPLICATION_JSON)) { |
|
|
|
if (contentType.isCompatibleWith(APPLICATION_JSON)) { |
|
|
|
@ -313,12 +278,12 @@ public class ProtobufMessageConverter extends AbstractMessageConverter { |
|
|
|
OutputStreamWriter writer = new OutputStreamWriter(output, charset); |
|
|
|
OutputStreamWriter writer = new OutputStreamWriter(output, charset); |
|
|
|
this.printer.appendTo(message, writer); |
|
|
|
this.printer.appendTo(message, writer); |
|
|
|
writer.flush(); |
|
|
|
writer.flush(); |
|
|
|
} else { |
|
|
|
} |
|
|
|
|
|
|
|
else { |
|
|
|
throw new MessageConversionException( |
|
|
|
throw new MessageConversionException( |
|
|
|
"protobuf-java-util does not support printing " + contentType); |
|
|
|
"protobuf-java-util does not support printing " + contentType); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|