在 Java 的 Web 后端(如 Spring Boot)中,限制文件上传类型通常通过判断 MultipartFile
的 Content-Type(MIME 类型)或文件扩展名(后缀名)来实现。
一、限制文件类型的常见做法
方法 1:根据 MultipartFile.getContentType()
判断 MIME 类型
java
public void validateFileType(MultipartFile file) {
List<String> allowedTypes = List.of("image/png", "image/jpeg", "application/pdf");
String contentType = file.getContentType();
if (!allowedTypes.contains(contentType)) {
throw new IllegalArgumentException("不支持的文件类型: " + contentType);
}
}
⚠️ 注意:浏览器伪造 Content-Type 是可能的,因此推荐再结合后缀判断或做文件头检查(Magic Number)
方法 2:根据文件名后缀判断类型(不安全但能挡住大部分无意误传)
java
public void validateExtension(MultipartFile file) {
String filename = file.getOriginalFilename().toLowerCase();
List<String> allowedExtensions = List.of(".jpg", ".jpeg", ".png", ".pdf");
if (allowedExtensions.stream().noneMatch(filename::endsWith)) {
throw new IllegalArgumentException("不支持的文件后缀");
}
}
方法 3:安全性更高 ------ 检查文件头(Magic Number)
每种文件格式都有"魔数"(Magic Number),可使用第三方库如 Apache Tika 、JMimeMagic 、FileTypeDetector 来检测。
使用 Apache Tika 示例:
java
import org.apache.tika.Tika;
public void validateByTika(MultipartFile file) throws IOException {
Tika tika = new Tika();
String detectedType = tika.detect(file.getInputStream());
List<String> allowedTypes = List.of("image/jpeg", "image/png", "application/pdf");
if (!allowedTypes.contains(detectedType)) {
throw new IllegalArgumentException("文件类型不合法: " + detectedType);
}
}
二、实战应用整合到上传接口中(Spring Boot)
java
@PostMapping("/upload")
public ResponseEntity<?> upload(@RequestParam MultipartFile file) throws IOException {
validateFileType(file); // 判断 MIME 类型
validateExtension(file); // 判断文件名后缀
validateByTika(file); // 推荐:更准确安全
// 保存逻辑略...
return ResponseEntity.ok("上传成功");
}
三、可配置化(支持配置文件控制允许类型)
application.yml
yaml
file:
allowed-types:
- image/png
- image/jpeg
- application/pdf
配置类注入:
java
@ConfigurationProperties(prefix = "file")
@Data
public class FileConfig {
private List<String> allowedTypes;
}
再注入 FileConfig
来校验:
java
@Autowired
private FileConfig fileConfig;
if (!fileConfig.getAllowedTypes().contains(contentType)) {
throw new IllegalArgumentException("不支持的文件类型");
}
四、其他建议
场景 | 建议 |
---|---|
前端限制文件选择 | <input accept="image/*"> |
后端强校验必不可少 | 防止绕过前端 |
存储前统一重命名处理 | 防止恶意脚本如 xx.jpg.exe |
加白名单优于黑名单 | 拒绝所有不认识的类型 |