Browse Source

Remove support for Protobuf 2.x and protobuf-java-format

Closes gh-31465
pull/31469/head
Brian Clozel 11 months ago
parent
commit
631a5d1dc1
  1. 3
      framework-platform/framework-platform.gradle
  2. 1
      spring-web/spring-web.gradle
  3. 103
      spring-web/src/main/java/org/springframework/http/converter/protobuf/ProtobufHttpMessageConverter.java
  4. 31
      spring-web/src/test/java/org/springframework/http/converter/protobuf/ProtobufHttpMessageConverterTests.java

3
framework-platform/framework-platform.gradle

@ -30,8 +30,7 @@ dependencies { @@ -30,8 +30,7 @@ dependencies {
api("com.google.code.findbugs:findbugs:3.0.1")
api("com.google.code.findbugs:jsr305:3.0.2")
api("com.google.code.gson:gson:2.10.1")
api("com.google.protobuf:protobuf-java-util:3.23.2")
api("com.googlecode.protobuf-java-format:protobuf-java-format:1.4")
api("com.google.protobuf:protobuf-java-util:3.24.4")
api("com.h2database:h2:2.2.220")
api("com.jayway.jsonpath:json-path:2.8.0")
api("com.rometools:rome:1.19.0")

1
spring-web/spring-web.gradle

@ -18,7 +18,6 @@ dependencies { @@ -18,7 +18,6 @@ dependencies {
optional("com.fasterxml.woodstox:woodstox-core")
optional("com.google.code.gson:gson")
optional("com.google.protobuf:protobuf-java-util")
optional("com.googlecode.protobuf-java-format:protobuf-java-format")
optional("com.rometools:rome")
optional("com.squareup.okhttp3:okhttp")
optional("io.reactivex.rxjava3:rxjava")

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

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2002-2022 the original author or authors.
* Copyright 2002-2023 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.
@ -32,8 +32,6 @@ import com.google.protobuf.ExtensionRegistry; @@ -32,8 +32,6 @@ import com.google.protobuf.ExtensionRegistry;
import com.google.protobuf.Message;
import com.google.protobuf.TextFormat;
import com.google.protobuf.util.JsonFormat;
import com.googlecode.protobuf.format.FormatFactory;
import com.googlecode.protobuf.format.ProtobufFormatter;
import org.springframework.http.HttpInputMessage;
import org.springframework.http.HttpOutputMessage;
@ -48,8 +46,6 @@ import org.springframework.util.ClassUtils; @@ -48,8 +46,6 @@ import org.springframework.util.ClassUtils;
import org.springframework.util.ConcurrentReferenceHashMap;
import static org.springframework.http.MediaType.APPLICATION_JSON;
import static org.springframework.http.MediaType.APPLICATION_XML;
import static org.springframework.http.MediaType.TEXT_HTML;
import static org.springframework.http.MediaType.TEXT_PLAIN;
/**
@ -60,26 +56,17 @@ import static org.springframework.http.MediaType.TEXT_PLAIN; @@ -60,26 +56,17 @@ import static org.springframework.http.MediaType.TEXT_PLAIN;
* <p>To generate {@code Message} Java classes, you need to install the {@code protoc} binary.
*
* <p>This converter supports by default {@code "application/x-protobuf"} and {@code "text/plain"}
* with the official {@code "com.google.protobuf:protobuf-java"} library. Other formats can be
* supported with one of the following additional libraries on the classpath:
* <ul>
* <li>{@code "application/json"}, {@code "application/xml"}, and {@code "text/html"} (write-only)
* with the {@code "com.googlecode.protobuf-java-format:protobuf-java-format"} third-party library
* <li>{@code "application/json"} with the official {@code "com.google.protobuf:protobuf-java-util"}
* for Protobuf 3 (see {@link ProtobufJsonFormatHttpMessageConverter} for a configurable variant)
* </ul>
* with the official {@code "com.google.protobuf:protobuf-java"} library.
* The {@code "application/json"} format is also supported with the {@code "com.google.protobuf:protobuf-java-util"}
* dependency. See {@link ProtobufJsonFormatHttpMessageConverter} for a configurable variant.
*
* <p>Requires Protobuf 2.6 or higher (and Protobuf Java Format 1.4 or higher for formatting).
* This converter will auto-adapt to Protobuf 3 and its default {@code protobuf-java-util} JSON
* format if the Protobuf 2 based {@code protobuf-java-format} isn't present; however, for more
* explicit JSON setup on Protobuf 3, consider {@link ProtobufJsonFormatHttpMessageConverter}.
* <p>This converter requires Protobuf 3 or higher as of Spring Framework 6.1.
*
* @author Alex Antonov
* @author Brian Clozel
* @author Juergen Hoeller
* @author Sebastien Deleuze
* @since 4.1
* @see FormatFactory
* @see JsonFormat
* @see ProtobufJsonFormatHttpMessageConverter
*/
@ -105,18 +92,10 @@ public class ProtobufHttpMessageConverter extends AbstractHttpMessageConverter<M @@ -105,18 +92,10 @@ public class ProtobufHttpMessageConverter extends AbstractHttpMessageConverter<M
*/
public static final String X_PROTOBUF_MESSAGE_HEADER = "X-Protobuf-Message";
private static final boolean protobufFormatFactoryPresent;
private static final boolean protobufJsonFormatPresent;
private static final boolean protobufJsonFormatPresent = ClassUtils.isPresent("com.google.protobuf.util.JsonFormat", ProtobufHttpMessageConverter.class.getClassLoader());
private static final Map<Class<?>, Method> methodCache = new ConcurrentReferenceHashMap<>();
static {
ClassLoader classLoader = ProtobufHttpMessageConverter.class.getClassLoader();
protobufFormatFactoryPresent = ClassUtils.isPresent("com.googlecode.protobuf.format.FormatFactory", classLoader);
protobufJsonFormatPresent = ClassUtils.isPresent("com.google.protobuf.util.JsonFormat", classLoader);
}
final ExtensionRegistry extensionRegistry;
@ -146,9 +125,6 @@ public class ProtobufHttpMessageConverter extends AbstractHttpMessageConverter<M @@ -146,9 +125,6 @@ public class ProtobufHttpMessageConverter extends AbstractHttpMessageConverter<M
if (formatSupport != null) {
this.protobufFormatSupport = formatSupport;
}
else if (protobufFormatFactoryPresent) {
this.protobufFormatSupport = new ProtobufJavaFormatSupport();
}
else if (protobufJsonFormatPresent) {
this.protobufFormatSupport = new ProtobufJavaUtilSupport(null, null);
}
@ -290,73 +266,6 @@ public class ProtobufHttpMessageConverter extends AbstractHttpMessageConverter<M @@ -290,73 +266,6 @@ public class ProtobufHttpMessageConverter extends AbstractHttpMessageConverter<M
}
/**
* {@link ProtobufFormatSupport} implementation used when
* {@code com.googlecode.protobuf.format.FormatFactory} is available.
*/
static class ProtobufJavaFormatSupport implements ProtobufFormatSupport {
private final ProtobufFormatter jsonFormatter;
private final ProtobufFormatter xmlFormatter;
private final ProtobufFormatter htmlFormatter;
public ProtobufJavaFormatSupport() {
FormatFactory formatFactory = new FormatFactory();
this.jsonFormatter = formatFactory.createFormatter(FormatFactory.Formatter.JSON);
this.xmlFormatter = formatFactory.createFormatter(FormatFactory.Formatter.XML);
this.htmlFormatter = formatFactory.createFormatter(FormatFactory.Formatter.HTML);
}
@Override
public MediaType[] supportedMediaTypes() {
return new MediaType[] {PROTOBUF, TEXT_PLAIN, APPLICATION_XML, APPLICATION_JSON};
}
@Override
public boolean supportsWriteOnly(@Nullable MediaType mediaType) {
return TEXT_HTML.isCompatibleWith(mediaType);
}
@Override
public void merge(InputStream input, Charset charset, MediaType contentType,
ExtensionRegistry extensionRegistry, Message.Builder builder)
throws IOException, HttpMessageConversionException {
if (contentType.isCompatibleWith(APPLICATION_JSON)) {
this.jsonFormatter.merge(input, charset, extensionRegistry, builder);
}
else if (contentType.isCompatibleWith(APPLICATION_XML)) {
this.xmlFormatter.merge(input, charset, extensionRegistry, builder);
}
else {
throw new HttpMessageConversionException(
"protobuf-java-format does not support parsing " + contentType);
}
}
@Override
public void print(Message message, OutputStream output, MediaType contentType, Charset charset)
throws IOException, HttpMessageConversionException {
if (contentType.isCompatibleWith(APPLICATION_JSON)) {
this.jsonFormatter.print(message, output, charset);
}
else if (contentType.isCompatibleWith(APPLICATION_XML)) {
this.xmlFormatter.print(message, output, charset);
}
else if (contentType.isCompatibleWith(TEXT_HTML)) {
this.htmlFormatter.print(message, output, charset);
}
else {
throw new HttpMessageConversionException(
"protobuf-java-format does not support printing " + contentType);
}
}
}
/**
* {@link ProtobufFormatSupport} implementation used when
* {@code com.google.protobuf.util.JsonFormat} is available.

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

@ -55,11 +55,7 @@ class ProtobufHttpMessageConverterTests { @@ -55,11 +55,7 @@ class ProtobufHttpMessageConverterTests {
assertThat(this.converter.canRead(Msg.class, null)).isTrue();
assertThat(this.converter.canRead(Msg.class, ProtobufHttpMessageConverter.PROTOBUF)).isTrue();
assertThat(this.converter.canRead(Msg.class, MediaType.APPLICATION_JSON)).isTrue();
assertThat(this.converter.canRead(Msg.class, MediaType.APPLICATION_XML)).isTrue();
assertThat(this.converter.canRead(Msg.class, MediaType.TEXT_PLAIN)).isTrue();
// only supported as an output format
assertThat(this.converter.canRead(Msg.class, MediaType.TEXT_HTML)).isFalse();
}
@Test
@ -67,9 +63,7 @@ class ProtobufHttpMessageConverterTests { @@ -67,9 +63,7 @@ class ProtobufHttpMessageConverterTests {
assertThat(this.converter.canWrite(Msg.class, null)).isTrue();
assertThat(this.converter.canWrite(Msg.class, ProtobufHttpMessageConverter.PROTOBUF)).isTrue();
assertThat(this.converter.canWrite(Msg.class, MediaType.APPLICATION_JSON)).isTrue();
assertThat(this.converter.canWrite(Msg.class, MediaType.APPLICATION_XML)).isTrue();
assertThat(this.converter.canWrite(Msg.class, MediaType.TEXT_PLAIN)).isTrue();
assertThat(this.converter.canWrite(Msg.class, MediaType.TEXT_HTML)).isTrue();
}
@Test
@ -131,31 +125,6 @@ class ProtobufHttpMessageConverterTests { @@ -131,31 +125,6 @@ class ProtobufHttpMessageConverterTests {
ProtobufHttpMessageConverter.X_PROTOBUF_SCHEMA_HEADER)).isNull();
}
@Test
void writeJsonWithJavaFormat() throws IOException {
this.converter = new ProtobufHttpMessageConverter(
new ProtobufHttpMessageConverter.ProtobufJavaFormatSupport(),
this.extensionRegistry);
MockHttpOutputMessage outputMessage = new MockHttpOutputMessage();
@SuppressWarnings("deprecation")
MediaType contentType = MediaType.APPLICATION_JSON_UTF8;
this.converter.write(this.testMsg, contentType, outputMessage);
assertThat(outputMessage.getHeaders().getContentType()).isEqualTo(contentType);
String body = outputMessage.getBodyAsString(StandardCharsets.UTF_8);
assertThat(body).as("body is empty").isNotEmpty();
Msg.Builder builder = Msg.newBuilder();
JsonFormat.parser().merge(body, builder);
assertThat(builder.build()).isEqualTo(this.testMsg);
assertThat(outputMessage.getHeaders().getFirst(
ProtobufHttpMessageConverter.X_PROTOBUF_MESSAGE_HEADER)).isNull();
assertThat(outputMessage.getHeaders().getFirst(
ProtobufHttpMessageConverter.X_PROTOBUF_SCHEMA_HEADER)).isNull();
}
@Test
void defaultContentType() throws Exception {
assertThat(this.converter.getDefaultContentType(this.testMsg))

Loading…
Cancel
Save