mirror of
https://github.com/spring-projects/spring-framework.git
synced 2026-09-23 14:40:00 +00:00
Allow ProtobufHttpMessageConverter extensions
Make ProtobufFormatDelegate protected and visible to subclasses. Expose constructor that allows passing the delegate in. See gh-35403
This commit is contained in:
+51
-30
@@ -17,9 +17,7 @@
|
||||
package org.springframework.http.converter.protobuf;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.OutputStream;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.lang.reflect.Method;
|
||||
import java.nio.charset.Charset;
|
||||
@@ -105,7 +103,7 @@ public class ProtobufHttpMessageConverter extends AbstractHttpMessageConverter<M
|
||||
|
||||
final ExtensionRegistry extensionRegistry;
|
||||
|
||||
private final @Nullable ProtobufFormatSupport protobufFormatSupport;
|
||||
private final ProtobufHttpMessageConverter.@Nullable ProtobufFormatDelegate protobufFormatDelegate;
|
||||
|
||||
|
||||
/**
|
||||
@@ -124,21 +122,27 @@ public class ProtobufHttpMessageConverter extends AbstractHttpMessageConverter<M
|
||||
this(null, extensionRegistry);
|
||||
}
|
||||
|
||||
ProtobufHttpMessageConverter(@Nullable ProtobufFormatSupport formatSupport,
|
||||
/**
|
||||
* Constructor for a subclass that supports additional formats.
|
||||
* @param formatDelegate delegate to read and write additional formats
|
||||
* @param extensionRegistry the registry to populate
|
||||
*/
|
||||
protected ProtobufHttpMessageConverter(
|
||||
ProtobufHttpMessageConverter.@Nullable ProtobufFormatDelegate formatDelegate,
|
||||
@Nullable ExtensionRegistry extensionRegistry) {
|
||||
|
||||
if (formatSupport != null) {
|
||||
this.protobufFormatSupport = formatSupport;
|
||||
if (formatDelegate != null) {
|
||||
this.protobufFormatDelegate = formatDelegate;
|
||||
}
|
||||
else if (PROTOBUF_JSON_FORMAT_PRESENT) {
|
||||
this.protobufFormatSupport = new ProtobufJavaUtilSupport(null, null);
|
||||
this.protobufFormatDelegate = new ProtobufJavaUtilDelegate(null, null);
|
||||
}
|
||||
else {
|
||||
this.protobufFormatSupport = null;
|
||||
this.protobufFormatDelegate = null;
|
||||
}
|
||||
|
||||
setSupportedMediaTypes(Arrays.asList(this.protobufFormatSupport != null ?
|
||||
this.protobufFormatSupport.supportedMediaTypes() : new MediaType[] {PROTOBUF, PLUS_PROTOBUF, TEXT_PLAIN}));
|
||||
setSupportedMediaTypes(Arrays.asList(this.protobufFormatDelegate != null ?
|
||||
this.protobufFormatDelegate.supportedMediaTypes() : new MediaType[] {PROTOBUF, PLUS_PROTOBUF, TEXT_PLAIN}));
|
||||
|
||||
this.extensionRegistry = (extensionRegistry == null ? ExtensionRegistry.newInstance() : extensionRegistry);
|
||||
}
|
||||
@@ -172,13 +176,13 @@ public class ProtobufHttpMessageConverter extends AbstractHttpMessageConverter<M
|
||||
PLUS_PROTOBUF.isCompatibleWith(contentType)) {
|
||||
builder.mergeFrom(inputMessage.getBody(), this.extensionRegistry);
|
||||
}
|
||||
else if (TEXT_PLAIN.isCompatibleWith(contentType)) {
|
||||
else if (MediaType.TEXT_PLAIN.isCompatibleWith(contentType)) {
|
||||
InputStreamReader reader = new InputStreamReader(inputMessage.getBody(), charset);
|
||||
TextFormat.merge(reader, this.extensionRegistry, builder);
|
||||
}
|
||||
else if (this.protobufFormatSupport != null) {
|
||||
this.protobufFormatSupport.merge(
|
||||
inputMessage.getBody(), charset, contentType, this.extensionRegistry, builder);
|
||||
else if (this.protobufFormatDelegate != null) {
|
||||
this.protobufFormatDelegate.merge(
|
||||
inputMessage, contentType, charset, builder, this.extensionRegistry);
|
||||
}
|
||||
return builder.build();
|
||||
}
|
||||
@@ -206,7 +210,7 @@ public class ProtobufHttpMessageConverter extends AbstractHttpMessageConverter<M
|
||||
@Override
|
||||
protected boolean canWrite(@Nullable MediaType mediaType) {
|
||||
return (super.canWrite(mediaType) ||
|
||||
(this.protobufFormatSupport != null && this.protobufFormatSupport.supportsWriteOnly(mediaType)));
|
||||
(this.protobufFormatDelegate != null && this.protobufFormatDelegate.supportsWriteOnly(mediaType)));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -235,8 +239,8 @@ public class ProtobufHttpMessageConverter extends AbstractHttpMessageConverter<M
|
||||
outputStreamWriter.flush();
|
||||
outputMessage.getBody().flush();
|
||||
}
|
||||
else if (this.protobufFormatSupport != null) {
|
||||
this.protobufFormatSupport.print(message, outputMessage.getBody(), contentType, charset);
|
||||
else if (this.protobufFormatDelegate != null) {
|
||||
this.protobufFormatDelegate.print(message, outputMessage, contentType, charset);
|
||||
outputMessage.getBody().flush();
|
||||
}
|
||||
}
|
||||
@@ -259,34 +263,51 @@ public class ProtobufHttpMessageConverter extends AbstractHttpMessageConverter<M
|
||||
|
||||
|
||||
/**
|
||||
* Protobuf format support.
|
||||
* Contract to enable subclasses to plug in support for additional formats.
|
||||
*/
|
||||
interface ProtobufFormatSupport {
|
||||
protected interface ProtobufFormatDelegate {
|
||||
|
||||
/**
|
||||
* Return the supported media types for the converter.
|
||||
* <p>Note that {@link #PROTOBUF}, {@link #PLUS_PROTOBUF}, and {@link MediaType#TEXT_PLAIN}
|
||||
* have built-in support and can be listed in addition to formats
|
||||
* specific to this delegate.
|
||||
*/
|
||||
MediaType[] supportedMediaTypes();
|
||||
|
||||
/**
|
||||
* Whether the media type is supported for writing.
|
||||
*/
|
||||
boolean supportsWriteOnly(@Nullable MediaType mediaType);
|
||||
|
||||
void merge(InputStream input, Charset charset, MediaType contentType,
|
||||
ExtensionRegistry extensionRegistry, Message.Builder builder)
|
||||
/**
|
||||
* Use merge methods on {@link Message.Builder} to read a message from
|
||||
* the given {@code HttpInputMessage}.
|
||||
*/
|
||||
void merge(HttpInputMessage inputMessage, MediaType contentType, Charset charset,
|
||||
Message.Builder builder, ExtensionRegistry extensionRegistry)
|
||||
throws IOException, HttpMessageConversionException;
|
||||
|
||||
void print(Message message, OutputStream output, MediaType contentType, Charset charset)
|
||||
/**
|
||||
* Use print methods on {@link Message.Builder} to write the message to
|
||||
* the given {@code HttpOutputMessage}.
|
||||
*/
|
||||
void print(Message message, HttpOutputMessage outputMessage, MediaType contentType, Charset charset)
|
||||
throws IOException, HttpMessageConversionException;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* {@link ProtobufFormatSupport} implementation used when
|
||||
* {@link ProtobufFormatDelegate} implementation used when
|
||||
* {@code com.google.protobuf.util.JsonFormat} is available.
|
||||
*/
|
||||
static class ProtobufJavaUtilSupport implements ProtobufFormatSupport {
|
||||
static class ProtobufJavaUtilDelegate implements ProtobufFormatDelegate {
|
||||
|
||||
private final JsonFormat.Parser parser;
|
||||
|
||||
private final JsonFormat.Printer printer;
|
||||
|
||||
public ProtobufJavaUtilSupport(JsonFormat.@Nullable Parser parser, JsonFormat.@Nullable Printer printer) {
|
||||
public ProtobufJavaUtilDelegate(JsonFormat.@Nullable Parser parser, JsonFormat.@Nullable Printer printer) {
|
||||
this.parser = (parser != null ? parser : JsonFormat.parser());
|
||||
this.printer = (printer != null ? printer : JsonFormat.printer());
|
||||
}
|
||||
@@ -302,12 +323,12 @@ public class ProtobufHttpMessageConverter extends AbstractHttpMessageConverter<M
|
||||
}
|
||||
|
||||
@Override
|
||||
public void merge(InputStream input, Charset charset, MediaType contentType,
|
||||
ExtensionRegistry extensionRegistry, Message.Builder builder)
|
||||
public void merge(HttpInputMessage inputMessage, MediaType contentType, Charset charset,
|
||||
Message.Builder builder, ExtensionRegistry extensionRegistry)
|
||||
throws IOException, HttpMessageConversionException {
|
||||
|
||||
if (contentType.isCompatibleWith(APPLICATION_JSON)) {
|
||||
InputStreamReader reader = new InputStreamReader(input, charset);
|
||||
InputStreamReader reader = new InputStreamReader(inputMessage.getBody(), charset);
|
||||
this.parser.merge(reader, builder);
|
||||
}
|
||||
else {
|
||||
@@ -317,11 +338,11 @@ public class ProtobufHttpMessageConverter extends AbstractHttpMessageConverter<M
|
||||
}
|
||||
|
||||
@Override
|
||||
public void print(Message message, OutputStream output, MediaType contentType, Charset charset)
|
||||
public void print(Message message, HttpOutputMessage outputMessage, MediaType contentType, Charset charset)
|
||||
throws IOException, HttpMessageConversionException {
|
||||
|
||||
if (contentType.isCompatibleWith(APPLICATION_JSON)) {
|
||||
OutputStreamWriter writer = new OutputStreamWriter(output, charset);
|
||||
OutputStreamWriter writer = new OutputStreamWriter(outputMessage.getBody(), charset);
|
||||
this.printer.appendTo(message, writer);
|
||||
writer.flush();
|
||||
}
|
||||
|
||||
+1
-1
@@ -71,7 +71,7 @@ public class ProtobufJsonFormatHttpMessageConverter extends ProtobufHttpMessageC
|
||||
public ProtobufJsonFormatHttpMessageConverter(JsonFormat.@Nullable Parser parser,
|
||||
JsonFormat.@Nullable Printer printer, @Nullable ExtensionRegistry extensionRegistry) {
|
||||
|
||||
super(new ProtobufJavaUtilSupport(parser, printer), extensionRegistry);
|
||||
super(new ProtobufJavaUtilDelegate(parser, printer), extensionRegistry);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user