发布于2026-07-09 阅读(0)
扫一扫,手机访问
必须先标准化文件名再校验后缀——提取纯文件名、去除空格、转小写、确保点号存在且非开头,最后用白名单集合比对真实后缀。

直接用 String.endsWith() 去判断文件后缀是否在白名单里?这事儿,还真不靠谱。它根本搞不定大小写差异、多余空格、路径干扰乃至点号缺失这些问题。要想验证得稳,必须先给文件名做个“大扫除”——标准化,再比对。
用户上传过来的文件名,很可能带着一长串路径,比如 "C:\Users\a\photo.JPG",或者前后还藏着空格。直接拿来就用,大概率要翻车。正确的步骤是:先用 FilenameUtils.getName()(Apache Commons IO 里就有)或者 new File(path).getName() 把纯文件名提出来,紧接着调用 trim() 把前后空白字符清干净。千万别偷懒,直接拿原始文件名去调 endsWith()。
endsWith() 默认是区分大小写的,但常见的后缀,像 "JPG"、"jpg"、"Jpg",都应该是合法值。所以,绕开这个坑的办法很简单:把文件名和白名单里的后缀,全部转成小写再做比对。比如,用 fileName.toLowerCase().endsWith(".pdf"),同时白名单也统一存储为小写字符串,像 Set.of(".pdf", ".png", ".jpg") 这样。
这里还有一个很容易忽略的陷阱:"report.pdf".endsWith(".pdf") 当然没问题,但 "my.pdf.backup".endsWith(".pdf") 也会返回 true——这显然不是我们想要的“以 .pdf 结尾”的意思。更稳妥的做法是:先用 String.lastIndexOf('.') > 0 确保点号存在且不在开头,然后再用 String.substring() 把最后一段后缀提取出来,拿到白名单里去查。或者,直接上正则:fileName.toLowerCase().matches(".*\.((pdf|png|jpg|jpeg|txt))$"),一步到位。
把这些要点串起来,一个能打的验证逻辑就出来了:
String cleanName = FilenameUtils.getName(fileName).trim();
int lastDot = cleanName.lastIndexOf('.');
if (lastDot <= 0) return false;
String ext = cleanName.substring(lastDot).toLowerCase(); // 包含点号,如 ".jpg"
Set whitelist = Set.of(".pdf", ".png", ".jpg", ".jpeg", ".txt");
return whitelist.contains(ext);
如果项目里不方便引入 Commons IO,也可以用 cleanName.substring(cleanName.lastIndexOf(File.separatorChar) + 1) 来替代 FilenameUtils.getName(),效果是一样的。
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
正版软件
正版软件
正版软件
正版软件
正版软件
1
2
3
7
8