mirror of
https://github.com/spring-projects/spring-framework.git
synced 2026-09-17 08:24:13 +00:00
Merge branch '7.0.x'
This commit is contained in:
+13
-14
@@ -173,6 +173,19 @@ public class ProtobufDecoder extends ProtobufCodecSupport implements Decoder<Mes
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new {@code Message.Builder} instance for the given class.
|
||||
* <p>This method uses a ConcurrentHashMap for caching method lookups.
|
||||
*/
|
||||
protected static Message.Builder getMessageBuilder(Class<?> clazz) throws Exception {
|
||||
Method method = methodCache.get(clazz);
|
||||
if (method == null) {
|
||||
method = clazz.getMethod("newBuilder");
|
||||
methodCache.put(clazz, method);
|
||||
}
|
||||
return (Message.Builder) method.invoke(clazz);
|
||||
}
|
||||
|
||||
/**
|
||||
* Use merge methods on {@link Message.Builder} to read a single message
|
||||
* from the given {@code DataBuffer}.
|
||||
@@ -184,20 +197,6 @@ public class ProtobufDecoder extends ProtobufCodecSupport implements Decoder<Mes
|
||||
builder.mergeFrom(CodedInputStream.newInstance(byteBuffer), this.extensionRegistry);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create a new {@code Message.Builder} instance for the given class.
|
||||
* <p>This method uses a ConcurrentHashMap for caching method lookups.
|
||||
*/
|
||||
private static Message.Builder getMessageBuilder(Class<?> clazz) throws Exception {
|
||||
Method method = methodCache.get(clazz);
|
||||
if (method == null) {
|
||||
method = clazz.getMethod("newBuilder");
|
||||
methodCache.put(clazz, method);
|
||||
}
|
||||
return (Message.Builder) method.invoke(clazz);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<MimeType> getDecodableMimeTypes() {
|
||||
return getMimeTypes();
|
||||
|
||||
@@ -54,6 +54,7 @@ import org.springframework.util.MimeType;
|
||||
*
|
||||
* @author Sebastien Deleuze
|
||||
* @since 5.1
|
||||
* @see ProtobufHttpMessageWriter
|
||||
* @see ProtobufDecoder
|
||||
*/
|
||||
public class ProtobufEncoder extends ProtobufCodecSupport implements HttpMessageEncoder<Message> {
|
||||
|
||||
+13
-13
@@ -95,6 +95,19 @@ public class ProtobufHttpMessageWriter extends EncoderHttpMessageWriter<Message>
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new {@code Message.Builder} instance for the given class.
|
||||
* <p>This method uses a ConcurrentHashMap for caching method lookups.
|
||||
*/
|
||||
protected static Message.Builder getMessageBuilder(Class<?> clazz) throws Exception {
|
||||
Method method = methodCache.get(clazz);
|
||||
if (method == null) {
|
||||
method = clazz.getMethod("newBuilder");
|
||||
methodCache.put(clazz, method);
|
||||
}
|
||||
return (Message.Builder) method.invoke(clazz);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the {@code MediaType} to use when the input Publisher is multivalued.
|
||||
* @since 7.0
|
||||
@@ -118,17 +131,4 @@ public class ProtobufHttpMessageWriter extends EncoderHttpMessageWriter<Message>
|
||||
protected void extendHeaders(ReactiveHttpOutputMessage message, Map<String, Object> hints) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new {@code Message.Builder} instance for the given class.
|
||||
* <p>This method uses a ConcurrentHashMap for caching method lookups.
|
||||
*/
|
||||
private static Message.Builder getMessageBuilder(Class<?> clazz) throws Exception {
|
||||
Method method = methodCache.get(clazz);
|
||||
if (method == null) {
|
||||
method = clazz.getMethod("newBuilder");
|
||||
methodCache.put(clazz, method);
|
||||
}
|
||||
return (Message.Builder) method.invoke(clazz);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+1
-1
@@ -161,7 +161,7 @@ public class ProtobufJsonDecoder implements Decoder<Message> {
|
||||
* Create a new {@code Message.Builder} instance for the given class.
|
||||
* <p>This method uses a ConcurrentHashMap for caching method lookups.
|
||||
*/
|
||||
private static Message.Builder getMessageBuilder(Class<?> clazz) throws Exception {
|
||||
protected static Message.Builder getMessageBuilder(Class<?> clazz) throws Exception {
|
||||
Method method = methodCache.get(clazz);
|
||||
if (method == null) {
|
||||
method = clazz.getMethod("newBuilder");
|
||||
|
||||
+15
-5
@@ -49,6 +49,7 @@ import org.springframework.util.MimeType;
|
||||
*
|
||||
* @author Brian Clozel
|
||||
* @since 6.2
|
||||
* @see ProtobufHttpMessageWriter
|
||||
* @see ProtobufJsonDecoder
|
||||
*/
|
||||
public class ProtobufJsonEncoder implements HttpMessageEncoder<Message> {
|
||||
@@ -59,7 +60,8 @@ public class ProtobufJsonEncoder implements HttpMessageEncoder<Message> {
|
||||
|
||||
private static final List<MimeType> defaultMimeTypes = List.of(
|
||||
MediaType.APPLICATION_JSON,
|
||||
new MediaType("application", "*+json"));
|
||||
new MediaType("application", "*+json"),
|
||||
MediaType.APPLICATION_NDJSON);
|
||||
|
||||
private final JsonFormat.Printer printer;
|
||||
|
||||
@@ -106,7 +108,10 @@ public class ProtobufJsonEncoder implements HttpMessageEncoder<Message> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Flux<DataBuffer> encode(Publisher<? extends Message> inputStream, DataBufferFactory bufferFactory, ResolvableType elementType, @Nullable MimeType mimeType, @Nullable Map<String, Object> hints) {
|
||||
public Flux<DataBuffer> encode(
|
||||
Publisher<? extends Message> inputStream, DataBufferFactory bufferFactory,
|
||||
ResolvableType elementType, @Nullable MimeType mimeType, @Nullable Map<String, Object> hints) {
|
||||
|
||||
if (inputStream instanceof Mono) {
|
||||
return Mono.from(inputStream)
|
||||
.map(value -> encodeValue(value, bufferFactory, elementType, mimeType, hints))
|
||||
@@ -120,17 +125,21 @@ public class ProtobufJsonEncoder implements HttpMessageEncoder<Message> {
|
||||
.map(value -> {
|
||||
byte[] prefix = helper.getPrefix();
|
||||
byte[] delimiter = helper.getDelimiter();
|
||||
DataBuffer delimiterBuffer = bufferFactory.wrap(delimiter);
|
||||
DataBuffer dataBuffer = encodeValue(value, bufferFactory, MESSAGE_TYPE, mimeType, hints);
|
||||
return (prefix.length > 0 ?
|
||||
bufferFactory.join(List.of(bufferFactory.wrap(prefix), bufferFactory.wrap(delimiter), dataBuffer)) :
|
||||
bufferFactory.join(List.of(bufferFactory.wrap(delimiter), dataBuffer)));
|
||||
bufferFactory.join(List.of(bufferFactory.wrap(prefix), delimiterBuffer, dataBuffer)) :
|
||||
bufferFactory.join(List.of(delimiterBuffer, dataBuffer)));
|
||||
})
|
||||
.switchIfEmpty(Mono.fromCallable(() -> bufferFactory.wrap(helper.getPrefix())))
|
||||
.concatWith(Mono.fromCallable(() -> bufferFactory.wrap(helper.getSuffix())));
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataBuffer encodeValue(Message message, DataBufferFactory bufferFactory, ResolvableType valueType, @Nullable MimeType mimeType, @Nullable Map<String, Object> hints) {
|
||||
public DataBuffer encodeValue(
|
||||
Message message, DataBufferFactory bufferFactory, ResolvableType valueType,
|
||||
@Nullable MimeType mimeType, @Nullable Map<String, Object> hints) {
|
||||
|
||||
FastByteArrayOutputStream bos = new FastByteArrayOutputStream();
|
||||
OutputStreamWriter writer = new OutputStreamWriter(bos, StandardCharsets.UTF_8);
|
||||
try {
|
||||
@@ -144,6 +153,7 @@ public class ProtobufJsonEncoder implements HttpMessageEncoder<Message> {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static class JsonArrayJoinHelper {
|
||||
|
||||
private static final byte[] COMMA_SEPARATOR = {','};
|
||||
|
||||
+15
-9
@@ -43,22 +43,28 @@ import static org.springframework.core.ResolvableType.forClass;
|
||||
*/
|
||||
class ProtobufJsonEncoderTests extends AbstractEncoderTests<ProtobufJsonEncoder> {
|
||||
|
||||
private Msg msg1 =
|
||||
Msg.newBuilder().setFoo("Foo").setBlah(SecondMsg.newBuilder().setBlah(123).build()).build();
|
||||
private Msg msg1 = Msg.newBuilder()
|
||||
.setFoo("Foo")
|
||||
.setBlah(SecondMsg.newBuilder().setBlah(123).build())
|
||||
.build();
|
||||
|
||||
private Msg msg2 = Msg.newBuilder()
|
||||
.setFoo("Bar")
|
||||
.setBlah(SecondMsg.newBuilder().setBlah(456).build())
|
||||
.build();
|
||||
|
||||
private Msg msg2 =
|
||||
Msg.newBuilder().setFoo("Bar").setBlah(SecondMsg.newBuilder().setBlah(456).build()).build();
|
||||
|
||||
public ProtobufJsonEncoderTests() {
|
||||
super(new ProtobufJsonEncoder(JsonFormat.printer().omittingInsignificantWhitespace()));
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
@Test
|
||||
protected void canEncode() throws Exception {
|
||||
assertThat(this.encoder.canEncode(forClass(Msg.class), null)).isFalse();
|
||||
assertThat(this.encoder.canEncode(forClass(Msg.class), MediaType.APPLICATION_JSON)).isTrue();
|
||||
assertThat(this.encoder.canEncode(forClass(Msg.class), MediaType.APPLICATION_NDJSON)).isFalse();
|
||||
assertThat(this.encoder.canEncode(forClass(Msg.class), MediaType.APPLICATION_NDJSON)).isTrue();
|
||||
assertThat(this.encoder.canEncode(forClass(Object.class), MediaType.APPLICATION_JSON)).isFalse();
|
||||
}
|
||||
|
||||
@@ -69,7 +75,7 @@ class ProtobufJsonEncoderTests extends AbstractEncoderTests<ProtobufJsonEncoder>
|
||||
ResolvableType inputType = forClass(Msg.class);
|
||||
|
||||
testEncode(input, inputType, MediaType.APPLICATION_JSON, null, step -> step
|
||||
.assertNext(dataBuffer -> assertBufferEqualsJson(dataBuffer, "{\"foo\":\"Foo\",\"blah\":{\"blah\":123}}"))
|
||||
.assertNext(buffer -> assertBufferEqualsJson(buffer, "{\"foo\":\"Foo\",\"blah\":{\"blah\":123}}"))
|
||||
.verifyComplete());
|
||||
testEncodeError(input, inputType, MediaType.APPLICATION_JSON, null);
|
||||
testEncodeCancel(input, inputType, MediaType.APPLICATION_JSON, null);
|
||||
@@ -91,9 +97,9 @@ class ProtobufJsonEncoderTests extends AbstractEncoderTests<ProtobufJsonEncoder>
|
||||
ResolvableType inputType = forClass(Msg.class);
|
||||
|
||||
testEncode(input, inputType, MediaType.APPLICATION_JSON, null, step -> step
|
||||
.assertNext(dataBuffer -> assertBufferEqualsJson(dataBuffer, "[{\"foo\":\"Foo\",\"blah\":{\"blah\":123}}"))
|
||||
.assertNext(dataBuffer -> assertBufferEqualsJson(dataBuffer, ",{\"foo\":\"Bar\",\"blah\":{\"blah\":456}}"))
|
||||
.assertNext(dataBuffer -> assertBufferEqualsJson(dataBuffer, "]"))
|
||||
.assertNext(buffer -> assertBufferEqualsJson(buffer, "[{\"foo\":\"Foo\",\"blah\":{\"blah\":123}}"))
|
||||
.assertNext(buffer -> assertBufferEqualsJson(buffer, ",{\"foo\":\"Bar\",\"blah\":{\"blah\":456}}"))
|
||||
.assertNext(buffer -> assertBufferEqualsJson(buffer, "]"))
|
||||
.verifyComplete());
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user