revised Servlet 3.0 based StandardServletMultipartResolver for correct param/file distinction; added multipart content type and headers access to MultipartRequest (dropping the previous header access solution on MultipartFile); MultipartFilter uses a Servlet 3.0 based StandardServletMultipartResolver by default
git-svn-id: https://src.springframework.org/svn/spring-framework/trunk@4736 50f2f4bb-b051-0410-bef5-90022cba6387
This commit is contained in:
parent
c76301e1f2
commit
d3a7fdadb0
|
|
@ -41,8 +41,6 @@ import org.springframework.web.multipart.MultipartFile;
|
||||||
*/
|
*/
|
||||||
public class MockMultipartFile implements MultipartFile {
|
public class MockMultipartFile implements MultipartFile {
|
||||||
|
|
||||||
private static final String CONTENT_TYPE = "Content-Type";
|
|
||||||
|
|
||||||
private final String name;
|
private final String name;
|
||||||
|
|
||||||
private String originalFilename;
|
private String originalFilename;
|
||||||
|
|
@ -133,26 +131,4 @@ public class MockMultipartFile implements MultipartFile {
|
||||||
FileCopyUtils.copy(this.content, dest);
|
FileCopyUtils.copy(this.content, dest);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getHeader(String name) {
|
|
||||||
if (CONTENT_TYPE.equalsIgnoreCase(name)) {
|
|
||||||
return this.contentType;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public String[] getHeaders(String name) {
|
|
||||||
if (CONTENT_TYPE.equalsIgnoreCase(name)) {
|
|
||||||
return new String[] {this.contentType};
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public Iterator<String> getHeaderNames() {
|
|
||||||
return Collections.singleton(CONTENT_TYPE).iterator();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2010 the original author or authors.
|
* Copyright 2002-2011 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.
|
||||||
|
|
@ -17,10 +17,13 @@
|
||||||
package org.springframework.mock.web;
|
package org.springframework.mock.web;
|
||||||
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
import java.util.Enumeration;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.springframework.http.HttpHeaders;
|
||||||
|
import org.springframework.http.HttpMethod;
|
||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
import org.springframework.util.LinkedMultiValueMap;
|
import org.springframework.util.LinkedMultiValueMap;
|
||||||
import org.springframework.util.MultiValueMap;
|
import org.springframework.util.MultiValueMap;
|
||||||
|
|
@ -89,4 +92,40 @@ public class MockMultipartHttpServletRequest extends MockHttpServletRequest impl
|
||||||
return new LinkedMultiValueMap<String, MultipartFile>(this.multipartFiles);
|
return new LinkedMultiValueMap<String, MultipartFile>(this.multipartFiles);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getMultipartContentType(String paramOrFileName) {
|
||||||
|
MultipartFile file = getFile(paramOrFileName);
|
||||||
|
if (file != null) {
|
||||||
|
return file.getContentType();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public HttpMethod getRequestMethod() {
|
||||||
|
return HttpMethod.valueOf(getMethod());
|
||||||
|
}
|
||||||
|
|
||||||
|
public HttpHeaders getRequestHeaders() {
|
||||||
|
HttpHeaders headers = new HttpHeaders();
|
||||||
|
Enumeration<String> headerNames = getHeaderNames();
|
||||||
|
while (headerNames.hasMoreElements()) {
|
||||||
|
String headerName = headerNames.nextElement();
|
||||||
|
headers.put(headerName, Collections.list(getHeaders(headerName)));
|
||||||
|
}
|
||||||
|
return headers;
|
||||||
|
}
|
||||||
|
|
||||||
|
public HttpHeaders getMultipartHeaders(String paramOrFileName) {
|
||||||
|
String contentType = getMultipartContentType(paramOrFileName);
|
||||||
|
if (contentType != null) {
|
||||||
|
HttpHeaders headers = new HttpHeaders();
|
||||||
|
headers.add("Content-Type", contentType);
|
||||||
|
return headers;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2010 the original author or authors.
|
* Copyright 2002-2011 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.
|
||||||
|
|
@ -82,4 +82,14 @@ public class MockMultipartActionRequest extends MockActionRequest implements Mul
|
||||||
return new LinkedMultiValueMap<String, MultipartFile>(this.multipartFiles);
|
return new LinkedMultiValueMap<String, MultipartFile>(this.multipartFiles);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getMultipartContentType(String paramOrFileName) {
|
||||||
|
MultipartFile file = getFile(paramOrFileName);
|
||||||
|
if (file != null) {
|
||||||
|
return file.getContentType();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2010 the original author or authors.
|
* Copyright 2002-2011 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.
|
||||||
|
|
@ -126,13 +126,14 @@ public class CommonsPortletMultipartResolver extends CommonsFileUploadSupport
|
||||||
MultipartParsingResult parsingResult = parseRequest(request);
|
MultipartParsingResult parsingResult = parseRequest(request);
|
||||||
setMultipartFiles(parsingResult.getMultipartFiles());
|
setMultipartFiles(parsingResult.getMultipartFiles());
|
||||||
setMultipartParameters(parsingResult.getMultipartParameters());
|
setMultipartParameters(parsingResult.getMultipartParameters());
|
||||||
|
setMultipartParameterContentTypes(parsingResult.getMultipartParameterContentTypes());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
MultipartParsingResult parsingResult = parseRequest(request);
|
MultipartParsingResult parsingResult = parseRequest(request);
|
||||||
return new DefaultMultipartActionRequest(
|
return new DefaultMultipartActionRequest(request, parsingResult.getMultipartFiles(),
|
||||||
request, parsingResult.getMultipartFiles(), parsingResult.getMultipartParameters());
|
parsingResult.getMultipartParameters(), parsingResult.getMultipartParameterContentTypes());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2008 the original author or authors.
|
* Copyright 2002-2011 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.
|
||||||
|
|
@ -21,15 +21,15 @@ import java.util.Enumeration;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.List;
|
|
||||||
import javax.portlet.ActionRequest;
|
import javax.portlet.ActionRequest;
|
||||||
import javax.portlet.filter.ActionRequestWrapper;
|
import javax.portlet.filter.ActionRequestWrapper;
|
||||||
|
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
|
||||||
import org.springframework.util.MultiValueMap;
|
|
||||||
import org.springframework.util.LinkedMultiValueMap;
|
import org.springframework.util.LinkedMultiValueMap;
|
||||||
|
import org.springframework.util.MultiValueMap;
|
||||||
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Default implementation of the {@link MultipartActionRequest} interface.
|
* Default implementation of the {@link MultipartActionRequest} interface.
|
||||||
|
|
@ -46,6 +46,8 @@ public class DefaultMultipartActionRequest extends ActionRequestWrapper implemen
|
||||||
|
|
||||||
private Map<String, String[]> multipartParameters;
|
private Map<String, String[]> multipartParameters;
|
||||||
|
|
||||||
|
private Map<String, String> multipartParameterContentTypes;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Wrap the given Portlet ActionRequest in a MultipartActionRequest.
|
* Wrap the given Portlet ActionRequest in a MultipartActionRequest.
|
||||||
|
|
@ -54,12 +56,13 @@ public class DefaultMultipartActionRequest extends ActionRequestWrapper implemen
|
||||||
* @param mpParams a map of the parameters to expose,
|
* @param mpParams a map of the parameters to expose,
|
||||||
* with Strings as keys and String arrays as values
|
* with Strings as keys and String arrays as values
|
||||||
*/
|
*/
|
||||||
public DefaultMultipartActionRequest(
|
public DefaultMultipartActionRequest(ActionRequest request, MultiValueMap<String, MultipartFile> mpFiles,
|
||||||
ActionRequest request, MultiValueMap<String, MultipartFile> mpFiles, Map<String, String[]> mpParams) {
|
Map<String, String[]> mpParams, Map<String, String> mpParamContentTypes) {
|
||||||
|
|
||||||
super(request);
|
super(request);
|
||||||
setMultipartFiles(mpFiles);
|
setMultipartFiles(mpFiles);
|
||||||
setMultipartParameters(mpParams);
|
setMultipartParameters(mpParams);
|
||||||
|
setMultipartParameterContentTypes(mpParamContentTypes);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -136,6 +139,16 @@ public class DefaultMultipartActionRequest extends ActionRequestWrapper implemen
|
||||||
return paramMap;
|
return paramMap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getMultipartContentType(String paramOrFileName) {
|
||||||
|
MultipartFile file = getFile(paramOrFileName);
|
||||||
|
if (file != null) {
|
||||||
|
return file.getContentType();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return getMultipartParameterContentTypes().get(paramOrFileName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set a Map with parameter names as keys and list of MultipartFile objects as values.
|
* Set a Map with parameter names as keys and list of MultipartFile objects as values.
|
||||||
|
|
@ -178,6 +191,27 @@ public class DefaultMultipartActionRequest extends ActionRequestWrapper implemen
|
||||||
return this.multipartParameters;
|
return this.multipartParameters;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set a Map with parameter names as keys and content type Strings as values.
|
||||||
|
* To be invoked by subclasses on initialization.
|
||||||
|
*/
|
||||||
|
protected final void setMultipartParameterContentTypes(Map<String, String> multipartParameterContentTypes) {
|
||||||
|
this.multipartParameterContentTypes = multipartParameterContentTypes;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Obtain the multipart parameter content type Map for retrieval,
|
||||||
|
* lazily initializing it if necessary.
|
||||||
|
* @see #initializeMultipart()
|
||||||
|
*/
|
||||||
|
protected Map<String, String> getMultipartParameterContentTypes() {
|
||||||
|
if (this.multipartParameterContentTypes == null) {
|
||||||
|
initializeMultipart();
|
||||||
|
}
|
||||||
|
return this.multipartParameterContentTypes;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Lazily initialize the multipart request, if possible.
|
* Lazily initialize the multipart request, if possible.
|
||||||
* Only called if not already eagerly initialized.
|
* Only called if not already eagerly initialized.
|
||||||
|
|
|
||||||
|
|
@ -41,8 +41,6 @@ import org.springframework.web.multipart.MultipartFile;
|
||||||
*/
|
*/
|
||||||
public class MockMultipartFile implements MultipartFile {
|
public class MockMultipartFile implements MultipartFile {
|
||||||
|
|
||||||
private static final String CONTENT_TYPE = "Content-Type";
|
|
||||||
|
|
||||||
private final String name;
|
private final String name;
|
||||||
|
|
||||||
private String originalFilename;
|
private String originalFilename;
|
||||||
|
|
@ -133,26 +131,4 @@ public class MockMultipartFile implements MultipartFile {
|
||||||
FileCopyUtils.copy(this.content, dest);
|
FileCopyUtils.copy(this.content, dest);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getHeader(String name) {
|
|
||||||
if (CONTENT_TYPE.equalsIgnoreCase(name)) {
|
|
||||||
return this.contentType;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public String[] getHeaders(String name) {
|
|
||||||
if (CONTENT_TYPE.equalsIgnoreCase(name)) {
|
|
||||||
return new String[] {this.contentType};
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public Iterator<String> getHeaderNames() {
|
|
||||||
return Collections.singleton(CONTENT_TYPE).iterator();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2010 the original author or authors.
|
* Copyright 2002-2011 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.
|
||||||
|
|
@ -82,4 +82,14 @@ public class MockMultipartActionRequest extends MockActionRequest implements Mul
|
||||||
return new LinkedMultiValueMap<String, MultipartFile>(this.multipartFiles);
|
return new LinkedMultiValueMap<String, MultipartFile>(this.multipartFiles);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getMultipartContentType(String paramOrFileName) {
|
||||||
|
MultipartFile file = getFile(paramOrFileName);
|
||||||
|
if (file != null) {
|
||||||
|
return file.getContentType();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2010 the original author or authors.
|
* Copyright 2002-2011 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.
|
||||||
|
|
@ -18,6 +18,7 @@ package org.springframework.web.portlet;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
|
@ -481,7 +482,7 @@ public class ComplexPortletApplicationContext extends StaticPortletApplicationCo
|
||||||
files.set("someFile", new MockMultipartFile("someFile", "someContent".getBytes()));
|
files.set("someFile", new MockMultipartFile("someFile", "someContent".getBytes()));
|
||||||
Map<String, String[]> params = new HashMap<String, String[]>();
|
Map<String, String[]> params = new HashMap<String, String[]>();
|
||||||
params.put("someParam", new String[] {"someParam"});
|
params.put("someParam", new String[] {"someParam"});
|
||||||
return new DefaultMultipartActionRequest(request, files, params);
|
return new DefaultMultipartActionRequest(request, files, params, Collections.<String, String>emptyMap());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void cleanupMultipart(MultipartActionRequest request) {
|
public void cleanupMultipart(MultipartActionRequest request) {
|
||||||
|
|
|
||||||
|
|
@ -39,7 +39,7 @@ import org.springframework.web.multipart.MultipartFile;
|
||||||
import org.springframework.web.multipart.MultipartHttpServletRequest;
|
import org.springframework.web.multipart.MultipartHttpServletRequest;
|
||||||
import org.springframework.web.multipart.MultipartRequest;
|
import org.springframework.web.multipart.MultipartRequest;
|
||||||
import org.springframework.web.multipart.MultipartResolver;
|
import org.springframework.web.multipart.MultipartResolver;
|
||||||
import org.springframework.web.multipart.RequestPartServletServerHttpRequest;
|
import org.springframework.web.multipart.support.RequestPartServletServerHttpRequest;
|
||||||
import org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver;
|
import org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver;
|
||||||
import org.springframework.web.util.WebUtils;
|
import org.springframework.web.util.WebUtils;
|
||||||
|
|
||||||
|
|
@ -123,9 +123,8 @@ public class RequestPartMethodArgumentResolver extends AbstractMessageConverterM
|
||||||
arg = servletRequest.getPart(partName);
|
arg = servletRequest.getPart(partName);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
HttpInputMessage inputMessage = new RequestPartServletServerHttpRequest(multipartRequest, partName);
|
HttpInputMessage inputMessage = new RequestPartServletServerHttpRequest(servletRequest, partName);
|
||||||
arg = readWithMessageConverters(inputMessage, parameter, parameter.getParameterType());
|
arg = readWithMessageConverters(inputMessage, parameter, parameter.getParameterType());
|
||||||
|
|
||||||
if (isValidationApplicable(arg, parameter)) {
|
if (isValidationApplicable(arg, parameter)) {
|
||||||
WebDataBinder binder = binderFactory.createBinder(request, arg, partName);
|
WebDataBinder binder = binderFactory.createBinder(request, arg, partName);
|
||||||
binder.validate();
|
binder.validate();
|
||||||
|
|
|
||||||
|
|
@ -41,8 +41,6 @@ import org.springframework.web.multipart.MultipartFile;
|
||||||
*/
|
*/
|
||||||
public class MockMultipartFile implements MultipartFile {
|
public class MockMultipartFile implements MultipartFile {
|
||||||
|
|
||||||
private static final String CONTENT_TYPE = "Content-Type";
|
|
||||||
|
|
||||||
private final String name;
|
private final String name;
|
||||||
|
|
||||||
private String originalFilename;
|
private String originalFilename;
|
||||||
|
|
@ -133,26 +131,4 @@ public class MockMultipartFile implements MultipartFile {
|
||||||
FileCopyUtils.copy(this.content, dest);
|
FileCopyUtils.copy(this.content, dest);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getHeader(String name) {
|
|
||||||
if (CONTENT_TYPE.equalsIgnoreCase(name)) {
|
|
||||||
return this.contentType;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public String[] getHeaders(String name) {
|
|
||||||
if (CONTENT_TYPE.equalsIgnoreCase(name)) {
|
|
||||||
return new String[] {this.contentType};
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public Iterator<String> getHeaderNames() {
|
|
||||||
return Collections.singleton(CONTENT_TYPE).iterator();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2010 the original author or authors.
|
* Copyright 2002-2011 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.
|
||||||
|
|
@ -17,10 +17,13 @@
|
||||||
package org.springframework.mock.web;
|
package org.springframework.mock.web;
|
||||||
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
import java.util.Enumeration;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.springframework.http.HttpHeaders;
|
||||||
|
import org.springframework.http.HttpMethod;
|
||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
import org.springframework.util.LinkedMultiValueMap;
|
import org.springframework.util.LinkedMultiValueMap;
|
||||||
import org.springframework.util.MultiValueMap;
|
import org.springframework.util.MultiValueMap;
|
||||||
|
|
@ -89,4 +92,40 @@ public class MockMultipartHttpServletRequest extends MockHttpServletRequest impl
|
||||||
return new LinkedMultiValueMap<String, MultipartFile>(this.multipartFiles);
|
return new LinkedMultiValueMap<String, MultipartFile>(this.multipartFiles);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getMultipartContentType(String paramOrFileName) {
|
||||||
|
MultipartFile file = getFile(paramOrFileName);
|
||||||
|
if (file != null) {
|
||||||
|
return file.getContentType();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public HttpMethod getRequestMethod() {
|
||||||
|
return HttpMethod.valueOf(getMethod());
|
||||||
|
}
|
||||||
|
|
||||||
|
public HttpHeaders getRequestHeaders() {
|
||||||
|
HttpHeaders headers = new HttpHeaders();
|
||||||
|
Enumeration<String> headerNames = getHeaderNames();
|
||||||
|
while (headerNames.hasMoreElements()) {
|
||||||
|
String headerName = headerNames.nextElement();
|
||||||
|
headers.put(headerName, Collections.list(getHeaders(headerName)));
|
||||||
|
}
|
||||||
|
return headers;
|
||||||
|
}
|
||||||
|
|
||||||
|
public HttpHeaders getMultipartHeaders(String paramOrFileName) {
|
||||||
|
String contentType = getMultipartContentType(paramOrFileName);
|
||||||
|
if (contentType != null) {
|
||||||
|
HttpHeaders headers = new HttpHeaders();
|
||||||
|
headers.add("Content-Type", contentType);
|
||||||
|
return headers;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2007 the original author or authors.
|
* Copyright 2002-2011 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.
|
||||||
|
|
@ -20,7 +20,6 @@ import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
|
||||||
import javax.servlet.Servlet;
|
import javax.servlet.Servlet;
|
||||||
import javax.servlet.ServletConfig;
|
import javax.servlet.ServletConfig;
|
||||||
import javax.servlet.ServletException;
|
import javax.servlet.ServletException;
|
||||||
|
|
@ -49,7 +48,7 @@ import org.springframework.web.multipart.MaxUploadSizeExceededException;
|
||||||
import org.springframework.web.multipart.MultipartException;
|
import org.springframework.web.multipart.MultipartException;
|
||||||
import org.springframework.web.multipart.MultipartHttpServletRequest;
|
import org.springframework.web.multipart.MultipartHttpServletRequest;
|
||||||
import org.springframework.web.multipart.MultipartResolver;
|
import org.springframework.web.multipart.MultipartResolver;
|
||||||
import org.springframework.web.multipart.support.AbstractMultipartHttpServletRequest;
|
import org.springframework.web.multipart.support.DefaultMultipartHttpServletRequest;
|
||||||
import org.springframework.web.servlet.handler.SimpleMappingExceptionResolver;
|
import org.springframework.web.servlet.handler.SimpleMappingExceptionResolver;
|
||||||
import org.springframework.web.servlet.handler.SimpleServletHandlerAdapter;
|
import org.springframework.web.servlet.handler.SimpleServletHandlerAdapter;
|
||||||
import org.springframework.web.servlet.handler.SimpleServletPostProcessor;
|
import org.springframework.web.servlet.handler.SimpleServletPostProcessor;
|
||||||
|
|
@ -434,8 +433,7 @@ public class ComplexWebApplicationContext extends StaticWebApplicationContext {
|
||||||
throw new IllegalStateException("Already resolved");
|
throw new IllegalStateException("Already resolved");
|
||||||
}
|
}
|
||||||
request.setAttribute("resolved", Boolean.TRUE);
|
request.setAttribute("resolved", Boolean.TRUE);
|
||||||
return new AbstractMultipartHttpServletRequest(request) {
|
return new DefaultMultipartHttpServletRequest(request);
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void cleanupMultipart(MultipartHttpServletRequest request) {
|
public void cleanupMultipart(MultipartHttpServletRequest request) {
|
||||||
|
|
|
||||||
|
|
@ -60,7 +60,7 @@ import org.springframework.web.context.request.NativeWebRequest;
|
||||||
import org.springframework.web.context.request.ServletWebRequest;
|
import org.springframework.web.context.request.ServletWebRequest;
|
||||||
import org.springframework.web.method.support.ModelAndViewContainer;
|
import org.springframework.web.method.support.ModelAndViewContainer;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
import org.springframework.web.multipart.RequestPartServletServerHttpRequest;
|
import org.springframework.web.multipart.support.RequestPartServletServerHttpRequest;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test fixture with {@link RequestPartMethodArgumentResolver} and mock {@link HttpMessageConverter}.
|
* Test fixture with {@link RequestPartMethodArgumentResolver} and mock {@link HttpMessageConverter}.
|
||||||
|
|
|
||||||
|
|
@ -44,13 +44,14 @@ import org.springframework.util.Assert;
|
||||||
*/
|
*/
|
||||||
public class ServletServerHttpRequest implements ServerHttpRequest {
|
public class ServletServerHttpRequest implements ServerHttpRequest {
|
||||||
|
|
||||||
private static final String FORM_CONTENT_TYPE = "application/x-www-form-urlencoded";
|
protected static final String FORM_CONTENT_TYPE = "application/x-www-form-urlencoded";
|
||||||
|
|
||||||
private static final String POST_METHOD = "POST";
|
protected static final String FORM_CHARSET = "UTF-8";
|
||||||
|
|
||||||
private static final String PUT_METHOD = "PUT";
|
private static final String METHOD_POST = "POST";
|
||||||
|
|
||||||
|
private static final String METHOD_PUT = "PUT";
|
||||||
|
|
||||||
private static final String FORM_CHARSET = "UTF-8";
|
|
||||||
|
|
||||||
private final HttpServletRequest servletRequest;
|
private final HttpServletRequest servletRequest;
|
||||||
|
|
||||||
|
|
@ -115,7 +116,7 @@ public class ServletServerHttpRequest implements ServerHttpRequest {
|
||||||
|
|
||||||
private boolean isFormSubmittal(HttpServletRequest request) {
|
private boolean isFormSubmittal(HttpServletRequest request) {
|
||||||
return FORM_CONTENT_TYPE.equals(request.getContentType()) &&
|
return FORM_CONTENT_TYPE.equals(request.getContentType()) &&
|
||||||
(POST_METHOD.equalsIgnoreCase(request.getMethod()) || PUT_METHOD.equalsIgnoreCase(request.getMethod()));
|
(METHOD_POST.equalsIgnoreCase(request.getMethod()) || METHOD_PUT.equalsIgnoreCase(request.getMethod()));
|
||||||
}
|
}
|
||||||
|
|
||||||
private InputStream getFormBody(HttpServletRequest request) throws IOException {
|
private InputStream getFormBody(HttpServletRequest request) throws IOException {
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,6 @@ package org.springframework.web.multipart;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.util.Iterator;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A representation of an uploaded file received in a multipart request.
|
* A representation of an uploaded file received in a multipart request.
|
||||||
|
|
@ -102,28 +101,4 @@ public interface MultipartFile {
|
||||||
*/
|
*/
|
||||||
void transferTo(File dest) throws IOException, IllegalStateException;
|
void transferTo(File dest) throws IOException, IllegalStateException;
|
||||||
|
|
||||||
/**
|
|
||||||
* Return the first value associated with the given header name, if any.
|
|
||||||
* @param name the name of the header
|
|
||||||
* @return the first header value, or <code>null</code> if no such header was found
|
|
||||||
* @since 3.1
|
|
||||||
*/
|
|
||||||
String getHeader(String name);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return all values associated with the given header name, if any.
|
|
||||||
* @param name the name of the header
|
|
||||||
* @return the header values as an array, or <code>null</code> if no such header was found
|
|
||||||
* @since 3.1
|
|
||||||
*/
|
|
||||||
String[] getHeaders(String name);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return an {@link java.util.Iterator} of Strings containing the
|
|
||||||
* names of headers associated with this file.
|
|
||||||
* @return the names of the headers
|
|
||||||
* @since 3.1
|
|
||||||
*/
|
|
||||||
Iterator<String> getHeaderNames();
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2008 the original author or authors.
|
* Copyright 2002-2011 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.
|
||||||
|
|
@ -18,6 +18,9 @@ package org.springframework.web.multipart;
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
|
||||||
|
import org.springframework.http.HttpHeaders;
|
||||||
|
import org.springframework.http.HttpMethod;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides additional methods for dealing with multipart content within a
|
* Provides additional methods for dealing with multipart content within a
|
||||||
* servlet request, allowing to access uploaded files.
|
* servlet request, allowing to access uploaded files.
|
||||||
|
|
@ -44,4 +47,21 @@ import javax.servlet.http.HttpServletRequest;
|
||||||
*/
|
*/
|
||||||
public interface MultipartHttpServletRequest extends HttpServletRequest, MultipartRequest {
|
public interface MultipartHttpServletRequest extends HttpServletRequest, MultipartRequest {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return this request's method as a convenient HttpMethod instance.
|
||||||
|
*/
|
||||||
|
HttpMethod getRequestMethod();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return this request's headers as a convenient HttpHeaders instance.
|
||||||
|
*/
|
||||||
|
HttpHeaders getRequestHeaders();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the headers associated with the specified part of the multipart request.
|
||||||
|
* <p>If the underlying implementation supports access to headers, then all headers are returned.
|
||||||
|
* Otherwise, the returned headers will include a 'Content-Type' header at the very least.
|
||||||
|
*/
|
||||||
|
HttpHeaders getMultipartHeaders(String paramOrFileName);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2010 the original author or authors.
|
* Copyright 2002-2011 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.
|
||||||
|
|
@ -75,4 +75,11 @@ public interface MultipartRequest {
|
||||||
*/
|
*/
|
||||||
MultiValueMap<String, MultipartFile> getMultiFileMap();
|
MultiValueMap<String, MultipartFile> getMultiFileMap();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine the content type of the specified request part.
|
||||||
|
* @param paramOrFileName the name of the part
|
||||||
|
* @return the associated content type, or <code>null</code> if not defined
|
||||||
|
*/
|
||||||
|
String getMultipartContentType(String paramOrFileName);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,98 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2002-2011 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.web.multipart;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.net.URI;
|
|
||||||
import java.net.URISyntaxException;
|
|
||||||
import java.util.Iterator;
|
|
||||||
|
|
||||||
import org.springframework.http.HttpHeaders;
|
|
||||||
import org.springframework.http.HttpMethod;
|
|
||||||
import org.springframework.http.server.ServerHttpRequest;
|
|
||||||
import org.springframework.util.Assert;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* {@link ServerHttpRequest} implementation that is based on a part of a {@link MultipartHttpServletRequest}.
|
|
||||||
* The part is accessed as {@link MultipartFile} and adapted to the ServerHttpRequest contract.
|
|
||||||
*
|
|
||||||
* @author Rossen Stoyanchev
|
|
||||||
* @since 3.1
|
|
||||||
*/
|
|
||||||
public class RequestPartServletServerHttpRequest implements ServerHttpRequest {
|
|
||||||
|
|
||||||
private final MultipartHttpServletRequest request;
|
|
||||||
|
|
||||||
private final MultipartFile multipartFile;
|
|
||||||
|
|
||||||
private HttpHeaders headers;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a new {@link RequestPartServletServerHttpRequest} instance.
|
|
||||||
*
|
|
||||||
* @param request the multipart request.
|
|
||||||
* @param name the name of the part to adapt to the {@link ServerHttpRequest} contract.
|
|
||||||
*/
|
|
||||||
public RequestPartServletServerHttpRequest(MultipartHttpServletRequest request, String name) {
|
|
||||||
this.request = request;
|
|
||||||
this.multipartFile = request.getFile(name);
|
|
||||||
Assert.notNull(multipartFile, "Request part named '" + name + "' not found. " +
|
|
||||||
"Available request part names: " + request.getMultiFileMap().keySet());
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public HttpMethod getMethod() {
|
|
||||||
return HttpMethod.valueOf(this.request.getMethod());
|
|
||||||
}
|
|
||||||
|
|
||||||
public URI getURI() {
|
|
||||||
try {
|
|
||||||
return new URI(this.request.getScheme(), null, this.request.getServerName(),
|
|
||||||
this.request.getServerPort(), this.request.getRequestURI(),
|
|
||||||
this.request.getQueryString(), null);
|
|
||||||
}
|
|
||||||
catch (URISyntaxException ex) {
|
|
||||||
throw new IllegalStateException("Could not get HttpServletRequest URI: " + ex.getMessage(), ex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the headers associated with the part of the multi-part request associated with this instance.
|
|
||||||
* If the underlying implementation supports access to headers, then all headers are returned.
|
|
||||||
* Otherwise, the returned headers will have a 'Content-Type' header in the very least.
|
|
||||||
*/
|
|
||||||
public HttpHeaders getHeaders() {
|
|
||||||
if (this.headers == null) {
|
|
||||||
this.headers = new HttpHeaders();
|
|
||||||
Iterator<String> iterator = this.multipartFile.getHeaderNames();
|
|
||||||
while (iterator.hasNext()) {
|
|
||||||
String name = iterator.next();
|
|
||||||
String[] values = this.multipartFile.getHeaders(name);
|
|
||||||
for (String value : values) {
|
|
||||||
this.headers.add(name, value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return this.headers;
|
|
||||||
}
|
|
||||||
|
|
||||||
public InputStream getBody() throws IOException {
|
|
||||||
return this.multipartFile.getInputStream();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -217,6 +217,7 @@ public abstract class CommonsFileUploadSupport {
|
||||||
protected MultipartParsingResult parseFileItems(List<FileItem> fileItems, String encoding) {
|
protected MultipartParsingResult parseFileItems(List<FileItem> fileItems, String encoding) {
|
||||||
MultiValueMap<String, MultipartFile> multipartFiles = new LinkedMultiValueMap<String, MultipartFile>();
|
MultiValueMap<String, MultipartFile> multipartFiles = new LinkedMultiValueMap<String, MultipartFile>();
|
||||||
Map<String, String[]> multipartParameters = new HashMap<String, String[]>();
|
Map<String, String[]> multipartParameters = new HashMap<String, String[]>();
|
||||||
|
Map<String, String> multipartParameterContentTypes = new HashMap<String, String>();
|
||||||
|
|
||||||
// Extract multipart files and multipart parameters.
|
// Extract multipart files and multipart parameters.
|
||||||
for (FileItem fileItem : fileItems) {
|
for (FileItem fileItem : fileItems) {
|
||||||
|
|
@ -248,6 +249,7 @@ public abstract class CommonsFileUploadSupport {
|
||||||
String[] newParam = StringUtils.addStringToArray(curParam, value);
|
String[] newParam = StringUtils.addStringToArray(curParam, value);
|
||||||
multipartParameters.put(fileItem.getFieldName(), newParam);
|
multipartParameters.put(fileItem.getFieldName(), newParam);
|
||||||
}
|
}
|
||||||
|
multipartParameterContentTypes.put(fileItem.getFieldName(), fileItem.getContentType());
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// multipart file field
|
// multipart file field
|
||||||
|
|
@ -260,7 +262,7 @@ public abstract class CommonsFileUploadSupport {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return new MultipartParsingResult(multipartFiles, multipartParameters);
|
return new MultipartParsingResult(multipartFiles, multipartParameters, multipartParameterContentTypes);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -305,29 +307,26 @@ public abstract class CommonsFileUploadSupport {
|
||||||
|
|
||||||
private final Map<String, String[]> multipartParameters;
|
private final Map<String, String[]> multipartParameters;
|
||||||
|
|
||||||
/**
|
private final Map<String, String> multipartParameterContentTypes;
|
||||||
* Create a new MultipartParsingResult.
|
|
||||||
* @param mpFiles Map of field name to MultipartFile instance
|
public MultipartParsingResult(MultiValueMap<String, MultipartFile> mpFiles,
|
||||||
* @param mpParams Map of field name to form field String value
|
Map<String, String[]> mpParams, Map<String, String> mpParamContentTypes) {
|
||||||
*/
|
|
||||||
public MultipartParsingResult(MultiValueMap<String, MultipartFile> mpFiles, Map<String, String[]> mpParams) {
|
|
||||||
this.multipartFiles = mpFiles;
|
this.multipartFiles = mpFiles;
|
||||||
this.multipartParameters = mpParams;
|
this.multipartParameters = mpParams;
|
||||||
|
this.multipartParameterContentTypes = mpParamContentTypes;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Return the multipart files as Map of field name to MultipartFile instance.
|
|
||||||
*/
|
|
||||||
public MultiValueMap<String, MultipartFile> getMultipartFiles() {
|
public MultiValueMap<String, MultipartFile> getMultipartFiles() {
|
||||||
return this.multipartFiles;
|
return this.multipartFiles;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Return the multipart parameters as Map of field name to form field String value.
|
|
||||||
*/
|
|
||||||
public Map<String, String[]> getMultipartParameters() {
|
public Map<String, String[]> getMultipartParameters() {
|
||||||
return this.multipartParameters;
|
return this.multipartParameters;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Map<String, String> getMultipartParameterContentTypes() {
|
||||||
|
return this.multipartParameterContentTypes;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -42,8 +42,6 @@ import org.springframework.web.multipart.MultipartFile;
|
||||||
*/
|
*/
|
||||||
public class CommonsMultipartFile implements MultipartFile, Serializable {
|
public class CommonsMultipartFile implements MultipartFile, Serializable {
|
||||||
|
|
||||||
private static final String CONTENT_TYPE = "Content-Type";
|
|
||||||
|
|
||||||
protected static final Log logger = LogFactory.getLog(CommonsMultipartFile.class);
|
protected static final Log logger = LogFactory.getLog(CommonsMultipartFile.class);
|
||||||
|
|
||||||
private final FileItem fileItem;
|
private final FileItem fileItem;
|
||||||
|
|
@ -191,26 +189,4 @@ public class CommonsMultipartFile implements MultipartFile, Serializable {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getHeader(String name) {
|
|
||||||
if (CONTENT_TYPE.equalsIgnoreCase(name)) {
|
|
||||||
return this.fileItem.getContentType();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public String[] getHeaders(String name) {
|
|
||||||
if (CONTENT_TYPE.equalsIgnoreCase(name)) {
|
|
||||||
return new String[] {this.fileItem.getContentType()};
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public Iterator<String> getHeaderNames() {
|
|
||||||
return Collections.singleton(CONTENT_TYPE).iterator();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2010 the original author or authors.
|
* Copyright 2002-2011 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.
|
||||||
|
|
@ -131,13 +131,14 @@ public class CommonsMultipartResolver extends CommonsFileUploadSupport
|
||||||
MultipartParsingResult parsingResult = parseRequest(request);
|
MultipartParsingResult parsingResult = parseRequest(request);
|
||||||
setMultipartFiles(parsingResult.getMultipartFiles());
|
setMultipartFiles(parsingResult.getMultipartFiles());
|
||||||
setMultipartParameters(parsingResult.getMultipartParameters());
|
setMultipartParameters(parsingResult.getMultipartParameters());
|
||||||
|
setMultipartParameterContentTypes(parsingResult.getMultipartParameterContentTypes());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
MultipartParsingResult parsingResult = parseRequest(request);
|
MultipartParsingResult parsingResult = parseRequest(request);
|
||||||
return new DefaultMultipartHttpServletRequest(
|
return new DefaultMultipartHttpServletRequest(request, parsingResult.getMultipartFiles(),
|
||||||
request, parsingResult.getMultipartFiles(), parsingResult.getMultipartParameters());
|
parsingResult.getMultipartParameters(), parsingResult.getMultipartParameterContentTypes());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2008 the original author or authors.
|
* Copyright 2002-2011 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.
|
||||||
|
|
@ -17,17 +17,19 @@
|
||||||
package org.springframework.web.multipart.support;
|
package org.springframework.web.multipart.support;
|
||||||
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
import java.util.Enumeration;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.Map;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
import javax.servlet.http.HttpServletRequestWrapper;
|
import javax.servlet.http.HttpServletRequestWrapper;
|
||||||
|
|
||||||
|
import org.springframework.http.HttpHeaders;
|
||||||
|
import org.springframework.http.HttpMethod;
|
||||||
|
import org.springframework.util.LinkedMultiValueMap;
|
||||||
|
import org.springframework.util.MultiValueMap;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
import org.springframework.web.multipart.MultipartHttpServletRequest;
|
import org.springframework.web.multipart.MultipartHttpServletRequest;
|
||||||
import org.springframework.util.MultiValueMap;
|
|
||||||
import org.springframework.util.LinkedMultiValueMap;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Abstract base implementation of the MultipartHttpServletRequest interface.
|
* Abstract base implementation of the MultipartHttpServletRequest interface.
|
||||||
|
|
@ -52,6 +54,25 @@ public abstract class AbstractMultipartHttpServletRequest extends HttpServletReq
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public HttpServletRequest getRequest() {
|
||||||
|
return (HttpServletRequest) super.getRequest();
|
||||||
|
}
|
||||||
|
|
||||||
|
public HttpMethod getRequestMethod() {
|
||||||
|
return HttpMethod.valueOf(getRequest().getMethod());
|
||||||
|
}
|
||||||
|
|
||||||
|
public HttpHeaders getRequestHeaders() {
|
||||||
|
HttpHeaders headers = new HttpHeaders();
|
||||||
|
Enumeration<String> headerNames = getHeaderNames();
|
||||||
|
while (headerNames.hasMoreElements()) {
|
||||||
|
String headerName = headerNames.nextElement();
|
||||||
|
headers.put(headerName, Collections.list(getHeaders(headerName)));
|
||||||
|
}
|
||||||
|
return headers;
|
||||||
|
}
|
||||||
|
|
||||||
public Iterator<String> getFileNames() {
|
public Iterator<String> getFileNames() {
|
||||||
return getMultipartFiles().keySet().iterator();
|
return getMultipartFiles().keySet().iterator();
|
||||||
}
|
}
|
||||||
|
|
@ -78,6 +99,7 @@ public abstract class AbstractMultipartHttpServletRequest extends HttpServletReq
|
||||||
return getMultipartFiles();
|
return getMultipartFiles();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set a Map with parameter names as keys and list of MultipartFile objects as values.
|
* Set a Map with parameter names as keys and list of MultipartFile objects as values.
|
||||||
* To be invoked by subclasses on initialization.
|
* To be invoked by subclasses on initialization.
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2008 the original author or authors.
|
* Copyright 2002-2011 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.
|
||||||
|
|
@ -24,8 +24,9 @@ import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.http.HttpHeaders;
|
||||||
import org.springframework.util.MultiValueMap;
|
import org.springframework.util.MultiValueMap;
|
||||||
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Default implementation of the
|
* Default implementation of the
|
||||||
|
|
@ -40,8 +41,12 @@ import org.springframework.util.MultiValueMap;
|
||||||
*/
|
*/
|
||||||
public class DefaultMultipartHttpServletRequest extends AbstractMultipartHttpServletRequest {
|
public class DefaultMultipartHttpServletRequest extends AbstractMultipartHttpServletRequest {
|
||||||
|
|
||||||
|
private static final String CONTENT_TYPE = "Content-Type";
|
||||||
|
|
||||||
private Map<String, String[]> multipartParameters;
|
private Map<String, String[]> multipartParameters;
|
||||||
|
|
||||||
|
private Map<String, String> multipartParameterContentTypes;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Wrap the given HttpServletRequest in a MultipartHttpServletRequest.
|
* Wrap the given HttpServletRequest in a MultipartHttpServletRequest.
|
||||||
|
|
@ -50,12 +55,13 @@ public class DefaultMultipartHttpServletRequest extends AbstractMultipartHttpSer
|
||||||
* @param mpParams a map of the parameters to expose,
|
* @param mpParams a map of the parameters to expose,
|
||||||
* with Strings as keys and String arrays as values
|
* with Strings as keys and String arrays as values
|
||||||
*/
|
*/
|
||||||
public DefaultMultipartHttpServletRequest(
|
public DefaultMultipartHttpServletRequest(HttpServletRequest request, MultiValueMap<String, MultipartFile> mpFiles,
|
||||||
HttpServletRequest request, MultiValueMap<String, MultipartFile> mpFiles, Map<String, String[]> mpParams) {
|
Map<String, String[]> mpParams, Map<String, String> mpParamContentTypes) {
|
||||||
|
|
||||||
super(request);
|
super(request);
|
||||||
setMultipartFiles(mpFiles);
|
setMultipartFiles(mpFiles);
|
||||||
setMultipartParameters(mpParams);
|
setMultipartParameters(mpParams);
|
||||||
|
setMultipartParameterContentTypes(mpParamContentTypes);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -105,6 +111,28 @@ public class DefaultMultipartHttpServletRequest extends AbstractMultipartHttpSer
|
||||||
return paramMap;
|
return paramMap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getMultipartContentType(String paramOrFileName) {
|
||||||
|
MultipartFile file = getFile(paramOrFileName);
|
||||||
|
if (file != null) {
|
||||||
|
return file.getContentType();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return getMultipartParameterContentTypes().get(paramOrFileName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public HttpHeaders getMultipartHeaders(String paramOrFileName) {
|
||||||
|
String contentType = getMultipartContentType(paramOrFileName);
|
||||||
|
if (contentType != null) {
|
||||||
|
HttpHeaders headers = new HttpHeaders();
|
||||||
|
headers.add(CONTENT_TYPE, contentType);
|
||||||
|
return headers;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set a Map with parameter names as keys and String array objects as values.
|
* Set a Map with parameter names as keys and String array objects as values.
|
||||||
|
|
@ -126,4 +154,24 @@ public class DefaultMultipartHttpServletRequest extends AbstractMultipartHttpSer
|
||||||
return this.multipartParameters;
|
return this.multipartParameters;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set a Map with parameter names as keys and content type Strings as values.
|
||||||
|
* To be invoked by subclasses on initialization.
|
||||||
|
*/
|
||||||
|
protected final void setMultipartParameterContentTypes(Map<String, String> multipartParameterContentTypes) {
|
||||||
|
this.multipartParameterContentTypes = multipartParameterContentTypes;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Obtain the multipart parameter content type Map for retrieval,
|
||||||
|
* lazily initializing it if necessary.
|
||||||
|
* @see #initializeMultipart()
|
||||||
|
*/
|
||||||
|
protected Map<String, String> getMultipartParameterContentTypes() {
|
||||||
|
if (this.multipartParameterContentTypes == null) {
|
||||||
|
initializeMultipart();
|
||||||
|
}
|
||||||
|
return this.multipartParameterContentTypes;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2010 the original author or authors.
|
* Copyright 2002-2011 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.
|
||||||
|
|
@ -38,6 +38,10 @@ import org.springframework.web.multipart.MultipartResolver;
|
||||||
* on each request, to avoid initialization order issues (when using ContextLoaderServlet,
|
* on each request, to avoid initialization order issues (when using ContextLoaderServlet,
|
||||||
* the root application context will get initialized <i>after</i> this filter).
|
* the root application context will get initialized <i>after</i> this filter).
|
||||||
*
|
*
|
||||||
|
* <p>If no MultipartResolver bean is found, this filter falls back to a default
|
||||||
|
* MultipartResolver: {@link StandardServletMultipartResolver} for Servlet 3.0,
|
||||||
|
* based on a multipart-config section in <code>web.xml</code>.
|
||||||
|
*
|
||||||
* <p>MultipartResolver lookup is customizable: Override this filter's
|
* <p>MultipartResolver lookup is customizable: Override this filter's
|
||||||
* <code>lookupMultipartResolver</code> method to use a custom MultipartResolver
|
* <code>lookupMultipartResolver</code> method to use a custom MultipartResolver
|
||||||
* instance, for example if not using a Spring web application context.
|
* instance, for example if not using a Spring web application context.
|
||||||
|
|
@ -61,6 +65,8 @@ public class MultipartFilter extends OncePerRequestFilter {
|
||||||
|
|
||||||
public static final String DEFAULT_MULTIPART_RESOLVER_BEAN_NAME = "filterMultipartResolver";
|
public static final String DEFAULT_MULTIPART_RESOLVER_BEAN_NAME = "filterMultipartResolver";
|
||||||
|
|
||||||
|
private final MultipartResolver defaultMultipartResolver = new StandardServletMultipartResolver();
|
||||||
|
|
||||||
private String multipartResolverBeanName = DEFAULT_MULTIPART_RESOLVER_BEAN_NAME;
|
private String multipartResolverBeanName = DEFAULT_MULTIPART_RESOLVER_BEAN_NAME;
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -122,7 +128,7 @@ public class MultipartFilter extends OncePerRequestFilter {
|
||||||
/**
|
/**
|
||||||
* Look up the MultipartResolver that this filter should use,
|
* Look up the MultipartResolver that this filter should use,
|
||||||
* taking the current HTTP request as argument.
|
* taking the current HTTP request as argument.
|
||||||
* <p>Default implementation delegates to the <code>lookupMultipartResolver</code>
|
* <p>The default implementation delegates to the <code>lookupMultipartResolver</code>
|
||||||
* without arguments.
|
* without arguments.
|
||||||
* @return the MultipartResolver to use
|
* @return the MultipartResolver to use
|
||||||
* @see #lookupMultipartResolver()
|
* @see #lookupMultipartResolver()
|
||||||
|
|
@ -140,11 +146,17 @@ public class MultipartFilter extends OncePerRequestFilter {
|
||||||
* @return the MultipartResolver instance, or <code>null</code> if none found
|
* @return the MultipartResolver instance, or <code>null</code> if none found
|
||||||
*/
|
*/
|
||||||
protected MultipartResolver lookupMultipartResolver() {
|
protected MultipartResolver lookupMultipartResolver() {
|
||||||
|
WebApplicationContext wac = WebApplicationContextUtils.getWebApplicationContext(getServletContext());
|
||||||
|
String beanName = getMultipartResolverBeanName();
|
||||||
|
if (wac != null && wac.containsBean(beanName)) {
|
||||||
if (logger.isDebugEnabled()) {
|
if (logger.isDebugEnabled()) {
|
||||||
logger.debug("Using MultipartResolver '" + getMultipartResolverBeanName() + "' for MultipartFilter");
|
logger.debug("Using MultipartResolver '" + beanName + "' for MultipartFilter");
|
||||||
|
}
|
||||||
|
return wac.getBean(beanName, MultipartResolver.class);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return this.defaultMultipartResolver;
|
||||||
}
|
}
|
||||||
WebApplicationContext wac = WebApplicationContextUtils.getRequiredWebApplicationContext(getServletContext());
|
|
||||||
return wac.getBean(getMultipartResolverBeanName(), MultipartResolver.class);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,94 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2002-2011 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.web.multipart.support;
|
||||||
|
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
|
||||||
|
import org.springframework.http.HttpHeaders;
|
||||||
|
import org.springframework.http.server.ServerHttpRequest;
|
||||||
|
import org.springframework.http.server.ServletServerHttpRequest;
|
||||||
|
import org.springframework.web.multipart.MultipartException;
|
||||||
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
import org.springframework.web.multipart.MultipartHttpServletRequest;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@link ServerHttpRequest} implementation that is based on a part of a {@link MultipartHttpServletRequest}.
|
||||||
|
* The part is accessed as {@link MultipartFile} and adapted to the ServerHttpRequest contract.
|
||||||
|
*
|
||||||
|
* @author Rossen Stoyanchev
|
||||||
|
* @author Juergen Hoeller
|
||||||
|
* @since 3.1
|
||||||
|
*/
|
||||||
|
public class RequestPartServletServerHttpRequest extends ServletServerHttpRequest {
|
||||||
|
|
||||||
|
private final MultipartHttpServletRequest multipartRequest;
|
||||||
|
|
||||||
|
private final String partName;
|
||||||
|
|
||||||
|
private final HttpHeaders headers;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new {@link RequestPartServletServerHttpRequest} instance.
|
||||||
|
* @param request the multipart request
|
||||||
|
* @param partName the name of the part to adapt to the {@link ServerHttpRequest} contract
|
||||||
|
*/
|
||||||
|
public RequestPartServletServerHttpRequest(HttpServletRequest request, String partName) {
|
||||||
|
super(request);
|
||||||
|
|
||||||
|
this.multipartRequest = (request instanceof MultipartHttpServletRequest ?
|
||||||
|
(MultipartHttpServletRequest) request : new StandardMultipartHttpServletRequest(request));
|
||||||
|
this.partName = partName;
|
||||||
|
|
||||||
|
this.headers = this.multipartRequest.getMultipartHeaders(this.partName);
|
||||||
|
if (this.headers == null) {
|
||||||
|
throw new IllegalArgumentException("No request part found for name '" + this.partName + "'");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public HttpHeaders getHeaders() {
|
||||||
|
return this.headers;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public InputStream getBody() throws IOException {
|
||||||
|
if (this.multipartRequest instanceof StandardMultipartHttpServletRequest) {
|
||||||
|
try {
|
||||||
|
return this.multipartRequest.getPart(this.partName).getInputStream();
|
||||||
|
}
|
||||||
|
catch (Exception ex) {
|
||||||
|
throw new MultipartException("Could not parse multipart servlet request", ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
MultipartFile file = this.multipartRequest.getFile(this.partName);
|
||||||
|
if (file != null) {
|
||||||
|
return file.getInputStream();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
String paramValue = this.multipartRequest.getParameter(this.partName);
|
||||||
|
return new ByteArrayInputStream(paramValue.getBytes(FORM_CHARSET));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,175 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2002-2011 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.web.multipart.support;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.Part;
|
||||||
|
|
||||||
|
import org.springframework.http.HttpHeaders;
|
||||||
|
import org.springframework.util.FileCopyUtils;
|
||||||
|
import org.springframework.util.LinkedMultiValueMap;
|
||||||
|
import org.springframework.util.MultiValueMap;
|
||||||
|
import org.springframework.web.multipart.MultipartException;
|
||||||
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Spring MultipartHttpServletRequest adapter, wrapping a Servlet 3.0 HttpServletRequest
|
||||||
|
* and its Part objects. Parameters get exposed through the native request's getParameter
|
||||||
|
* methods - without any custom processing on our side.
|
||||||
|
*
|
||||||
|
* @author Juergen Hoeller
|
||||||
|
* @since 3.1
|
||||||
|
*/
|
||||||
|
public class StandardMultipartHttpServletRequest extends AbstractMultipartHttpServletRequest {
|
||||||
|
|
||||||
|
private static final String CONTENT_DISPOSITION = "Content-Disposition";
|
||||||
|
|
||||||
|
private static final String FILENAME_KEY = "filename=";
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new StandardMultipartHttpServletRequest wrapper for the given request.
|
||||||
|
* @param request the servlet request to wrap
|
||||||
|
* @throws MultipartException if parsing failed
|
||||||
|
*/
|
||||||
|
public StandardMultipartHttpServletRequest(HttpServletRequest request) throws MultipartException {
|
||||||
|
super(request);
|
||||||
|
try {
|
||||||
|
Collection<Part> parts = request.getParts();
|
||||||
|
MultiValueMap<String, MultipartFile> files = new LinkedMultiValueMap<String, MultipartFile>(parts.size());
|
||||||
|
for (Part part : parts) {
|
||||||
|
String filename = extractFilename(part.getHeader(CONTENT_DISPOSITION));
|
||||||
|
if (filename != null) {
|
||||||
|
files.add(part.getName(), new StandardMultipartFile(part, filename));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
setMultipartFiles(files);
|
||||||
|
}
|
||||||
|
catch (Exception ex) {
|
||||||
|
throw new MultipartException("Could not parse multipart servlet request", ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private String extractFilename(String contentDisposition) {
|
||||||
|
if (contentDisposition == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
// TODO: can only handle the typical case at the moment
|
||||||
|
int startIndex = contentDisposition.indexOf(FILENAME_KEY);
|
||||||
|
if (startIndex == -1) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
String filename = contentDisposition.substring(startIndex + FILENAME_KEY.length());
|
||||||
|
if (filename.startsWith("\"")) {
|
||||||
|
int endIndex = filename.indexOf("\"", 1);
|
||||||
|
if (endIndex != -1) {
|
||||||
|
return filename.substring(1, endIndex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
int endIndex = filename.indexOf(";");
|
||||||
|
if (endIndex != -1) {
|
||||||
|
return filename.substring(0, endIndex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return filename;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public String getMultipartContentType(String paramOrFileName) {
|
||||||
|
try {
|
||||||
|
Part part = getPart(paramOrFileName);
|
||||||
|
return (part != null ? part.getContentType() : null);
|
||||||
|
}
|
||||||
|
catch (Exception ex) {
|
||||||
|
throw new MultipartException("Could not access multipart servlet request", ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public HttpHeaders getMultipartHeaders(String paramOrFileName) {
|
||||||
|
try {
|
||||||
|
Part part = getPart(paramOrFileName);
|
||||||
|
if (part != null) {
|
||||||
|
HttpHeaders headers = new HttpHeaders();
|
||||||
|
for (String headerName : part.getHeaderNames()) {
|
||||||
|
headers.put(headerName, new ArrayList<String>(part.getHeaders(headerName)));
|
||||||
|
}
|
||||||
|
return headers;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex) {
|
||||||
|
throw new MultipartException("Could not access multipart servlet request", ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Spring MultipartFile adapter, wrapping a Servlet 3.0 Part object.
|
||||||
|
*/
|
||||||
|
private static class StandardMultipartFile implements MultipartFile {
|
||||||
|
|
||||||
|
private final Part part;
|
||||||
|
|
||||||
|
private final String filename;
|
||||||
|
|
||||||
|
public StandardMultipartFile(Part part, String filename) {
|
||||||
|
this.part = part;
|
||||||
|
this.filename = filename;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return this.part.getName();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getOriginalFilename() {
|
||||||
|
return this.filename;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getContentType() {
|
||||||
|
return this.part.getContentType();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isEmpty() {
|
||||||
|
return (this.part.getSize() == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getSize() {
|
||||||
|
return this.part.getSize();
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte[] getBytes() throws IOException {
|
||||||
|
return FileCopyUtils.copyToByteArray(this.part.getInputStream());
|
||||||
|
}
|
||||||
|
|
||||||
|
public InputStream getInputStream() throws IOException {
|
||||||
|
return this.part.getInputStream();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void transferTo(File dest) throws IOException, IllegalStateException {
|
||||||
|
this.part.write(dest.getPath());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -16,23 +16,12 @@
|
||||||
|
|
||||||
package org.springframework.web.multipart.support;
|
package org.springframework.web.multipart.support;
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.Iterator;
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
import javax.servlet.http.Part;
|
import javax.servlet.http.Part;
|
||||||
|
|
||||||
import org.apache.commons.logging.Log;
|
|
||||||
import org.apache.commons.logging.LogFactory;
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
|
||||||
import org.springframework.util.FileCopyUtils;
|
|
||||||
import org.springframework.util.LinkedMultiValueMap;
|
|
||||||
import org.springframework.util.MultiValueMap;
|
|
||||||
import org.springframework.util.StringUtils;
|
|
||||||
import org.springframework.web.multipart.MultipartException;
|
import org.springframework.web.multipart.MultipartException;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
|
||||||
import org.springframework.web.multipart.MultipartHttpServletRequest;
|
import org.springframework.web.multipart.MultipartHttpServletRequest;
|
||||||
import org.springframework.web.multipart.MultipartResolver;
|
import org.springframework.web.multipart.MultipartResolver;
|
||||||
|
|
||||||
|
|
@ -56,9 +45,6 @@ import org.springframework.web.multipart.MultipartResolver;
|
||||||
*/
|
*/
|
||||||
public class StandardServletMultipartResolver implements MultipartResolver {
|
public class StandardServletMultipartResolver implements MultipartResolver {
|
||||||
|
|
||||||
protected final Log logger = LogFactory.getLog(getClass());
|
|
||||||
|
|
||||||
|
|
||||||
public boolean isMultipart(HttpServletRequest request) {
|
public boolean isMultipart(HttpServletRequest request) {
|
||||||
// Same check as in Commons FileUpload...
|
// Same check as in Commons FileUpload...
|
||||||
if (!"post".equals(request.getMethod().toLowerCase())) {
|
if (!"post".equals(request.getMethod().toLowerCase())) {
|
||||||
|
|
@ -80,89 +66,7 @@ public class StandardServletMultipartResolver implements MultipartResolver {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex) {
|
catch (Exception ex) {
|
||||||
logger.warn("Failed to perform cleanup of multipart items", ex);
|
LogFactory.getLog(getClass()).warn("Failed to perform cleanup of multipart items", ex);
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Spring MultipartHttpServletRequest adapter, wrapping a Servlet 3.0 HttpServletRequest
|
|
||||||
* and its Part objects. Parameters get exposed through the native request's getParameter
|
|
||||||
* methods - without any custom processing on our side.
|
|
||||||
*/
|
|
||||||
private static class StandardMultipartHttpServletRequest extends AbstractMultipartHttpServletRequest {
|
|
||||||
|
|
||||||
public StandardMultipartHttpServletRequest(HttpServletRequest request) throws MultipartException {
|
|
||||||
super(request);
|
|
||||||
try {
|
|
||||||
Collection<Part> parts = request.getParts();
|
|
||||||
MultiValueMap<String, MultipartFile> files = new LinkedMultiValueMap<String, MultipartFile>(parts.size());
|
|
||||||
for (Part part : parts) {
|
|
||||||
files.add(part.getName(), new StandardMultipartFile(part));
|
|
||||||
}
|
|
||||||
setMultipartFiles(files);
|
|
||||||
}
|
|
||||||
catch (Exception ex) {
|
|
||||||
throw new MultipartException("Could not parse multipart servlet request", ex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Spring MultipartFile adapter, wrapping a Servlet 3.0 Part object.
|
|
||||||
*/
|
|
||||||
private static class StandardMultipartFile implements MultipartFile {
|
|
||||||
|
|
||||||
private final Part part;
|
|
||||||
|
|
||||||
public StandardMultipartFile(Part part) {
|
|
||||||
this.part = part;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getName() {
|
|
||||||
return this.part.getName();
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getOriginalFilename() {
|
|
||||||
return null; // not supported in Servlet 3.0 - switch to Commons FileUpload if you need this
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getContentType() {
|
|
||||||
return this.part.getContentType();
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isEmpty() {
|
|
||||||
return (this.part.getSize() == 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
public long getSize() {
|
|
||||||
return this.part.getSize();
|
|
||||||
}
|
|
||||||
|
|
||||||
public byte[] getBytes() throws IOException {
|
|
||||||
return FileCopyUtils.copyToByteArray(this.part.getInputStream());
|
|
||||||
}
|
|
||||||
|
|
||||||
public InputStream getInputStream() throws IOException {
|
|
||||||
return this.part.getInputStream();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void transferTo(File dest) throws IOException, IllegalStateException {
|
|
||||||
this.part.write(dest.getPath());
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getHeader(String name) {
|
|
||||||
return this.part.getHeader(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
public String[] getHeaders(String name) {
|
|
||||||
Collection<String> headers = this.part.getHeaders(name);
|
|
||||||
return (headers != null ? StringUtils.toStringArray(headers) : null);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Iterator<String> getHeaderNames() {
|
|
||||||
return this.part.getHeaderNames().iterator();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -41,8 +41,6 @@ import org.springframework.web.multipart.MultipartFile;
|
||||||
*/
|
*/
|
||||||
public class MockMultipartFile implements MultipartFile {
|
public class MockMultipartFile implements MultipartFile {
|
||||||
|
|
||||||
private static final String CONTENT_TYPE = "Content-Type";
|
|
||||||
|
|
||||||
private final String name;
|
private final String name;
|
||||||
|
|
||||||
private String originalFilename;
|
private String originalFilename;
|
||||||
|
|
@ -133,26 +131,4 @@ public class MockMultipartFile implements MultipartFile {
|
||||||
FileCopyUtils.copy(this.content, dest);
|
FileCopyUtils.copy(this.content, dest);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getHeader(String name) {
|
|
||||||
if (CONTENT_TYPE.equalsIgnoreCase(name)) {
|
|
||||||
return this.contentType;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public String[] getHeaders(String name) {
|
|
||||||
if (CONTENT_TYPE.equalsIgnoreCase(name)) {
|
|
||||||
return new String[] {this.contentType};
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public Iterator<String> getHeaderNames() {
|
|
||||||
return Collections.singleton(CONTENT_TYPE).iterator();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2010 the original author or authors.
|
* Copyright 2002-2011 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.
|
||||||
|
|
@ -17,10 +17,13 @@
|
||||||
package org.springframework.mock.web;
|
package org.springframework.mock.web;
|
||||||
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
import java.util.Enumeration;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.springframework.http.HttpHeaders;
|
||||||
|
import org.springframework.http.HttpMethod;
|
||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
import org.springframework.util.LinkedMultiValueMap;
|
import org.springframework.util.LinkedMultiValueMap;
|
||||||
import org.springframework.util.MultiValueMap;
|
import org.springframework.util.MultiValueMap;
|
||||||
|
|
@ -89,4 +92,40 @@ public class MockMultipartHttpServletRequest extends MockHttpServletRequest impl
|
||||||
return new LinkedMultiValueMap<String, MultipartFile>(this.multipartFiles);
|
return new LinkedMultiValueMap<String, MultipartFile>(this.multipartFiles);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getMultipartContentType(String paramOrFileName) {
|
||||||
|
MultipartFile file = getFile(paramOrFileName);
|
||||||
|
if (file != null) {
|
||||||
|
return file.getContentType();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public HttpMethod getRequestMethod() {
|
||||||
|
return HttpMethod.valueOf(getMethod());
|
||||||
|
}
|
||||||
|
|
||||||
|
public HttpHeaders getRequestHeaders() {
|
||||||
|
HttpHeaders headers = new HttpHeaders();
|
||||||
|
Enumeration<String> headerNames = getHeaderNames();
|
||||||
|
while (headerNames.hasMoreElements()) {
|
||||||
|
String headerName = headerNames.nextElement();
|
||||||
|
headers.put(headerName, Collections.list(getHeaders(headerName)));
|
||||||
|
}
|
||||||
|
return headers;
|
||||||
|
}
|
||||||
|
|
||||||
|
public HttpHeaders getMultipartHeaders(String paramOrFileName) {
|
||||||
|
String contentType = getMultipartContentType(paramOrFileName);
|
||||||
|
if (contentType != null) {
|
||||||
|
HttpHeaders headers = new HttpHeaders();
|
||||||
|
headers.add("Content-Type", contentType);
|
||||||
|
return headers;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -14,16 +14,13 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.web.multipart;
|
package org.springframework.web.multipart.support;
|
||||||
|
|
||||||
import static org.junit.Assert.assertArrayEquals;
|
|
||||||
import static org.junit.Assert.assertEquals;
|
|
||||||
import static org.junit.Assert.assertNotNull;
|
|
||||||
|
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
|
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import org.springframework.http.HttpHeaders;
|
import org.springframework.http.HttpHeaders;
|
||||||
import org.springframework.http.HttpMethod;
|
import org.springframework.http.HttpMethod;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
|
|
@ -31,9 +28,9 @@ import org.springframework.mock.web.MockMultipartFile;
|
||||||
import org.springframework.mock.web.MockMultipartHttpServletRequest;
|
import org.springframework.mock.web.MockMultipartHttpServletRequest;
|
||||||
import org.springframework.util.FileCopyUtils;
|
import org.springframework.util.FileCopyUtils;
|
||||||
|
|
||||||
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test fixture for {@link RequestPartServletServerHttpRequest} unit tests.
|
|
||||||
*
|
|
||||||
* @author Rossen Stoyanchev
|
* @author Rossen Stoyanchev
|
||||||
*/
|
*/
|
||||||
public class RequestPartServletServerHttpRequestTests {
|
public class RequestPartServletServerHttpRequestTests {
|
||||||
Loading…
Reference in New Issue