Servlet getSubmittedFileName 从路径中删除斜杠
Servlet getSubmittedFileName removes slashes from path
我使用 file
类型的 input
元素通过 html 表单上传文件。
如果文件是在 Internet Explorer 上上传的,路径包含在文件名中。
获取文件名如下:
Collection<Part> parts = request.getParts();
for (Part part: parts) {
if (part.getName().equals(inputName)) {
System.out.println(part.getSubmittedFileName());
}
}
导致文件的文件名(在本例中为完整路径,因为它是通过 ie 上传的)显示时没有斜线(例如:如果路径为 c://directory/file_name
,则打印为 c:directoryfile_name
)
如果我自己用 part.getHeader("Content-Disposition")
得到 header 然后我看到斜杠存在。
这是怎么回事?我怎样才能修复它,使斜杠位于 getSubmittedFileName()
?
谢谢
这似乎是 Internet Explorer 的错误:
此外,Internet Explorer 对本地(Intranet)站点的默认设置发送完整路径,而 Internet 站点的默认行为是不显示整个路径。因此,这只是本地(内联网)使用的问题,对我来说无关紧要。
在 org.apache.catalina.core.ApplicationPart
中扩展他们的 self-answer, this misbehavior on Internet Explorer's part turns out to be worsened by Tomcat versions newer than 8.0.33, when it's (trying to) conform to RFC 6266。下面是 Tomcat 代码的相关部分,它从 Internet Explorer 提交的文件名中删除了反斜杠:
/*
* Adapted from FileUploadBase.getFileName()
*/
@Override
public String getSubmittedFileName() {
(...)
// RFC 6266. This is either a token or a quoted-string
if (fileName.indexOf('\') > -1) {
// This is a quoted-string
fileName = HttpParser.unquote(fileName.trim());
} else {
// This is a token
fileName = fileName.trim();
}
(...)
return fileName;
}
因此,为了避免这种情况发生,您需要自己评估 part.getHeader("Content-Disposition")
。首先,从 header 中提取 filename
字段,例如:
filename = header.replaceFirst("(?i)^.*filename=\"?([^\"]+)[\";]?.*$", ""));
然后您需要 trim 到文件名,删除其他路径元素。这里有很多选项:
- 再次使用正则表达式:
filename = filename.replaceFirst("^.+\\([^\\]+)$", "");
- 使用引用的 Apache Commons Fileupload 的
FileUploadBase.getFileName(...)
- 使用Apache Commons IO的
FilenameUtils.getName(...)
默认情况下,Internet Explorer 会在上传文件时发送完整路径。您可以禁用完整路径设置:
Internet 选项 > 安全 > Internet/本地 Intranet > 自定义级别 > 查找 "Include local directory path when uploading files to server” and set it to “disable".
我使用 file
类型的 input
元素通过 html 表单上传文件。
如果文件是在 Internet Explorer 上上传的,路径包含在文件名中。
获取文件名如下:
Collection<Part> parts = request.getParts();
for (Part part: parts) {
if (part.getName().equals(inputName)) {
System.out.println(part.getSubmittedFileName());
}
}
导致文件的文件名(在本例中为完整路径,因为它是通过 ie 上传的)显示时没有斜线(例如:如果路径为 c://directory/file_name
,则打印为 c:directoryfile_name
)
如果我自己用 part.getHeader("Content-Disposition")
得到 header 然后我看到斜杠存在。
这是怎么回事?我怎样才能修复它,使斜杠位于 getSubmittedFileName()
?
谢谢
这似乎是 Internet Explorer 的错误:
此外,Internet Explorer 对本地(Intranet)站点的默认设置发送完整路径,而 Internet 站点的默认行为是不显示整个路径。因此,这只是本地(内联网)使用的问题,对我来说无关紧要。
在 org.apache.catalina.core.ApplicationPart
中扩展他们的 self-answer, this misbehavior on Internet Explorer's part turns out to be worsened by Tomcat versions newer than 8.0.33, when it's (trying to) conform to RFC 6266。下面是 Tomcat 代码的相关部分,它从 Internet Explorer 提交的文件名中删除了反斜杠:
/*
* Adapted from FileUploadBase.getFileName()
*/
@Override
public String getSubmittedFileName() {
(...)
// RFC 6266. This is either a token or a quoted-string
if (fileName.indexOf('\') > -1) {
// This is a quoted-string
fileName = HttpParser.unquote(fileName.trim());
} else {
// This is a token
fileName = fileName.trim();
}
(...)
return fileName;
}
因此,为了避免这种情况发生,您需要自己评估 part.getHeader("Content-Disposition")
。首先,从 header 中提取 filename
字段,例如:
filename = header.replaceFirst("(?i)^.*filename=\"?([^\"]+)[\";]?.*$", ""));
然后您需要 trim 到文件名,删除其他路径元素。这里有很多选项:
- 再次使用正则表达式:
filename = filename.replaceFirst("^.+\\([^\\]+)$", "");
- 使用引用的 Apache Commons Fileupload 的
FileUploadBase.getFileName(...)
- 使用Apache Commons IO的
FilenameUtils.getName(...)
默认情况下,Internet Explorer 会在上传文件时发送完整路径。您可以禁用完整路径设置:
Internet 选项 > 安全 > Internet/本地 Intranet > 自定义级别 > 查找 "Include local directory path when uploading files to server” and set it to “disable".