CommonsMultipartFile.getOriginalFilename() can be configured to preserve header-specified filename as-is
Issue: SPR-14613
This commit is contained in:
parent
39739b3157
commit
aa29495d1d
|
|
@ -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");
|
* 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 {
|
||||||
* 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 {
|
||||||
|
|
||||||
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 {
|
||||||
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 {
|
||||||
}
|
}
|
||||||
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 {
|
||||||
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 {
|
||||||
|
|
||||||
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;
|
||||||
|
|
|
||||||
|
|
@ -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");
|
* 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 {
|
||||||
|
|
||||||
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 {
|
||||||
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 {
|
||||||
// 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("/");
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue