Browse Source

Add ServerRequest::multipartData in WebMvc.fn

This commit adds the multipartData method to ServerRequest in WebMvc.fn,
returning a MultiValueMap<String, Part>.

Closes gh-24909
pull/24989/head
Arjen Poutsma 5 years ago
parent
commit
54e6103def
  1. 17
      spring-webmvc/src/main/java/org/springframework/web/servlet/function/DefaultServerRequest.java
  2. 12
      spring-webmvc/src/main/java/org/springframework/web/servlet/function/DefaultServerRequestBuilder.java
  3. 11
      spring-webmvc/src/main/java/org/springframework/web/servlet/function/RequestPredicates.java
  4. 12
      spring-webmvc/src/main/java/org/springframework/web/servlet/function/ServerRequest.java
  5. 21
      spring-webmvc/src/test/java/org/springframework/web/servlet/function/DefaultServerRequestTests.java

17
spring-webmvc/src/main/java/org/springframework/web/servlet/function/DefaultServerRequest.java

@ -44,6 +44,7 @@ import javax.servlet.http.Cookie; @@ -44,6 +44,7 @@ import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import javax.servlet.http.Part;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.http.HttpHeaders;
@ -85,6 +86,9 @@ class DefaultServerRequest implements ServerRequest { @@ -85,6 +86,9 @@ class DefaultServerRequest implements ServerRequest {
private final Map<String, Object> attributes;
@Nullable
private MultiValueMap<String, Part> parts;
public DefaultServerRequest(HttpServletRequest servletRequest, List<HttpMessageConverter<?>> messageConverters) {
this.serverHttpRequest = new ServletServerHttpRequest(servletRequest);
@ -228,6 +232,19 @@ class DefaultServerRequest implements ServerRequest { @@ -228,6 +232,19 @@ class DefaultServerRequest implements ServerRequest {
return this.params;
}
@Override
public MultiValueMap<String, Part> multipartData() throws IOException, ServletException {
MultiValueMap<String, Part> result = this.parts;
if (result == null) {
result = servletRequest().getParts().stream()
.collect(Collectors.groupingBy(Part::getName,
LinkedMultiValueMap::new,
Collectors.toList()));
this.parts = result;
}
return result;
}
@Override
@SuppressWarnings("unchecked")
public Map<String, String> pathVariables() {

12
spring-webmvc/src/main/java/org/springframework/web/servlet/function/DefaultServerRequestBuilder.java

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2002-2019 the original author or authors.
* Copyright 2002-2020 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.
@ -30,6 +30,7 @@ import java.util.List; @@ -30,6 +30,7 @@ import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.function.Consumer;
import java.util.stream.Collectors;
import javax.servlet.ReadListener;
import javax.servlet.ServletException;
@ -37,6 +38,7 @@ import javax.servlet.ServletInputStream; @@ -37,6 +38,7 @@ import javax.servlet.ServletInputStream;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import javax.servlet.http.Part;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.http.HttpHeaders;
@ -199,6 +201,14 @@ class DefaultServerRequestBuilder implements ServerRequest.Builder { @@ -199,6 +201,14 @@ class DefaultServerRequestBuilder implements ServerRequest.Builder {
return this.methodName;
}
@Override
public MultiValueMap<String, Part> multipartData() throws IOException, ServletException {
return servletRequest().getParts().stream()
.collect(Collectors.groupingBy(Part::getName,
LinkedMultiValueMap::new,
Collectors.toList()));
}
@Override
public URI uri() {
return this.uri;

11
spring-webmvc/src/main/java/org/springframework/web/servlet/function/RequestPredicates.java

@ -40,6 +40,7 @@ import javax.servlet.ServletException; @@ -40,6 +40,7 @@ import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import javax.servlet.http.Part;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@ -994,6 +995,16 @@ public abstract class RequestPredicates { @@ -994,6 +995,16 @@ public abstract class RequestPredicates {
return this.request.params();
}
@Override
public MultiValueMap<String, Part> multipartData() throws IOException, ServletException {
return this.request.multipartData();
}
@Override
public String pathVariable(String name) {
return this.request.pathVariable(name);
}
@Override
@SuppressWarnings("unchecked")
public Map<String, String> pathVariables() {

12
spring-webmvc/src/main/java/org/springframework/web/servlet/function/ServerRequest.java

@ -33,6 +33,7 @@ import javax.servlet.ServletException; @@ -33,6 +33,7 @@ import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import javax.servlet.http.Part;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.core.io.buffer.DataBuffer;
@ -186,6 +187,17 @@ public interface ServerRequest { @@ -186,6 +187,17 @@ public interface ServerRequest {
*/
MultiValueMap<String, String> params();
/**
* Get the parts of a multipart request, provided the Content-Type is
* {@code "multipart/form-data"}, or an exception otherwise.
* @return the multipart data, mapping from name to part(s)
* @throws IOException if an I/O error occurred during the retrieval
* @throws ServletException if this request is not of type {@code "multipart/form-data"}
* @since 5.3
* @see HttpServletRequest#getParts()
*/
MultiValueMap<String, Part> multipartData() throws IOException, ServletException;
/**
* Get the path variable with the given name, if present.
* @param name the variable name

21
spring-webmvc/src/test/java/org/springframework/web/servlet/function/DefaultServerRequestTests.java

@ -33,6 +33,7 @@ import java.util.Optional; @@ -33,6 +33,7 @@ import java.util.Optional;
import java.util.OptionalLong;
import javax.servlet.http.Cookie;
import javax.servlet.http.Part;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
@ -53,6 +54,7 @@ import org.springframework.web.HttpMediaTypeNotSupportedException; @@ -53,6 +54,7 @@ import org.springframework.web.HttpMediaTypeNotSupportedException;
import org.springframework.web.testfixture.server.MockServerWebExchange;
import org.springframework.web.testfixture.servlet.MockHttpServletRequest;
import org.springframework.web.testfixture.servlet.MockHttpSession;
import org.springframework.web.testfixture.servlet.MockPart;
import static java.nio.charset.StandardCharsets.UTF_8;
import static org.assertj.core.api.Assertions.assertThat;
@ -129,6 +131,25 @@ public class DefaultServerRequestTests { @@ -129,6 +131,25 @@ public class DefaultServerRequestTests {
assertThat(request.param("foo")).isEqualTo(Optional.of("bar"));
}
@Test
public void multipartData() throws Exception {
MockPart formPart = new MockPart("form", "foo".getBytes(UTF_8));
MockPart filePart = new MockPart("file", "foo.txt", "foo".getBytes(UTF_8));
MockHttpServletRequest servletRequest = new MockHttpServletRequest("POST", "/");
servletRequest.addPart(formPart);
servletRequest.addPart(filePart);
DefaultServerRequest request =
new DefaultServerRequest(servletRequest, this.messageConverters);
MultiValueMap<String, Part> result = request.multipartData();
assertThat(result).hasSize(2);
assertThat(result.get("form")).containsExactly(formPart);
assertThat(result.get("file")).containsExactly(filePart);
}
@Test
public void emptyQueryParam() {
MockHttpServletRequest servletRequest = new MockHttpServletRequest("GET", "/");

Loading…
Cancel
Save