From e7cca7792d9281aacecb422bc51a758d67d27e6c Mon Sep 17 00:00:00 2001 From: Arjen Poutsma Date: Wed, 8 May 2019 11:45:54 +0200 Subject: [PATCH] Add way to override default multipartReader This commit introduces a way to override the default multipart reader, for instance to the SynchronossPartHttpMessageReader. --- .../http/codec/ServerCodecConfigurer.java | 18 +++++++-- .../support/ServerDefaultCodecsImpl.java | 40 +++++++++++-------- .../support/ServerCodecConfigurerTests.java | 6 +-- 3 files changed, 42 insertions(+), 22 deletions(-) diff --git a/spring-web/src/main/java/org/springframework/http/codec/ServerCodecConfigurer.java b/spring-web/src/main/java/org/springframework/http/codec/ServerCodecConfigurer.java index 9e4350e72e..ba8d19a3d4 100644 --- a/spring-web/src/main/java/org/springframework/http/codec/ServerCodecConfigurer.java +++ b/spring-web/src/main/java/org/springframework/http/codec/ServerCodecConfigurer.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2019 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. @@ -17,6 +17,7 @@ package org.springframework.http.codec; import org.springframework.core.codec.Encoder; +import org.springframework.http.codec.multipart.Part; /** * Extension of {@link CodecConfigurer} for HTTP message reader and writer @@ -79,10 +80,21 @@ public interface ServerCodecConfigurer extends CodecConfigurer { /** * Configure the {@code Encoder} to use for Server-Sent Events. *

By default if this is not set, and Jackson is available, the - * {@link #jackson2JsonEncoder} override is used instead. Use this property - * if you want to further customize the SSE encoder. + * {@link #jackson2JsonEncoder} override is used instead. Use this method + * to customize the SSE encoder. */ void serverSentEventEncoder(Encoder encoder); + + /** + * Configure the {@code HttpMessageReader} to use for multipart messages + * (i.e. file uploads). + *

By default if this is not set, the + * {@link org.springframework.http.codec.multipart.DefaultMultipartMessageReader} is used. + * Use this method to customize the multipart reader, for instance to use + * {@link org.springframework.http.codec.multipart.SynchronossPartHttpMessageReader} + * instead. + */ + void multipartReader(HttpMessageReader multipartReader); } } diff --git a/spring-web/src/main/java/org/springframework/http/codec/support/ServerDefaultCodecsImpl.java b/spring-web/src/main/java/org/springframework/http/codec/support/ServerDefaultCodecsImpl.java index 15461d11f4..4529cd5f5b 100644 --- a/spring-web/src/main/java/org/springframework/http/codec/support/ServerDefaultCodecsImpl.java +++ b/spring-web/src/main/java/org/springframework/http/codec/support/ServerDefaultCodecsImpl.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2019 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. @@ -20,12 +20,13 @@ import java.util.List; import org.springframework.core.codec.Encoder; import org.springframework.http.codec.HttpMessageReader; import org.springframework.http.codec.HttpMessageWriter; +import org.springframework.http.codec.LoggingCodecSupport; import org.springframework.http.codec.ServerCodecConfigurer; import org.springframework.http.codec.ServerSentEventHttpMessageWriter; +import org.springframework.http.codec.multipart.DefaultMultipartMessageReader; import org.springframework.http.codec.multipart.MultipartHttpMessageReader; -import org.springframework.http.codec.multipart.SynchronossPartHttpMessageReader; +import org.springframework.http.codec.multipart.Part; import org.springframework.lang.Nullable; -import org.springframework.util.ClassUtils; /** * Default implementation of {@link ServerCodecConfigurer.ServerDefaultCodecs}. @@ -34,34 +35,41 @@ import org.springframework.util.ClassUtils; */ class ServerDefaultCodecsImpl extends BaseDefaultCodecs implements ServerCodecConfigurer.ServerDefaultCodecs { - private static final boolean synchronossMultipartPresent = - ClassUtils.isPresent("org.synchronoss.cloud.nio.multipart.NioMultipartParser", - DefaultServerCodecConfigurer.class.getClassLoader()); - - @Nullable private Encoder sseEncoder; + @Nullable + private HttpMessageReader multipartReader; @Override public void serverSentEventEncoder(Encoder encoder) { this.sseEncoder = encoder; } + @Override + public void multipartReader(HttpMessageReader multipartReader) { + this.multipartReader = multipartReader; + } + @Override protected void extendTypedReaders(List> typedReaders) { - if (synchronossMultipartPresent) { - boolean enable = isEnableLoggingRequestDetails(); - SynchronossPartHttpMessageReader partReader = new SynchronossPartHttpMessageReader(); - partReader.setEnableLoggingRequestDetails(enable); - typedReaders.add(partReader); + HttpMessageReader partReader = getMultipartReader(); - MultipartHttpMessageReader reader = new MultipartHttpMessageReader(partReader); - reader.setEnableLoggingRequestDetails(enable); - typedReaders.add(reader); + boolean logRequestDetails = isEnableLoggingRequestDetails(); + if (partReader instanceof LoggingCodecSupport) { + ((LoggingCodecSupport) partReader).setEnableLoggingRequestDetails(logRequestDetails); } + typedReaders.add(partReader); + + MultipartHttpMessageReader reader = new MultipartHttpMessageReader(partReader); + reader.setEnableLoggingRequestDetails(logRequestDetails); + typedReaders.add(reader); + } + + private HttpMessageReader getMultipartReader() { + return this.multipartReader != null ? this.multipartReader : new DefaultMultipartMessageReader(); } @Override diff --git a/spring-web/src/test/java/org/springframework/http/codec/support/ServerCodecConfigurerTests.java b/spring-web/src/test/java/org/springframework/http/codec/support/ServerCodecConfigurerTests.java index dd01022d55..061dfd2e7d 100644 --- a/spring-web/src/test/java/org/springframework/http/codec/support/ServerCodecConfigurerTests.java +++ b/spring-web/src/test/java/org/springframework/http/codec/support/ServerCodecConfigurerTests.java @@ -52,8 +52,8 @@ import org.springframework.http.codec.json.Jackson2JsonDecoder; import org.springframework.http.codec.json.Jackson2JsonEncoder; import org.springframework.http.codec.json.Jackson2SmileDecoder; import org.springframework.http.codec.json.Jackson2SmileEncoder; +import org.springframework.http.codec.multipart.DefaultMultipartMessageReader; import org.springframework.http.codec.multipart.MultipartHttpMessageReader; -import org.springframework.http.codec.multipart.SynchronossPartHttpMessageReader; import org.springframework.http.codec.protobuf.ProtobufDecoder; import org.springframework.http.codec.protobuf.ProtobufHttpMessageWriter; import org.springframework.http.codec.xml.Jaxb2XmlDecoder; @@ -61,7 +61,7 @@ import org.springframework.http.codec.xml.Jaxb2XmlEncoder; import org.springframework.util.MimeTypeUtils; import static org.junit.Assert.*; -import static org.springframework.core.ResolvableType.*; +import static org.springframework.core.ResolvableType.forClass; /** * Unit tests for {@link ServerCodecConfigurer}. @@ -86,7 +86,7 @@ public class ServerCodecConfigurerTests { assertStringDecoder(getNextDecoder(readers), true); assertEquals(ProtobufDecoder.class, getNextDecoder(readers).getClass()); assertEquals(FormHttpMessageReader.class, readers.get(this.index.getAndIncrement()).getClass()); - assertEquals(SynchronossPartHttpMessageReader.class, readers.get(this.index.getAndIncrement()).getClass()); + assertEquals(DefaultMultipartMessageReader.class, readers.get(this.index.getAndIncrement()).getClass()); assertEquals(MultipartHttpMessageReader.class, readers.get(this.index.getAndIncrement()).getClass()); assertEquals(Jackson2JsonDecoder.class, getNextDecoder(readers).getClass()); assertEquals(Jackson2SmileDecoder.class, getNextDecoder(readers).getClass());