Skip to content

Commit e8af432

Browse files
committed
Added support for "application/*+x-protobuf" media type
Signed-off-by: Kamil Doroszkiewicz <[email protected]>
1 parent 7d0cc6c commit e8af432

File tree

3 files changed

+20
-8
lines changed

3 files changed

+20
-8
lines changed

spring-web/src/main/java/org/springframework/http/converter/protobuf/ProtobufHttpMessageConverter.java

+14-8
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,6 @@
4141
import org.springframework.http.converter.HttpMessageConversionException;
4242
import org.springframework.http.converter.HttpMessageNotReadableException;
4343
import org.springframework.http.converter.HttpMessageNotWritableException;
44-
import org.springframework.util.Assert;
4544
import org.springframework.util.ClassUtils;
4645
import org.springframework.util.ConcurrentReferenceHashMap;
4746

@@ -55,8 +54,8 @@
5554
*
5655
* <p>To generate {@code Message} Java classes, you need to install the {@code protoc} binary.
5756
*
58-
* <p>This converter supports by default {@code "application/x-protobuf"} and {@code "text/plain"}
59-
* with the official {@code "com.google.protobuf:protobuf-java"} library.
57+
* <p>This converter supports by default {@code "application/x-protobuf"}, {@code "application/*+x-protobuf"}
58+
* and {@code "text/plain"} with the official {@code "com.google.protobuf:protobuf-java"} library.
6059
* The {@code "application/json"} format is also supported with the {@code "com.google.protobuf:protobuf-java-util"}
6160
* dependency. See {@link ProtobufJsonFormatHttpMessageConverter} for a configurable variant.
6261
*
@@ -66,6 +65,7 @@
6665
* @author Brian Clozel
6766
* @author Juergen Hoeller
6867
* @author Sebastien Deleuze
68+
* @author Kamil Doroszkiewicz
6969
* @since 4.1
7070
* @see JsonFormat
7171
* @see ProtobufJsonFormatHttpMessageConverter
@@ -82,6 +82,11 @@ public class ProtobufHttpMessageConverter extends AbstractHttpMessageConverter<M
8282
*/
8383
public static final MediaType PROTOBUF = new MediaType("application", "x-protobuf", DEFAULT_CHARSET);
8484

85+
/**
86+
* The media-type for protobuf {@code application/*+x-protobuf}.
87+
*/
88+
public static final MediaType PLUS_PROTOBUF = new MediaType("application", "*+x-protobuf", DEFAULT_CHARSET);
89+
8590
/**
8691
* The HTTP header containing the protobuf schema.
8792
*/
@@ -132,7 +137,7 @@ else if (protobufJsonFormatPresent) {
132137
}
133138

134139
setSupportedMediaTypes(Arrays.asList(this.protobufFormatSupport != null ?
135-
this.protobufFormatSupport.supportedMediaTypes() : new MediaType[] {PROTOBUF, TEXT_PLAIN}));
140+
this.protobufFormatSupport.supportedMediaTypes() : new MediaType[] {PROTOBUF, PLUS_PROTOBUF, TEXT_PLAIN}));
136141

137142
this.extensionRegistry = (extensionRegistry == null ? ExtensionRegistry.newInstance() : extensionRegistry);
138143
}
@@ -162,7 +167,8 @@ protected Message readInternal(Class<? extends Message> clazz, HttpInputMessage
162167
}
163168

