CommonsMultipartResolver supports configurable HTTP methods
Closes gh-27161
This commit is contained in:
parent
1ff8da3635
commit
e1c0f3b067
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2018 the original author or authors.
|
* Copyright 2002-2021 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
|
@ -16,7 +16,10 @@
|
||||||
|
|
||||||
package org.springframework.web.multipart.commons;
|
package org.springframework.web.multipart.commons;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
import javax.servlet.ServletContext;
|
import javax.servlet.ServletContext;
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
|
@ -27,7 +30,9 @@ import org.apache.commons.fileupload.FileUpload;
|
||||||
import org.apache.commons.fileupload.FileUploadBase;
|
import org.apache.commons.fileupload.FileUploadBase;
|
||||||
import org.apache.commons.fileupload.FileUploadException;
|
import org.apache.commons.fileupload.FileUploadException;
|
||||||
import org.apache.commons.fileupload.servlet.ServletFileUpload;
|
import org.apache.commons.fileupload.servlet.ServletFileUpload;
|
||||||
|
import org.apache.commons.fileupload.servlet.ServletRequestContext;
|
||||||
|
|
||||||
|
import org.springframework.lang.Nullable;
|
||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
import org.springframework.web.context.ServletContextAware;
|
import org.springframework.web.context.ServletContextAware;
|
||||||
import org.springframework.web.multipart.MaxUploadSizeExceededException;
|
import org.springframework.web.multipart.MaxUploadSizeExceededException;
|
||||||
|
|
@ -41,7 +46,11 @@ import org.springframework.web.util.WebUtils;
|
||||||
/**
|
/**
|
||||||
* Servlet-based {@link MultipartResolver} implementation for
|
* Servlet-based {@link MultipartResolver} implementation for
|
||||||
* <a href="https://commons.apache.org/proper/commons-fileupload">Apache Commons FileUpload</a>
|
* <a href="https://commons.apache.org/proper/commons-fileupload">Apache Commons FileUpload</a>
|
||||||
* 1.2 or above.
|
* 1.2 or above. This resolver variant delegates to a local FileUpload library
|
||||||
|
* within the application, providing maximum portability across Servlet containers.
|
||||||
|
*
|
||||||
|
* <p>Commons FileUpload traditionally parses POST requests with any "multipart/" type.
|
||||||
|
* Supported HTTP methods may be customized through {@link #setSupportedMethods}.
|
||||||
*
|
*
|
||||||
* <p>Provides "maxUploadSize", "maxInMemorySize" and "defaultEncoding" settings as
|
* <p>Provides "maxUploadSize", "maxInMemorySize" and "defaultEncoding" settings as
|
||||||
* bean properties (inherited from {@link CommonsFileUploadSupport}). See corresponding
|
* bean properties (inherited from {@link CommonsFileUploadSupport}). See corresponding
|
||||||
|
|
@ -52,19 +61,29 @@ import org.springframework.web.util.WebUtils;
|
||||||
* Needs to be initialized <i>either</i> by an application context <i>or</i>
|
* Needs to be initialized <i>either</i> by an application context <i>or</i>
|
||||||
* via the constructor that takes a ServletContext (for standalone usage).
|
* via the constructor that takes a ServletContext (for standalone usage).
|
||||||
*
|
*
|
||||||
|
* <p>Note: The common alternative is
|
||||||
|
* {@link org.springframework.web.multipart.support.StandardServletMultipartResolver},
|
||||||
|
* delegating to the Servlet container's own multipart parser, with configuration to
|
||||||
|
* happen at the container level and potentially with container-specific limitations.
|
||||||
|
*
|
||||||
* @author Trevor D. Cook
|
* @author Trevor D. Cook
|
||||||
* @author Juergen Hoeller
|
* @author Juergen Hoeller
|
||||||
* @since 29.09.2003
|
* @since 29.09.2003
|
||||||
* @see #CommonsMultipartResolver(ServletContext)
|
* @see #CommonsMultipartResolver(ServletContext)
|
||||||
* @see #setResolveLazily
|
* @see #setResolveLazily
|
||||||
|
* @see #setSupportedMethods
|
||||||
* @see org.apache.commons.fileupload.servlet.ServletFileUpload
|
* @see org.apache.commons.fileupload.servlet.ServletFileUpload
|
||||||
* @see org.apache.commons.fileupload.disk.DiskFileItemFactory
|
* @see org.apache.commons.fileupload.disk.DiskFileItemFactory
|
||||||
|
* @see org.springframework.web.multipart.support.StandardServletMultipartResolver
|
||||||
*/
|
*/
|
||||||
public class CommonsMultipartResolver extends CommonsFileUploadSupport
|
public class CommonsMultipartResolver extends CommonsFileUploadSupport
|
||||||
implements MultipartResolver, ServletContextAware {
|
implements MultipartResolver, ServletContextAware {
|
||||||
|
|
||||||
private boolean resolveLazily = false;
|
private boolean resolveLazily = false;
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
private Set<String> supportedMethods;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor for use as bean. Determines the servlet container's
|
* Constructor for use as bean. Determines the servlet container's
|
||||||
|
|
@ -101,6 +120,17 @@ public class CommonsMultipartResolver extends CommonsFileUploadSupport
|
||||||
this.resolveLazily = resolveLazily;
|
this.resolveLazily = resolveLazily;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specify supported methods as an array of HTTP method names.
|
||||||
|
* The traditional Commons FileUpload default is "POST" only.
|
||||||
|
* <p>When configured as a Spring property value,
|
||||||
|
* this can be a comma-separated String: e.g. "POST,PUT".
|
||||||
|
* @since 5.3.9
|
||||||
|
*/
|
||||||
|
public void setSupportedMethods(String... supportedMethods) {
|
||||||
|
this.supportedMethods = new HashSet<>(Arrays.asList(supportedMethods));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialize the underlying {@code org.apache.commons.fileupload.servlet.ServletFileUpload}
|
* Initialize the underlying {@code org.apache.commons.fileupload.servlet.ServletFileUpload}
|
||||||
* instance. Can be overridden to use a custom subclass, e.g. for testing purposes.
|
* instance. Can be overridden to use a custom subclass, e.g. for testing purposes.
|
||||||
|
|
@ -122,7 +152,10 @@ public class CommonsMultipartResolver extends CommonsFileUploadSupport
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isMultipart(HttpServletRequest request) {
|
public boolean isMultipart(HttpServletRequest request) {
|
||||||
return ServletFileUpload.isMultipartContent(request);
|
return (this.supportedMethods != null ?
|
||||||
|
this.supportedMethods.contains(request.getMethod()) &&
|
||||||
|
FileUploadBase.isMultipartContent(new ServletRequestContext(request)) :
|
||||||
|
ServletFileUpload.isMultipartContent(request));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2019 the original author or authors.
|
* Copyright 2002-2021 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
|
@ -46,6 +46,7 @@ import org.apache.commons.fileupload.servlet.ServletFileUpload;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
import org.springframework.beans.MutablePropertyValues;
|
import org.springframework.beans.MutablePropertyValues;
|
||||||
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.util.MultiValueMap;
|
import org.springframework.util.MultiValueMap;
|
||||||
import org.springframework.web.bind.ServletRequestDataBinder;
|
import org.springframework.web.bind.ServletRequestDataBinder;
|
||||||
import org.springframework.web.context.WebApplicationContext;
|
import org.springframework.web.context.WebApplicationContext;
|
||||||
|
|
@ -71,6 +72,65 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||||
*/
|
*/
|
||||||
public class CommonsMultipartResolverTests {
|
public class CommonsMultipartResolverTests {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void isMultipartWithDefaultSetting() {
|
||||||
|
CommonsMultipartResolver resolver = new CommonsMultipartResolver();
|
||||||
|
|
||||||
|
MockHttpServletRequest request = new MockHttpServletRequest("POST", "/");
|
||||||
|
assertThat(resolver.isMultipart(request)).isFalse();
|
||||||
|
|
||||||
|
request.setContentType(MediaType.MULTIPART_FORM_DATA_VALUE);
|
||||||
|
assertThat(resolver.isMultipart(request)).isTrue();
|
||||||
|
|
||||||
|
request.setContentType(MediaType.MULTIPART_MIXED_VALUE);
|
||||||
|
assertThat(resolver.isMultipart(request)).isTrue();
|
||||||
|
|
||||||
|
request.setContentType(MediaType.MULTIPART_RELATED_VALUE);
|
||||||
|
assertThat(resolver.isMultipart(request)).isTrue();
|
||||||
|
|
||||||
|
request = new MockHttpServletRequest("PUT", "/");
|
||||||
|
assertThat(resolver.isMultipart(request)).isFalse();
|
||||||
|
|
||||||
|
request.setContentType(MediaType.MULTIPART_FORM_DATA_VALUE);
|
||||||
|
assertThat(resolver.isMultipart(request)).isFalse();
|
||||||
|
|
||||||
|
request.setContentType(MediaType.MULTIPART_MIXED_VALUE);
|
||||||
|
assertThat(resolver.isMultipart(request)).isFalse();
|
||||||
|
|
||||||
|
request.setContentType(MediaType.MULTIPART_RELATED_VALUE);
|
||||||
|
assertThat(resolver.isMultipart(request)).isFalse();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void isMultipartWithSupportedMethods() {
|
||||||
|
CommonsMultipartResolver resolver = new CommonsMultipartResolver();
|
||||||
|
resolver.setSupportedMethods("POST", "PUT");
|
||||||
|
|
||||||
|
MockHttpServletRequest request = new MockHttpServletRequest("POST", "/");
|
||||||
|
assertThat(resolver.isMultipart(request)).isFalse();
|
||||||
|
|
||||||
|
request.setContentType(MediaType.MULTIPART_FORM_DATA_VALUE);
|
||||||
|
assertThat(resolver.isMultipart(request)).isTrue();
|
||||||
|
|
||||||
|
request.setContentType(MediaType.MULTIPART_MIXED_VALUE);
|
||||||
|
assertThat(resolver.isMultipart(request)).isTrue();
|
||||||
|
|
||||||
|
request.setContentType(MediaType.MULTIPART_RELATED_VALUE);
|
||||||
|
assertThat(resolver.isMultipart(request)).isTrue();
|
||||||
|
|
||||||
|
request = new MockHttpServletRequest("PUT", "/");
|
||||||
|
assertThat(resolver.isMultipart(request)).isFalse();
|
||||||
|
|
||||||
|
request.setContentType(MediaType.MULTIPART_FORM_DATA_VALUE);
|
||||||
|
assertThat(resolver.isMultipart(request)).isTrue();
|
||||||
|
|
||||||
|
request.setContentType(MediaType.MULTIPART_MIXED_VALUE);
|
||||||
|
assertThat(resolver.isMultipart(request)).isTrue();
|
||||||
|
|
||||||
|
request.setContentType(MediaType.MULTIPART_RELATED_VALUE);
|
||||||
|
assertThat(resolver.isMultipart(request)).isTrue();
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void withApplicationContext() throws Exception {
|
public void withApplicationContext() throws Exception {
|
||||||
doTestWithApplicationContext(false);
|
doTestWithApplicationContext(false);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue