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
This commit is contained in:
parent
21f3f59cb7
commit
571535352b
|
|
@ -41,8 +41,6 @@ import org.springframework.web.multipart.MultipartFile;
|
|||
*/
|
||||
public class MockMultipartFile implements MultipartFile {
|
||||
|
||||
private static final String CONTENT_TYPE = "Content-Type";
|
||||
|
||||
private final String name;
|
||||
|
||||
private String originalFilename;
|
||||
|
|
@ -133,26 +131,4 @@ public class MockMultipartFile implements MultipartFile {
|
|||
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");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
|
@ -17,10 +17,13 @@
|
|||
package org.springframework.mock.web;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Enumeration;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.HttpMethod;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.LinkedMultiValueMap;
|
||||
import org.springframework.util.MultiValueMap;
|
||||
|
|
@ -89,4 +92,40 @@ public class MockMultipartHttpServletRequest extends MockHttpServletRequest impl
|
|||
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");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
|
@ -72,7 +72,7 @@ public class MockMultipartActionRequest extends MockActionRequest implements Mul
|
|||
else {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Map<String, MultipartFile> getFileMap() {
|
||||
return this.multipartFiles.toSingleValueMap();
|
||||
|
|
@ -82,4 +82,14 @@ public class MockMultipartActionRequest extends MockActionRequest implements Mul
|
|||
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");
|
||||
* 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);
|
||||
setMultipartFiles(parsingResult.getMultipartFiles());
|
||||
setMultipartParameters(parsingResult.getMultipartParameters());
|
||||
setMultipartParameterContentTypes(parsingResult.getMultipartParameterContentTypes());
|
||||
}
|
||||
};
|
||||
}
|
||||
else {
|
||||
MultipartParsingResult parsingResult = parseRequest(request);
|
||||
return new DefaultMultipartActionRequest(
|
||||
request, parsingResult.getMultipartFiles(), parsingResult.getMultipartParameters());
|
||||
return new DefaultMultipartActionRequest(request, parsingResult.getMultipartFiles(),
|
||||
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");
|
||||
* 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.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.List;
|
||||
import javax.portlet.ActionRequest;
|
||||
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.MultiValueMap;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
/**
|
||||
* 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> multipartParameterContentTypes;
|
||||
|
||||
|
||||
/**
|
||||
* 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,
|
||||
* with Strings as keys and String arrays as values
|
||||
*/
|
||||
public DefaultMultipartActionRequest(
|
||||
ActionRequest request, MultiValueMap<String, MultipartFile> mpFiles, Map<String, String[]> mpParams) {
|
||||
public DefaultMultipartActionRequest(ActionRequest request, MultiValueMap<String, MultipartFile> mpFiles,
|
||||
Map<String, String[]> mpParams, Map<String, String> mpParamContentTypes) {
|
||||
|
||||
super(request);
|
||||
setMultipartFiles(mpFiles);
|
||||
setMultipartParameters(mpParams);
|
||||
setMultipartParameterContentTypes(mpParamContentTypes);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -136,6 +139,16 @@ public class DefaultMultipartActionRequest extends ActionRequestWrapper implemen
|
|||
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.
|
||||
|
|
@ -178,6 +191,27 @@ public class DefaultMultipartActionRequest extends ActionRequestWrapper implemen
|
|||
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.
|
||||
* Only called if not already eagerly initialized.
|
||||
|
|
|
|||
|
|
@ -41,8 +41,6 @@ import org.springframework.web.multipart.MultipartFile;
|
|||
*/
|
||||
public class MockMultipartFile implements MultipartFile {
|
||||
|
||||
private static final String CONTENT_TYPE = "Content-Type";
|
||||
|
||||
private final String name;
|
||||
|
||||
private String originalFilename;
|
||||
|
|
@ -133,26 +131,4 @@ public class MockMultipartFile implements MultipartFile {
|
|||
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");
|
||||
* 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);
|
||||
}
|
||||
|
||||
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");
|
||||
* 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.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
|
@ -481,7 +482,7 @@ public class ComplexPortletApplicationContext extends StaticPortletApplicationCo
|
|||
files.set("someFile", new MockMultipartFile("someFile", "someContent".getBytes()));
|
||||
Map<String, String[]> params = new HashMap<String, String[]>();
|
||||
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) {
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ import org.springframework.web.multipart.MultipartFile;
|
|||
import org.springframework.web.multipart.MultipartHttpServletRequest;
|
||||
import org.springframework.web.multipart.MultipartRequest;
|
||||
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.util.WebUtils;
|
||||
|
||||
|
|
@ -123,9 +123,8 @@ public class RequestPartMethodArgumentResolver extends AbstractMessageConverterM
|
|||
arg = servletRequest.getPart(partName);
|
||||
}
|
||||
else {
|
||||
HttpInputMessage inputMessage = new RequestPartServletServerHttpRequest(multipartRequest, partName);
|
||||
HttpInputMessage inputMessage = new RequestPartServletServerHttpRequest(servletRequest, partName);
|
||||
arg = readWithMessageConverters(inputMessage, parameter, parameter.getParameterType());
|
||||
|
||||
if (isValidationApplicable(arg, parameter)) {
|
||||
WebDataBinder binder = binderFactory.createBinder(request, arg, partName);
|
||||
binder.validate();
|
||||
|
|
|
|||
|
|
@ -41,8 +41,6 @@ import org.springframework.web.multipart.MultipartFile;
|
|||
*/
|
||||
public class MockMultipartFile implements MultipartFile {
|
||||
|
||||
private static final String CONTENT_TYPE = "Content-Type";
|
||||
|
||||
private final String name;
|
||||
|
||||
private String originalFilename;
|
||||
|
|
@ -133,26 +131,4 @@ public class MockMultipartFile implements MultipartFile {
|
|||
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");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
|
@ -17,10 +17,13 @@
|
|||
package org.springframework.mock.web;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Enumeration;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.HttpMethod;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.LinkedMultiValueMap;
|
||||
import org.springframework.util.MultiValueMap;
|
||||
|
|
@ -89,4 +92,40 @@ public class MockMultipartHttpServletRequest extends MockHttpServletRequest impl
|
|||
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");
|
||||
* 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.List;
|
||||
import java.util.Locale;
|
||||
|
||||
import javax.servlet.Servlet;
|
||||
import javax.servlet.ServletConfig;
|
||||
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.MultipartHttpServletRequest;
|
||||
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.SimpleServletHandlerAdapter;
|
||||
import org.springframework.web.servlet.handler.SimpleServletPostProcessor;
|
||||
|
|
@ -434,8 +433,7 @@ public class ComplexWebApplicationContext extends StaticWebApplicationContext {
|
|||
throw new IllegalStateException("Already resolved");
|
||||
}
|
||||
request.setAttribute("resolved", Boolean.TRUE);
|
||||
return new AbstractMultipartHttpServletRequest(request) {
|
||||
};
|
||||
return new DefaultMultipartHttpServletRequest(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.method.support.ModelAndViewContainer;
|
||||
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}.
|
||||
|
|
|
|||
|
|
@ -44,13 +44,14 @@ import org.springframework.util.Assert;
|
|||
*/
|
||||
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;
|
||||
|
||||
|
|
@ -115,7 +116,7 @@ public class ServletServerHttpRequest implements ServerHttpRequest {
|
|||
|
||||
private boolean isFormSubmittal(HttpServletRequest request) {
|
||||
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 {
|
||||
|
|
|
|||
|
|
@ -19,7 +19,6 @@ package org.springframework.web.multipart;
|
|||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.Iterator;
|
||||
|
||||
/**
|
||||
* 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;
|
||||
|
||||
/**
|
||||
* 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");
|
||||
* 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 org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.HttpMethod;
|
||||
|
||||
/**
|
||||
* Provides additional methods for dealing with multipart content within a
|
||||
* servlet request, allowing to access uploaded files.
|
||||
|
|
@ -44,4 +47,21 @@ import javax.servlet.http.HttpServletRequest;
|
|||
*/
|
||||
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");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
|
@ -75,4 +75,11 @@ public interface MultipartRequest {
|
|||
*/
|
||||
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) {
|
||||
MultiValueMap<String, MultipartFile> multipartFiles = new LinkedMultiValueMap<String, MultipartFile>();
|
||||
Map<String, String[]> multipartParameters = new HashMap<String, String[]>();
|
||||
Map<String, String> multipartParameterContentTypes = new HashMap<String, String>();
|
||||
|
||||
// Extract multipart files and multipart parameters.
|
||||
for (FileItem fileItem : fileItems) {
|
||||
|
|
@ -248,6 +249,7 @@ public abstract class CommonsFileUploadSupport {
|
|||
String[] newParam = StringUtils.addStringToArray(curParam, value);
|
||||
multipartParameters.put(fileItem.getFieldName(), newParam);
|
||||
}
|
||||
multipartParameterContentTypes.put(fileItem.getFieldName(), fileItem.getContentType());
|
||||
}
|
||||
else {
|
||||
// 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;
|
||||
|
||||
/**
|
||||
* Create a new MultipartParsingResult.
|
||||
* @param mpFiles Map of field name to MultipartFile instance
|
||||
* @param mpParams Map of field name to form field String value
|
||||
*/
|
||||
public MultipartParsingResult(MultiValueMap<String, MultipartFile> mpFiles, Map<String, String[]> mpParams) {
|
||||
private final Map<String, String> multipartParameterContentTypes;
|
||||
|
||||
public MultipartParsingResult(MultiValueMap<String, MultipartFile> mpFiles,
|
||||
Map<String, String[]> mpParams, Map<String, String> mpParamContentTypes) {
|
||||
this.multipartFiles = mpFiles;
|
||||
this.multipartParameters = mpParams;
|
||||
this.multipartParameterContentTypes = mpParamContentTypes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the multipart files as Map of field name to MultipartFile instance.
|
||||
*/
|
||||
public MultiValueMap<String, MultipartFile> getMultipartFiles() {
|
||||
return this.multipartFiles;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the multipart parameters as Map of field name to form field String value.
|
||||
*/
|
||||
public Map<String, String[]> getMultipartParameters() {
|
||||
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 {
|
||||
|
||||
private static final String CONTENT_TYPE = "Content-Type";
|
||||
|
||||
protected static final Log logger = LogFactory.getLog(CommonsMultipartFile.class);
|
||||
|
||||
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");
|
||||
* 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);
|
||||
setMultipartFiles(parsingResult.getMultipartFiles());
|
||||
setMultipartParameters(parsingResult.getMultipartParameters());
|
||||
setMultipartParameterContentTypes(parsingResult.getMultipartParameterContentTypes());
|
||||
}
|
||||
};
|
||||
}
|
||||
else {
|
||||
MultipartParsingResult parsingResult = parseRequest(request);
|
||||
return new DefaultMultipartHttpServletRequest(
|
||||
request, parsingResult.getMultipartFiles(), parsingResult.getMultipartParameters());
|
||||
return new DefaultMultipartHttpServletRequest(request, parsingResult.getMultipartFiles(),
|
||||
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");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
|
@ -17,17 +17,19 @@
|
|||
package org.springframework.web.multipart.support;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Enumeration;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.List;
|
||||
|
||||
import java.util.Map;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
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.MultipartHttpServletRequest;
|
||||
import org.springframework.util.MultiValueMap;
|
||||
import org.springframework.util.LinkedMultiValueMap;
|
||||
|
||||
/**
|
||||
* Abstract base implementation of the MultipartHttpServletRequest interface.
|
||||
|
|
@ -38,7 +40,7 @@ import org.springframework.util.LinkedMultiValueMap;
|
|||
* @since 06.10.2003
|
||||
*/
|
||||
public abstract class AbstractMultipartHttpServletRequest extends HttpServletRequestWrapper
|
||||
implements MultipartHttpServletRequest {
|
||||
implements MultipartHttpServletRequest {
|
||||
|
||||
private MultiValueMap<String, MultipartFile> multipartFiles;
|
||||
|
||||
|
|
@ -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() {
|
||||
return getMultipartFiles().keySet().iterator();
|
||||
}
|
||||
|
|
@ -78,6 +99,7 @@ public abstract class AbstractMultipartHttpServletRequest extends HttpServletReq
|
|||
return getMultipartFiles();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set a Map with parameter names as keys and list of MultipartFile objects as values.
|
||||
* 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");
|
||||
* 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 javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.util.MultiValueMap;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
/**
|
||||
* Default implementation of the
|
||||
|
|
@ -40,8 +41,12 @@ import org.springframework.util.MultiValueMap;
|
|||
*/
|
||||
public class DefaultMultipartHttpServletRequest extends AbstractMultipartHttpServletRequest {
|
||||
|
||||
private static final String CONTENT_TYPE = "Content-Type";
|
||||
|
||||
private Map<String, String[]> multipartParameters;
|
||||
|
||||
private Map<String, String> multipartParameterContentTypes;
|
||||
|
||||
|
||||
/**
|
||||
* 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,
|
||||
* with Strings as keys and String arrays as values
|
||||
*/
|
||||
public DefaultMultipartHttpServletRequest(
|
||||
HttpServletRequest request, MultiValueMap<String, MultipartFile> mpFiles, Map<String, String[]> mpParams) {
|
||||
public DefaultMultipartHttpServletRequest(HttpServletRequest request, MultiValueMap<String, MultipartFile> mpFiles,
|
||||
Map<String, String[]> mpParams, Map<String, String> mpParamContentTypes) {
|
||||
|
||||
super(request);
|
||||
setMultipartFiles(mpFiles);
|
||||
setMultipartParameters(mpParams);
|
||||
setMultipartParameterContentTypes(mpParamContentTypes);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -105,6 +111,28 @@ public class DefaultMultipartHttpServletRequest extends AbstractMultipartHttpSer
|
|||
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.
|
||||
|
|
@ -126,4 +154,24 @@ public class DefaultMultipartHttpServletRequest extends AbstractMultipartHttpSer
|
|||
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");
|
||||
* 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,
|
||||
* 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
|
||||
* <code>lookupMultipartResolver</code> method to use a custom MultipartResolver
|
||||
* 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";
|
||||
|
||||
private final MultipartResolver defaultMultipartResolver = new StandardServletMultipartResolver();
|
||||
|
||||
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,
|
||||
* 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.
|
||||
* @return the MultipartResolver to use
|
||||
* @see #lookupMultipartResolver()
|
||||
|
|
@ -140,11 +146,17 @@ public class MultipartFilter extends OncePerRequestFilter {
|
|||
* @return the MultipartResolver instance, or <code>null</code> if none found
|
||||
*/
|
||||
protected MultipartResolver lookupMultipartResolver() {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Using MultipartResolver '" + getMultipartResolverBeanName() + "' for MultipartFilter");
|
||||
WebApplicationContext wac = WebApplicationContextUtils.getWebApplicationContext(getServletContext());
|
||||
String beanName = getMultipartResolverBeanName();
|
||||
if (wac != null && wac.containsBean(beanName)) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
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;
|
||||
|
||||
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.Part;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
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.MultipartFile;
|
||||
import org.springframework.web.multipart.MultipartHttpServletRequest;
|
||||
import org.springframework.web.multipart.MultipartResolver;
|
||||
|
||||
|
|
@ -56,9 +45,6 @@ import org.springframework.web.multipart.MultipartResolver;
|
|||
*/
|
||||
public class StandardServletMultipartResolver implements MultipartResolver {
|
||||
|
||||
protected final Log logger = LogFactory.getLog(getClass());
|
||||
|
||||
|
||||
public boolean isMultipart(HttpServletRequest request) {
|
||||
// Same check as in Commons FileUpload...
|
||||
if (!"post".equals(request.getMethod().toLowerCase())) {
|
||||
|
|
@ -80,89 +66,7 @@ public class StandardServletMultipartResolver implements MultipartResolver {
|
|||
}
|
||||
}
|
||||
catch (Exception ex) {
|
||||
logger.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();
|
||||
LogFactory.getLog(getClass()).warn("Failed to perform cleanup of multipart items", ex);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -41,8 +41,6 @@ import org.springframework.web.multipart.MultipartFile;
|
|||
*/
|
||||
public class MockMultipartFile implements MultipartFile {
|
||||
|
||||
private static final String CONTENT_TYPE = "Content-Type";
|
||||
|
||||
private final String name;
|
||||
|
||||
private String originalFilename;
|
||||
|
|
@ -133,26 +131,4 @@ public class MockMultipartFile implements MultipartFile {
|
|||
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");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
|
@ -17,10 +17,13 @@
|
|||
package org.springframework.mock.web;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Enumeration;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.HttpMethod;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.LinkedMultiValueMap;
|
||||
import org.springframework.util.MultiValueMap;
|
||||
|
|
@ -89,4 +92,40 @@ public class MockMultipartHttpServletRequest extends MockHttpServletRequest impl
|
|||
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.
|
||||
*/
|
||||
|
||||
package org.springframework.web.multipart;
|
||||
|
||||
import static org.junit.Assert.assertArrayEquals;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
package org.springframework.web.multipart.support;
|
||||
|
||||
import java.net.URI;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.HttpMethod;
|
||||
import org.springframework.http.MediaType;
|
||||
|
|
@ -31,9 +28,9 @@ import org.springframework.mock.web.MockMultipartFile;
|
|||
import org.springframework.mock.web.MockMultipartHttpServletRequest;
|
||||
import org.springframework.util.FileCopyUtils;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
/**
|
||||
* Test fixture for {@link RequestPartServletServerHttpRequest} unit tests.
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
*/
|
||||
public class RequestPartServletServerHttpRequestTests {
|
||||
Loading…
Reference in New Issue