164169
Message.Builder builder = getMessageBuilder(clazz);
165-
if (PROTOBUF.isCompatibleWith(contentType)) {
170+
if (PROTOBUF.isCompatibleWith(contentType) ||
171+
PLUS_PROTOBUF.isCompatibleWith(contentType)) {
166172
builder.mergeFrom(inputMessage.getBody(), this.extensionRegistry);
167173
}
168174
else if (TEXT_PLAIN.isCompatibleWith(contentType)) {
@@ -209,14 +215,14 @@ protected void writeInternal(Message message, HttpOutputMessage outputMessage)
209215
MediaType contentType = outputMessage.getHeaders().getContentType();
210216
if (contentType == null) {
211217
contentType = getDefaultContentType(message);
212-
Assert.state(contentType != null, "No content type");
213218
}
214219
Charset charset = contentType.getCharset();
215220
if (charset == null) {
216221
charset = DEFAULT_CHARSET;
217222
}
218223

219-
if (PROTOBUF.isCompatibleWith(contentType)) {
224+
if (PROTOBUF.isCompatibleWith(contentType) ||
225+
PLUS_PROTOBUF.isCompatibleWith(contentType)) {
220226
setProtoHeader(outputMessage, message);
221227
CodedOutputStream codedOutputStream = CodedOutputStream.newInstance(outputMessage.getBody());
222228
message.writeTo(codedOutputStream);
@@ -285,7 +291,7 @@ public ProtobufJavaUtilSupport(JsonFormat.@Nullable Parser parser, JsonFormat.@N
285291

286292
@Override
287293
public MediaType[] supportedMediaTypes() {
288-
return new MediaType[] {PROTOBUF, TEXT_PLAIN, APPLICATION_JSON};
294+
return new MediaType[] {PROTOBUF, PLUS_PROTOBUF, TEXT_PLAIN, APPLICATION_JSON};
289295
}
290296

291297
@Override

spring-web/src/test/java/org/springframework/http/converter/protobuf/ProtobufHttpMessageConverterTests.java

+3
Original file line numberDiff line numberDiff line change
@@ -48,12 +48,14 @@ class ProtobufHttpMessageConverterTests {
4848
private ExtensionRegistry extensionRegistry = mock();
4949

5050
private Msg testMsg = Msg.newBuilder().setFoo("Foo").setBlah(SecondMsg.newBuilder().setBlah(123).build()).build();
51+
private MediaType testPlusProtoMediaType = MediaType.parseMediaType("application/vnd.example.public.v1+x-protobuf");
5152

5253

5354
@Test
5455
void canRead() {
5556
assertThat(this.converter.canRead(Msg.class, null)).isTrue();
5657
assertThat(this.converter.canRead(Msg.class, ProtobufHttpMessageConverter.PROTOBUF)).isTrue();
58+
assertThat(this.converter.canRead(Msg.class, this.testPlusProtoMediaType)).isTrue();
5759
assertThat(this.converter.canRead(Msg.class, MediaType.APPLICATION_JSON)).isTrue();
5860
assertThat(this.converter.canRead(Msg.class, MediaType.TEXT_PLAIN)).isTrue();
5961
}
@@ -62,6 +64,7 @@ void canRead() {
6264
void canWrite() {
6365
assertThat(this.converter.canWrite(Msg.class, null)).isTrue();
6466
assertThat(this.converter.canWrite(Msg.class, ProtobufHttpMessageConverter.PROTOBUF)).isTrue();
67+
assertThat(this.converter.canRead(Msg.class, this.testPlusProtoMediaType)).isTrue();
6568
assertThat(this.converter.canWrite(Msg.class, MediaType.APPLICATION_JSON)).isTrue();
6669
assertThat(this.converter.canWrite(Msg.class, MediaType.TEXT_PLAIN)).isTrue();
6770
}

spring-web/src/test/java/org/springframework/http/converter/protobuf/ProtobufJsonFormatHttpMessageConverterTests.java

+3
Original file line numberDiff line numberDiff line change
@@ -42,12 +42,14 @@ class ProtobufJsonFormatHttpMessageConverterTests {
4242
JsonFormat.parser(), JsonFormat.printer());
4343

4444
private final Msg testMsg = Msg.newBuilder().setFoo("Foo").setBlah(SecondMsg.newBuilder().setBlah(123).build()).build();
45+
private MediaType testPlusProtoMediaType = MediaType.parseMediaType("application/vnd.examle.public.v1+x-protobuf");
4546

4647

4748
@Test
4849
void canRead() {
4950
assertThat(this.converter.canRead(Msg.class, null)).isTrue();
5051
assertThat(this.converter.canRead(Msg.class, ProtobufHttpMessageConverter.PROTOBUF)).isTrue();
52+
assertThat(this.converter.canRead(Msg.class, this.testPlusProtoMediaType)).isTrue();
5153
assertThat(this.converter.canRead(Msg.class, MediaType.APPLICATION_JSON)).isTrue();
5254
assertThat(this.converter.canRead(Msg.class, MediaType.TEXT_PLAIN)).isTrue();
5355
}
@@ -56,6 +58,7 @@ void canRead() {
5658
void canWrite() {
5759
assertThat(this.converter.canWrite(Msg.class, null)).isTrue();
5860
assertThat(this.converter.canWrite(Msg.class, ProtobufHttpMessageConverter.PROTOBUF)).isTrue();
61+
assertThat(this.converter.canWrite(Msg.class, this.testPlusProtoMediaType)).isTrue();
5962
assertThat(this.converter.canWrite(Msg.class, MediaType.APPLICATION_JSON)).isTrue();
6063
assertThat(this.converter.canWrite(Msg.class, MediaType.TEXT_PLAIN)).isTrue();
6164
}

0 commit comments

Comments
 (0)