From a15cc8554ce23437bbdc0b764ca3a6aafad66aea Mon Sep 17 00:00:00 2001 From: Sebastien Deleuze Date: Thu, 13 Oct 2016 18:17:38 +0200 Subject: [PATCH] Add multipart support to HttpServer and WebApplicationInitializer Issue: SPR-14546 --- .../AbstractDispatcherHandlerInitializer.java | 22 ++- ...tServletHttpHandlerAdapterInitializer.java | 16 +- .../reactive/ReactorHttpHandlerAdapter.java | 10 +- .../reactive/RxNettyHttpHandlerAdapter.java | 11 +- .../reactive/ServletHttpHandlerAdapter.java | 18 +- .../reactive/UndertowHttpHandlerAdapter.java | 8 +- .../AbstractHttpHandlerIntegrationTests.java | 7 +- .../reactive/MultipartIntegrationTests.java | 183 ++++++++++++++++++ .../server/reactive/bootstrap/HttpServer.java | 4 + .../reactive/bootstrap/HttpServerSupport.java | 10 + .../reactive/bootstrap/JettyHttpServer.java | 3 +- .../reactive/bootstrap/ReactorHttpServer.java | 2 +- .../reactive/bootstrap/RxNettyHttpServer.java | 2 +- .../reactive/bootstrap/TomcatHttpServer.java | 2 +- .../bootstrap/UndertowHttpServer.java | 2 +- 15 files changed, 280 insertions(+), 20 deletions(-) create mode 100644 spring-web/src/test/java/org/springframework/http/server/reactive/MultipartIntegrationTests.java diff --git a/spring-web-reactive/src/main/java/org/springframework/web/reactive/support/AbstractDispatcherHandlerInitializer.java b/spring-web-reactive/src/main/java/org/springframework/web/reactive/support/AbstractDispatcherHandlerInitializer.java index 657a0be1830b..5f7092cbe23d 100644 --- a/spring-web-reactive/src/main/java/org/springframework/web/reactive/support/AbstractDispatcherHandlerInitializer.java +++ b/spring-web-reactive/src/main/java/org/springframework/web/reactive/support/AbstractDispatcherHandlerInitializer.java @@ -22,12 +22,14 @@ import javax.servlet.ServletException; import javax.servlet.ServletRegistration; +import org.springframework.beans.factory.NoSuchBeanDefinitionException; import org.springframework.context.ApplicationContext; import org.springframework.context.ConfigurableApplicationContext; import org.springframework.http.server.reactive.HttpHandler; import org.springframework.http.server.reactive.ServletHttpHandlerAdapter; import org.springframework.util.Assert; import org.springframework.web.WebApplicationInitializer; +import org.springframework.web.multipart.reactive.MultipartResolver; import org.springframework.web.reactive.DispatcherHandler; import org.springframework.web.server.WebHandler; import org.springframework.web.server.adapter.HttpWebHandlerAdapter; @@ -91,7 +93,9 @@ protected void registerDispatcherHandler(ServletContext servletContext) { Assert.notNull(dispatcherHandler, "createDispatcherHandler() did not return a WebHandler for servlet [" + servletName + "]"); - ServletHttpHandlerAdapter handlerAdapter = createHandlerAdapter(dispatcherHandler); + MultipartResolver multipartResolver = createMultipartResolver(applicationContext); + + ServletHttpHandlerAdapter handlerAdapter = createHandlerAdapter(dispatcherHandler, multipartResolver); Assert.notNull(handlerAdapter, "createHttpHandler() did not return a ServletHttpHandlerAdapter for servlet [" + servletName + "]"); @@ -145,14 +149,26 @@ protected WebHandler createDispatcherHandler(ApplicationContext applicationConte return new DispatcherHandler(applicationContext); } + /** + * Create a {@link MultipartResolver} with the specified {@link ApplicationContext}. + */ + protected MultipartResolver createMultipartResolver(ApplicationContext applicationContext) { + try { + return applicationContext.getBean(MultipartResolver.class); + } + catch (NoSuchBeanDefinitionException nsbe) { + } + return null; + } + /** * Create a {@link ServletHttpHandlerAdapter}. *

Default implementation returns a {@code ServletHttpHandlerAdapter} with the provided * {@code webHandler}. */ - protected ServletHttpHandlerAdapter createHandlerAdapter(WebHandler webHandler) { + protected ServletHttpHandlerAdapter createHandlerAdapter(WebHandler webHandler, MultipartResolver multipartResolver) { HttpHandler httpHandler = new HttpWebHandlerAdapter(webHandler); - return new ServletHttpHandlerAdapter(httpHandler); + return new ServletHttpHandlerAdapter(httpHandler, multipartResolver); } /** diff --git a/spring-web-reactive/src/main/java/org/springframework/web/reactive/support/AbstractServletHttpHandlerAdapterInitializer.java b/spring-web-reactive/src/main/java/org/springframework/web/reactive/support/AbstractServletHttpHandlerAdapterInitializer.java index 2dedbfc1b59f..0d0a8eecb0db 100644 --- a/spring-web-reactive/src/main/java/org/springframework/web/reactive/support/AbstractServletHttpHandlerAdapterInitializer.java +++ b/spring-web-reactive/src/main/java/org/springframework/web/reactive/support/AbstractServletHttpHandlerAdapterInitializer.java @@ -24,6 +24,7 @@ import org.springframework.http.server.reactive.ServletHttpHandlerAdapter; import org.springframework.util.Assert; import org.springframework.web.WebApplicationInitializer; +import org.springframework.web.multipart.reactive.MultipartResolver; /** * Base class for {@link org.springframework.web.WebApplicationInitializer} @@ -59,7 +60,7 @@ public void onStartup(ServletContext servletContext) throws ServletException { * returned from {@link #getServletMappings()}. *

Further customization can be achieved by overriding {@link * #customizeRegistration(ServletRegistration.Dynamic)} or - * {@link #createServlet(HttpHandler)}. + * {@link #createServlet(HttpHandler, MultipartResolver)}. * @param servletContext the context to register the servlet against */ protected void registerHandlerAdapter(ServletContext servletContext) { @@ -70,7 +71,9 @@ protected void registerHandlerAdapter(ServletContext servletContext) { Assert.notNull(httpHandler, "createHttpHandler() did not return a HttpHandler for servlet [" + servletName + "]"); - ServletHttpHandlerAdapter servlet = createServlet(httpHandler); + MultipartResolver multipartResolver = createMultipartResolver(); + + ServletHttpHandlerAdapter servlet = createServlet(httpHandler, multipartResolver); Assert.notNull(servlet, "createHttpHandler() did not return a ServletHttpHandlerAdapter for servlet [" + servletName + "]"); @@ -100,13 +103,18 @@ protected String getServletName() { */ protected abstract HttpHandler createHttpHandler(); + /** + * Create the {@link MultipartResolver}. + */ + protected abstract MultipartResolver createMultipartResolver(); + /** * Create a {@link ServletHttpHandlerAdapter} with the specified . *

Default implementation returns a {@code ServletHttpHandlerAdapter} with the provided * {@code httpHandler}. */ - protected ServletHttpHandlerAdapter createServlet(HttpHandler httpHandler) { - return new ServletHttpHandlerAdapter(httpHandler); + protected ServletHttpHandlerAdapter createServlet(HttpHandler httpHandler, MultipartResolver multipartResolver) { + return new ServletHttpHandlerAdapter(httpHandler, multipartResolver); } /** diff --git a/spring-web/src/main/java/org/springframework/http/server/reactive/ReactorHttpHandlerAdapter.java b/spring-web/src/main/java/org/springframework/http/server/reactive/ReactorHttpHandlerAdapter.java index 31bc30c34c89..510afa723bd3 100644 --- a/spring-web/src/main/java/org/springframework/http/server/reactive/ReactorHttpHandlerAdapter.java +++ b/spring-web/src/main/java/org/springframework/http/server/reactive/ReactorHttpHandlerAdapter.java @@ -26,6 +26,7 @@ import org.springframework.core.io.buffer.NettyDataBufferFactory; import org.springframework.util.Assert; +import org.springframework.web.multipart.reactive.MultipartResolver; /** * Adapt {@link HttpHandler} to the Reactor Netty channel handling function. @@ -39,17 +40,24 @@ public class ReactorHttpHandlerAdapter implements Function apply(HttpChannel channel) { NettyDataBufferFactory bufferFactory = new NettyDataBufferFactory(channel.delegate().alloc()); - ReactorServerHttpRequest adaptedRequest = new ReactorServerHttpRequest(channel, bufferFactory); + ReactorServerHttpRequest adaptedRequest = new ReactorServerHttpRequest(channel, bufferFactory, this.multipartResolver); ReactorServerHttpResponse adaptedResponse = new ReactorServerHttpResponse(channel, bufferFactory); return this.delegate.handle(adaptedRequest, adaptedResponse) diff --git a/spring-web/src/main/java/org/springframework/http/server/reactive/RxNettyHttpHandlerAdapter.java b/spring-web/src/main/java/org/springframework/http/server/reactive/RxNettyHttpHandlerAdapter.java index af66ca4a73a5..2859f628c012 100644 --- a/spring-web/src/main/java/org/springframework/http/server/reactive/RxNettyHttpHandlerAdapter.java +++ b/spring-web/src/main/java/org/springframework/http/server/reactive/RxNettyHttpHandlerAdapter.java @@ -30,6 +30,7 @@ import org.springframework.core.io.buffer.NettyDataBufferFactory; import org.springframework.util.Assert; +import org.springframework.web.multipart.reactive.MultipartResolver; /** * Adapt {@link HttpHandler} to the RxNetty {@link RequestHandler}. @@ -43,17 +44,25 @@ public class RxNettyHttpHandlerAdapter implements RequestHandler handle(HttpServerRequest request, HttpServerResponse response) { NettyDataBufferFactory bufferFactory = new NettyDataBufferFactory(response.unsafeNettyChannel().alloc()); - RxNettyServerHttpRequest adaptedRequest = new RxNettyServerHttpRequest(request, bufferFactory); + RxNettyServerHttpRequest adaptedRequest = new RxNettyServerHttpRequest(request, bufferFactory, this.multipartResolver); RxNettyServerHttpResponse adaptedResponse = new RxNettyServerHttpResponse(response, bufferFactory); Publisher result = this.delegate.handle(adaptedRequest, adaptedResponse) diff --git a/spring-web/src/main/java/org/springframework/http/server/reactive/ServletHttpHandlerAdapter.java b/spring-web/src/main/java/org/springframework/http/server/reactive/ServletHttpHandlerAdapter.java index a4d0153d87ab..22dff2977cfd 100644 --- a/spring-web/src/main/java/org/springframework/http/server/reactive/ServletHttpHandlerAdapter.java +++ b/spring-web/src/main/java/org/springframework/http/server/reactive/ServletHttpHandlerAdapter.java @@ -32,6 +32,7 @@ import org.springframework.core.io.buffer.DataBufferFactory; import org.springframework.core.io.buffer.DefaultDataBufferFactory; import org.springframework.util.Assert; +import org.springframework.web.multipart.reactive.MultipartResolver; /** * Adapt {@link HttpHandler} to an {@link HttpServlet} using Servlet Async @@ -52,6 +53,8 @@ public class ServletHttpHandlerAdapter extends HttpServlet { private final HttpHandler handler; + private final MultipartResolver multipartResolver; + // Servlet is based on blocking I/O, hence the usage of non-direct, heap-based buffers // (i.e. 'false' as constructor argument) private DataBufferFactory dataBufferFactory = new DefaultDataBufferFactory(false); @@ -62,10 +65,21 @@ public class ServletHttpHandlerAdapter extends HttpServlet { /** * Create a new {@code ServletHttpHandlerAdapter} with the given HTTP handler. * @param handler the handler - */ + */ public ServletHttpHandlerAdapter(HttpHandler handler) { + this(handler, null); + } + + /** + * Create a new {@code ServletHttpHandlerAdapter} with the given HTTP handler and multipart + * resolver. + * @param handler the handler + * @param multipartResolver the multipart resolver + */ + public ServletHttpHandlerAdapter(HttpHandler handler, MultipartResolver multipartResolver) { Assert.notNull(handler, "HttpHandler must not be null"); this.handler = handler; + this.multipartResolver = multipartResolver; } @@ -86,7 +100,7 @@ protected void service(HttpServletRequest servletRequest, HttpServletResponse se AsyncContext asyncContext = servletRequest.startAsync(); ServletServerHttpRequest request = new ServletServerHttpRequest( - servletRequest, this.dataBufferFactory, this.bufferSize); + servletRequest, this.dataBufferFactory, this.bufferSize, this.multipartResolver); ServletServerHttpResponse response = new ServletServerHttpResponse( servletResponse, this.dataBufferFactory, this.bufferSize); HandlerResultSubscriber resultSubscriber = new HandlerResultSubscriber(asyncContext); diff --git a/spring-web/src/main/java/org/springframework/http/server/reactive/UndertowHttpHandlerAdapter.java b/spring-web/src/main/java/org/springframework/http/server/reactive/UndertowHttpHandlerAdapter.java index 78b70279d133..dac90a9b103e 100644 --- a/spring-web/src/main/java/org/springframework/http/server/reactive/UndertowHttpHandlerAdapter.java +++ b/spring-web/src/main/java/org/springframework/http/server/reactive/UndertowHttpHandlerAdapter.java @@ -25,6 +25,7 @@ import org.springframework.core.io.buffer.DataBufferFactory; import org.springframework.core.io.buffer.DefaultDataBufferFactory; import org.springframework.util.Assert; +import org.springframework.web.multipart.reactive.MultipartResolver; /** * Adapt {@link HttpHandler} to the Undertow {@link io.undertow.server.HttpHandler}. @@ -41,12 +42,15 @@ public class UndertowHttpHandlerAdapter implements io.undertow.server.HttpHandle private final HttpHandler delegate; + private final MultipartResolver multipartResolver; + private DataBufferFactory dataBufferFactory = new DefaultDataBufferFactory(false); - public UndertowHttpHandlerAdapter(HttpHandler delegate) { + public UndertowHttpHandlerAdapter(HttpHandler delegate, MultipartResolver multipartResolver) { Assert.notNull(delegate, "HttpHandler delegate is required"); this.delegate = delegate; + this.multipartResolver = multipartResolver; } @@ -58,7 +62,7 @@ public void setDataBufferFactory(DataBufferFactory dataBufferFactory) { @Override public void handleRequest(HttpServerExchange exchange) throws Exception { - ServerHttpRequest request = new UndertowServerHttpRequest(exchange, this.dataBufferFactory); + ServerHttpRequest request = new UndertowServerHttpRequest(exchange, this.dataBufferFactory, this.multipartResolver); ServerHttpResponse response = new UndertowServerHttpResponse(exchange, this.dataBufferFactory); this.delegate.handle(request, response).subscribe(new Subscriber() { diff --git a/spring-web/src/test/java/org/springframework/http/server/reactive/AbstractHttpHandlerIntegrationTests.java b/spring-web/src/test/java/org/springframework/http/server/reactive/AbstractHttpHandlerIntegrationTests.java index 1b705ed5f5d3..ca2ba379aae8 100644 --- a/spring-web/src/test/java/org/springframework/http/server/reactive/AbstractHttpHandlerIntegrationTests.java +++ b/spring-web/src/test/java/org/springframework/http/server/reactive/AbstractHttpHandlerIntegrationTests.java @@ -30,7 +30,7 @@ import org.springframework.http.server.reactive.bootstrap.TomcatHttpServer; import org.springframework.http.server.reactive.bootstrap.UndertowHttpServer; import org.springframework.util.SocketUtils; - +import org.springframework.web.multipart.reactive.MultipartResolver; @RunWith(Parameterized.class) public abstract class AbstractHttpHandlerIntegrationTests { @@ -59,12 +59,17 @@ public void setup() throws Exception { this.port = SocketUtils.findAvailableTcpPort(); this.server.setPort(this.port); this.server.setHandler(createHttpHandler()); + this.server.setMultipartResolver(createMultipartResolver()); this.server.afterPropertiesSet(); this.server.start(); } protected abstract HttpHandler createHttpHandler(); + protected MultipartResolver createMultipartResolver() { + return null; + } + @After public void tearDown() throws Exception { this.server.stop(); diff --git a/spring-web/src/test/java/org/springframework/http/server/reactive/MultipartIntegrationTests.java b/spring-web/src/test/java/org/springframework/http/server/reactive/MultipartIntegrationTests.java new file mode 100644 index 000000000000..7c26e9c7e2e2 --- /dev/null +++ b/spring-web/src/test/java/org/springframework/http/server/reactive/MultipartIntegrationTests.java @@ -0,0 +1,183 @@ +/* + * Copyright 2002-2016 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.http.server.reactive; + +import java.io.File; +import java.net.URI; +import java.util.Optional; +import java.util.logging.Level; + +import static org.junit.Assert.*; +import org.junit.Test; +import org.junit.runners.Parameterized; +import reactor.core.publisher.Mono; + +import org.springframework.core.io.ClassPathResource; +import org.springframework.core.io.buffer.DataBuffer; +import org.springframework.http.HttpEntity; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.RequestEntity; +import org.springframework.http.ResponseEntity; +import org.springframework.http.server.reactive.bootstrap.JettyHttpServer; +import org.springframework.http.server.reactive.bootstrap.ReactorHttpServer; +import org.springframework.http.server.reactive.bootstrap.RxNettyHttpServer; +import org.springframework.http.server.reactive.bootstrap.TomcatHttpServer; +import org.springframework.http.server.reactive.bootstrap.UndertowHttpServer; +import org.springframework.util.LinkedMultiValueMap; +import org.springframework.util.MultiValueMap; +import org.springframework.web.client.RestTemplate; +import org.springframework.web.multipart.reactive.MultipartResolver; +import org.springframework.web.multipart.reactive.Part; +import org.springframework.web.multipart.reactive.nio.NioMultipartResolver; + +public class MultipartIntegrationTests extends AbstractHttpHandlerIntegrationTests { + + @Parameterized.Parameters(name = "server [{0}]") + public static Object[][] arguments() { + File base = new File(System.getProperty("java.io.tmpdir")); + return new Object[][] { + {new JettyHttpServer()}, + {new RxNettyHttpServer()}, + {new ReactorHttpServer()}, + {new TomcatHttpServer(base.getAbsolutePath())}, + {new UndertowHttpServer()} + }; + } + + @Override + protected CheckRequestHandler createHttpHandler() { + return new CheckRequestHandler(); + } + + @Override + protected MultipartResolver createMultipartResolver() { + return new NioMultipartResolver(); + } + + @Test + public void getParts() throws Exception { + RestTemplate restTemplate = new RestTemplate(); + RequestEntity> request = RequestEntity + .post(new URI("http://localhost:" + port + "/parts")) + .contentType(MediaType.MULTIPART_FORM_DATA) + .body(generateBody()); + ResponseEntity response = restTemplate.exchange(request, Void.class); + assertEquals(HttpStatus.OK, response.getStatusCode()); + } + + @Test + public void getAllParts() throws Exception { + RestTemplate restTemplate = new RestTemplate(); + RequestEntity> request = RequestEntity + .post(new URI("http://localhost:" + port + "/all-parts")) + .contentType(MediaType.MULTIPART_FORM_DATA) + .body(generateBody()); + ResponseEntity response = restTemplate.exchange(request, Void.class); + assertEquals(HttpStatus.OK, response.getStatusCode()); + } + + private MultiValueMap generateBody() { + HttpHeaders fooHeaders = new HttpHeaders(); + fooHeaders.setContentType(MediaType.TEXT_PLAIN); + ClassPathResource fooResource = new ClassPathResource("org/springframework/web/multipart/reactive/foo.txt"); + HttpEntity fooPart = new HttpEntity<>(fooResource, fooHeaders); + HttpEntity barPart = new HttpEntity<>("bar"); + MultiValueMap parts = new LinkedMultiValueMap<>(); + parts.add("fooPart", fooPart); + parts.add("barPart", barPart); + return parts; + } + + public static class CheckRequestHandler implements HttpHandler { + + @Override + public Mono handle(ServerHttpRequest request, ServerHttpResponse response) { + if (request.getURI().getPath().equals("/parts")) { + return assertGetParts(request); + } + else if (request.getURI().getPath().equals("/all-parts")) { + return assertGetAllParts(request); + } + return Mono.error(new AssertionError()); + } + + private Mono assertGetParts(ServerHttpRequest request) { + return request.getParts() + .log("reactor", Level.SEVERE) + .doOnNext(part -> { + if (part.getName().equals("fooPart")) { + assertEquals("fooPart", part.getName()); + Optional filename = part.getFilename(); + assertTrue(filename.isPresent()); + assertEquals("foo.txt", filename.get()); + DataBuffer buffer = part + .getContent() + .reduce((s1, s2) -> s1.write(s2)) + .block(); + assertEquals(12, buffer.readableByteCount()); + byte[] byteContent = new byte[12]; + buffer.read(byteContent); + assertEquals("Lorem\nIpsum\n", new String(byteContent)); + } + else if (part.getName().equals("barPart")) { + assertEquals("barPart", part.getName()); + Optional filename = part.getFilename(); + assertFalse(filename.isPresent()); + assertEquals("bar", part.getValue().block()); + } + else { + fail(); + } + }) + .then(); + } + + private Mono assertGetAllParts(ServerHttpRequest request) { + return request + .getAllParts() + .doOnNext(parts -> { + assertEquals(2, parts.size()); + assertTrue(parts.containsKey("fooPart")); + + Part part = parts.getFirst("fooPart"); + assertEquals("fooPart", part.getName()); + Optional filename = part.getFilename(); + assertTrue(filename.isPresent()); + assertEquals("foo.txt", filename.get()); + DataBuffer buffer = part + .getContent() + .reduce((s1, s2) -> s1.write(s2)) + .block(); + assertEquals(12, buffer.readableByteCount()); + byte[] byteContent = new byte[12]; + buffer.read(byteContent); + assertEquals("Lorem\nIpsum\n", new String(byteContent)); + + assertTrue(parts.containsKey("barPart")); + part = parts.getFirst("barPart"); + assertEquals("barPart", part.getName()); + filename = part.getFilename(); + assertFalse(filename.isPresent()); + assertEquals("bar", part.getValue().block()); + }) + .then(); + } + } + +} diff --git a/spring-web/src/test/java/org/springframework/http/server/reactive/bootstrap/HttpServer.java b/spring-web/src/test/java/org/springframework/http/server/reactive/bootstrap/HttpServer.java index 8bc8ae12d4e3..6b75b41c10ce 100644 --- a/spring-web/src/test/java/org/springframework/http/server/reactive/bootstrap/HttpServer.java +++ b/spring-web/src/test/java/org/springframework/http/server/reactive/bootstrap/HttpServer.java @@ -20,9 +20,11 @@ import org.springframework.beans.factory.InitializingBean; import org.springframework.context.Lifecycle; import org.springframework.http.server.reactive.HttpHandler; +import org.springframework.web.multipart.reactive.MultipartResolver; /** * @author Rossen Stoyanchev + * @author Sebastien Deleuze */ public interface HttpServer extends InitializingBean, Lifecycle { @@ -32,4 +34,6 @@ public interface HttpServer extends InitializingBean, Lifecycle { void setHandler(HttpHandler handler); + void setMultipartResolver(MultipartResolver multipartResolver); + } diff --git a/spring-web/src/test/java/org/springframework/http/server/reactive/bootstrap/HttpServerSupport.java b/spring-web/src/test/java/org/springframework/http/server/reactive/bootstrap/HttpServerSupport.java index 4c22291b91ed..584edf1b467c 100644 --- a/spring-web/src/test/java/org/springframework/http/server/reactive/bootstrap/HttpServerSupport.java +++ b/spring-web/src/test/java/org/springframework/http/server/reactive/bootstrap/HttpServerSupport.java @@ -18,6 +18,7 @@ import org.springframework.http.server.reactive.HttpHandler; import org.springframework.util.SocketUtils; +import org.springframework.web.multipart.reactive.MultipartResolver; /** * @author Rossen Stoyanchev @@ -30,6 +31,8 @@ public class HttpServerSupport { private HttpHandler httpHandler; + private MultipartResolver multipartResolver; + public void setHost(String host) { this.host = host; } @@ -57,4 +60,11 @@ public HttpHandler getHttpHandler() { return this.httpHandler; } + public MultipartResolver getMultipartResolver() { + return multipartResolver; + } + + public void setMultipartResolver(MultipartResolver multipartResolver) { + this.multipartResolver = multipartResolver; + } } diff --git a/spring-web/src/test/java/org/springframework/http/server/reactive/bootstrap/JettyHttpServer.java b/spring-web/src/test/java/org/springframework/http/server/reactive/bootstrap/JettyHttpServer.java index ae4139253858..0b7739fd059f 100644 --- a/spring-web/src/test/java/org/springframework/http/server/reactive/bootstrap/JettyHttpServer.java +++ b/spring-web/src/test/java/org/springframework/http/server/reactive/bootstrap/JettyHttpServer.java @@ -23,7 +23,6 @@ import org.springframework.beans.factory.InitializingBean; import org.springframework.http.server.reactive.ServletHttpHandlerAdapter; -import org.springframework.util.Assert; /** * @author Rossen Stoyanchev @@ -39,7 +38,7 @@ public class JettyHttpServer extends HttpServerSupport implements HttpServer, In public void afterPropertiesSet() throws Exception { this.jettyServer = new Server(); - ServletHttpHandlerAdapter servlet = new ServletHttpHandlerAdapter(getHttpHandler()); + ServletHttpHandlerAdapter servlet = new ServletHttpHandlerAdapter(getHttpHandler(), getMultipartResolver()); ServletHolder servletHolder = new ServletHolder(servlet); ServletContextHandler contextHandler = new ServletContextHandler(this.jettyServer, "", false, false); diff --git a/spring-web/src/test/java/org/springframework/http/server/reactive/bootstrap/ReactorHttpServer.java b/spring-web/src/test/java/org/springframework/http/server/reactive/bootstrap/ReactorHttpServer.java index 2d5ede795099..84ceee1a34a7 100644 --- a/spring-web/src/test/java/org/springframework/http/server/reactive/bootstrap/ReactorHttpServer.java +++ b/spring-web/src/test/java/org/springframework/http/server/reactive/bootstrap/ReactorHttpServer.java @@ -37,7 +37,7 @@ public class ReactorHttpServer extends HttpServerSupport implements HttpServer, public void afterPropertiesSet() throws Exception { Assert.notNull(getHttpHandler()); - this.reactorHandler = new ReactorHttpHandlerAdapter(getHttpHandler()); + this.reactorHandler = new ReactorHttpHandlerAdapter(getHttpHandler(), getMultipartResolver()); this.reactorServer = reactor.ipc.netty.http.HttpServer.create(getHost(), getPort()); } diff --git a/spring-web/src/test/java/org/springframework/http/server/reactive/bootstrap/RxNettyHttpServer.java b/spring-web/src/test/java/org/springframework/http/server/reactive/bootstrap/RxNettyHttpServer.java index 051ba64e6665..0952d6c8fa28 100644 --- a/spring-web/src/test/java/org/springframework/http/server/reactive/bootstrap/RxNettyHttpServer.java +++ b/spring-web/src/test/java/org/springframework/http/server/reactive/bootstrap/RxNettyHttpServer.java @@ -38,7 +38,7 @@ public class RxNettyHttpServer extends HttpServerSupport implements HttpServer { @Override public void afterPropertiesSet() throws Exception { Assert.notNull(getHttpHandler()); - this.rxNettyHandler = new RxNettyHttpHandlerAdapter(getHttpHandler()); + this.rxNettyHandler = new RxNettyHttpHandlerAdapter(getHttpHandler(), getMultipartResolver()); this.rxNettyServer = io.reactivex.netty.protocol.http.server.HttpServer .newServer(new InetSocketAddress(getHost(), getPort())); diff --git a/spring-web/src/test/java/org/springframework/http/server/reactive/bootstrap/TomcatHttpServer.java b/spring-web/src/test/java/org/springframework/http/server/reactive/bootstrap/TomcatHttpServer.java index 44c7b35fdef4..4f9f2b2c0e96 100644 --- a/spring-web/src/test/java/org/springframework/http/server/reactive/bootstrap/TomcatHttpServer.java +++ b/spring-web/src/test/java/org/springframework/http/server/reactive/bootstrap/TomcatHttpServer.java @@ -54,7 +54,7 @@ public void afterPropertiesSet() throws Exception { this.tomcatServer.setHostname(getHost()); this.tomcatServer.setPort(getPort()); - ServletHttpHandlerAdapter servlet = new ServletHttpHandlerAdapter(getHttpHandler()); + ServletHttpHandlerAdapter servlet = new ServletHttpHandlerAdapter(getHttpHandler(), getMultipartResolver()); File base = new File(System.getProperty("java.io.tmpdir")); Context rootContext = tomcatServer.addContext("", base.getAbsolutePath()); diff --git a/spring-web/src/test/java/org/springframework/http/server/reactive/bootstrap/UndertowHttpServer.java b/spring-web/src/test/java/org/springframework/http/server/reactive/bootstrap/UndertowHttpServer.java index ee3ab6dafa48..f3028b80af77 100644 --- a/spring-web/src/test/java/org/springframework/http/server/reactive/bootstrap/UndertowHttpServer.java +++ b/spring-web/src/test/java/org/springframework/http/server/reactive/bootstrap/UndertowHttpServer.java @@ -35,7 +35,7 @@ public class UndertowHttpServer extends HttpServerSupport implements HttpServer @Override public void afterPropertiesSet() throws Exception { Assert.notNull(getHttpHandler()); - HttpHandler handler = new UndertowHttpHandlerAdapter(getHttpHandler()); + HttpHandler handler = new UndertowHttpHandlerAdapter(getHttpHandler(), getMultipartResolver()); this.server = Undertow.builder().addHttpListener(getPort(), getHost()) .setHandler(handler).build(); }