diff --git a/spring-web/src/main/java/org/springframework/web/multipart/MultipartFile.java b/spring-web/src/main/java/org/springframework/web/multipart/MultipartFile.java index 6097bd39ab9..f5674104c15 100644 --- a/spring-web/src/main/java/org/springframework/web/multipart/MultipartFile.java +++ b/spring-web/src/main/java/org/springframework/web/multipart/MultipartFile.java @@ -1,5 +1,5 @@ /* - * 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"); * you may not use this file except in compliance with the License. @@ -48,9 +48,8 @@ public interface MultipartFile extends InputStreamSource { * Return the original filename in the client's filesystem. *
This may contain path information depending on the browser used, * but it typically will not with any other than Opera. - * @return the original filename, or the empty String if no file - * has been chosen in the multipart form, or {@code null} - * if not defined or not available + * @return the original filename, or the empty String if no file has been chosen + * in the multipart form, or {@code null} if not defined or not available */ String getOriginalFilename(); diff --git a/spring-web/src/main/java/org/springframework/web/multipart/commons/CommonsFileUploadSupport.java b/spring-web/src/main/java/org/springframework/web/multipart/commons/CommonsFileUploadSupport.java index e2339b58707..2bafb378dea 100644 --- a/spring-web/src/main/java/org/springframework/web/multipart/commons/CommonsFileUploadSupport.java +++ b/spring-web/src/main/java/org/springframework/web/multipart/commons/CommonsFileUploadSupport.java @@ -62,6 +62,8 @@ public abstract class CommonsFileUploadSupport { private boolean uploadTempDirSpecified = false; + private boolean preserveFilename = false; + /** * Instantiate a new CommonsFileUploadSupport with its @@ -168,6 +170,20 @@ public abstract class CommonsFileUploadSupport { return this.uploadTempDirSpecified; } + /** + * Set whether to preserve the filename as sent by the client, not stripping off + * path information in {@link CommonsMultipartFile#getOriginalFilename()}. + *
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.
@@ -259,7 +275,7 @@ public abstract class CommonsFileUploadSupport {
}
else {
// multipart file field
- CommonsMultipartFile file = new CommonsMultipartFile(fileItem);
+ CommonsMultipartFile file = createMultipartFile(fileItem);
multipartFiles.add(file.getName(), file);
if (logger.isDebugEnabled()) {
logger.debug("Found multipart file [" + file.getName() + "] of size " + file.getSize() +
@@ -271,6 +287,20 @@ public abstract class CommonsFileUploadSupport {
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,
* potentially holding temporary data on disk.
@@ -317,6 +347,7 @@ public abstract class CommonsFileUploadSupport {
public MultipartParsingResult(MultiValueMap 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
public String getName() {
return this.fileItem.getFieldName();
@@ -78,6 +95,10 @@ public class CommonsMultipartFile implements MultipartFile, Serializable {
// Should never happen.
return "";
}
+ if (this.preserveFilename) {
+ // Do not try to strip off a path...
+ return filename;
+ }
// Check for Unix-style path
int unixSep = filename.lastIndexOf("/");