提交 aa29495d 编写于 作者: J Juergen Hoeller

CommonsMultipartFile.getOriginalFilename() can be configured to preserve...

CommonsMultipartFile.getOriginalFilename() can be configured to preserve header-specified filename as-is

Issue: SPR-14613
上级 39739b31
/* /*
* Copyright 2002-2015 the original author or authors. * Copyright 2002-2016 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.
...@@ -48,9 +48,8 @@ public interface MultipartFile extends InputStreamSource { ...@@ -48,9 +48,8 @@ public interface MultipartFile extends InputStreamSource {
* Return the original filename in the client's filesystem. * Return the original filename in the client's filesystem.
* <p>This may contain path information depending on the browser used, * <p>This may contain path information depending on the browser used,
* but it typically will not with any other than Opera. * but it typically will not with any other than Opera.
* @return the original filename, or the empty String if no file * @return the original filename, or the empty String if no file has been chosen
* has been chosen in the multipart form, or {@code null} * in the multipart form, or {@code null} if not defined or not available
* if not defined or not available
*/ */
String getOriginalFilename(); String getOriginalFilename();
......
...@@ -62,6 +62,8 @@ public abstract class CommonsFileUploadSupport { ...@@ -62,6 +62,8 @@ public abstract class CommonsFileUploadSupport {
private boolean uploadTempDirSpecified = false; private boolean uploadTempDirSpecified = false;
private boolean preserveFilename = false;
/** /**
* Instantiate a new CommonsFileUploadSupport with its * Instantiate a new CommonsFileUploadSupport with its
...@@ -168,6 +170,20 @@ public abstract class CommonsFileUploadSupport { ...@@ -168,6 +170,20 @@ public abstract class CommonsFileUploadSupport {
return this.uploadTempDirSpecified; return this.uploadTempDirSpecified;
} }
/**
* Set whether to preserve the filename as sent by the client, not stripping off
* path information in {@link CommonsMultipartFile#getOriginalFilename()}.
* <p>Default is "false", stripping off path information that may prefix the
* actual filename e.g. from Opera. Switch this to "true" for preserving the
* client-specified filename as-is, including potential path separators.
* @since 4.3.5
* @see MultipartFile#getOriginalFilename()
* @see CommonsMultipartFile#setPreserveFilename(boolean)
*/
public void setPreserveFilename(boolean preserveFilename) {
this.preserveFilename = preserveFilename;
}
/** /**
* Factory method for a Commons DiskFileItemFactory instance. * Factory method for a Commons DiskFileItemFactory instance.
...@@ -259,7 +275,7 @@ public abstract class CommonsFileUploadSupport { ...@@ -259,7 +275,7 @@ public abstract class CommonsFileUploadSupport {
} }
else { else {
// multipart file field // multipart file field
CommonsMultipartFile file = new CommonsMultipartFile(fileItem); CommonsMultipartFile file = createMultipartFile(fileItem);
multipartFiles.add(file.getName(), file); multipartFiles.add(file.getName(), file);
if (logger.isDebugEnabled()) { if (logger.isDebugEnabled()) {
logger.debug("Found multipart file [" + file.getName() + "] of size " + file.getSize() + logger.debug("Found multipart file [" + file.getName() + "] of size " + file.getSize() +
...@@ -271,6 +287,20 @@ public abstract class CommonsFileUploadSupport { ...@@ -271,6 +287,20 @@ public abstract class CommonsFileUploadSupport {
return new MultipartParsingResult(multipartFiles, multipartParameters, multipartParameterContentTypes); return new MultipartParsingResult(multipartFiles, multipartParameters, multipartParameterContentTypes);
} }
/**
* Create a {@link CommonsMultipartFile} wrapper for the given Commons {@link FileItem}.
* @param fileItem the Commons FileItem to wrap
* @return the corresponding CommonsMultipartFile (potentially a custom subclass)
* @since 4.3.5
* @see #setPreserveFilename(boolean)
* @see CommonsMultipartFile#setPreserveFilename(boolean)
*/
protected CommonsMultipartFile createMultipartFile(FileItem fileItem) {
CommonsMultipartFile multipartFile = new CommonsMultipartFile(fileItem);
multipartFile.setPreserveFilename(this.preserveFilename);
return multipartFile;
}
/** /**
* Cleanup the Spring MultipartFiles created during multipart parsing, * Cleanup the Spring MultipartFiles created during multipart parsing,
* potentially holding temporary data on disk. * potentially holding temporary data on disk.
...@@ -317,6 +347,7 @@ public abstract class CommonsFileUploadSupport { ...@@ -317,6 +347,7 @@ public abstract class CommonsFileUploadSupport {
public MultipartParsingResult(MultiValueMap<String, MultipartFile> mpFiles, public MultipartParsingResult(MultiValueMap<String, MultipartFile> mpFiles,
Map<String, String[]> mpParams, Map<String, String> mpParamContentTypes) { Map<String, String[]> mpParams, Map<String, String> mpParamContentTypes) {
this.multipartFiles = mpFiles; this.multipartFiles = mpFiles;
this.multipartParameters = mpParams; this.multipartParameters = mpParams;
this.multipartParameterContentTypes = mpParamContentTypes; this.multipartParameterContentTypes = mpParamContentTypes;
......
/* /*
* Copyright 2002-2015 the original author or authors. * Copyright 2002-2016 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.
...@@ -47,6 +47,8 @@ public class CommonsMultipartFile implements MultipartFile, Serializable { ...@@ -47,6 +47,8 @@ public class CommonsMultipartFile implements MultipartFile, Serializable {
private final long size; private final long size;
private boolean preserveFilename = false;
/** /**
* Create an instance wrapping the given FileItem. * Create an instance wrapping the given FileItem.
...@@ -66,6 +68,21 @@ public class CommonsMultipartFile implements MultipartFile, Serializable { ...@@ -66,6 +68,21 @@ public class CommonsMultipartFile implements MultipartFile, Serializable {
return this.fileItem; return this.fileItem;
} }
/**
* Set whether to preserve the filename as sent by the client, not stripping off
* path information in {@link CommonsMultipartFile#getOriginalFilename()}.
* <p>Default is "false", stripping off path information that may prefix the
* actual filename e.g. from Opera. Switch this to "true" for preserving the
* client-specified filename as-is, including potential path separators.
* @since 4.3.5
* @see #getOriginalFilename()
* @see CommonsMultipartResolver#setPreserveFilename(boolean)
*/
public void setPreserveFilename(boolean preserveFilename) {
this.preserveFilename = preserveFilename;
}
@Override @Override
public String getName() { public String getName() {
return this.fileItem.getFieldName(); return this.fileItem.getFieldName();
...@@ -78,6 +95,10 @@ public class CommonsMultipartFile implements MultipartFile, Serializable { ...@@ -78,6 +95,10 @@ public class CommonsMultipartFile implements MultipartFile, Serializable {
// Should never happen. // Should never happen.
return ""; return "";
} }
if (this.preserveFilename) {
// Do not try to strip off a path...
return filename;
}
// Check for Unix-style path // Check for Unix-style path
int unixSep = filename.lastIndexOf("/"); int unixSep = filename.lastIndexOf("/");
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册