商品管理模塊涉及圖片上傳需求,第 13 戰基於 Struts 2 文件上傳攔截器,構建可復用的 FileUpload 組件,實現多文件類型驗證、UUID 隨機重命名、指定目錄存儲、臨時文件自動清理的完整鏈路。
Struts 2 約定三屬性自動注入:
public class FileImage {
private File file; // 上傳文件臨時路徑
private String contentType; // MIME 類型
private String filename; // 原始文件名
// Setter 命名約定:set + 屬性名首字母大寫
public void setUpload(File file) { this.file = file; }
public void setUploadContentType(String contentType) { this.contentType = contentType; }
public void setUploadFileName(String filename) { this.filename = filename; }
// Getter 省略
}
前端表單 <input type="file" name="fileImage.upload"/> 對應 setUpload。
public interface FileUpload {
String uploadFile(FileImage fileImage); // 返回新文件名
}
@Component("fileUpload")
public class FileUploadUtil implements FileUpload {
private String filePath; // 存儲根目錄,從 properties 注入
@Value("#{prop.filePath}")
public void setFilePath(String filePath) { this.filePath = filePath; }
// 1. 獲取擴展名
private String getFileExt(String fileName) {
return FilenameUtils.getExtension(fileName); // Apache Commons IO
}
// 2. UUID 隨機文件名
private String newFileName(String fileName) {
return UUID.randomUUID().toString() + "." + getFileExt(fileName);
}
@Override
public String uploadFile(FileImage fileImage) {
String newName = newFileName(fileImage.getFilename());
try {
FileUtil.copyFile(fileImage.getFile(), new File(filePath, newName));
return newName;
} catch (Exception e) {
throw new RuntimeException(e);
} finally {
fileImage.getFile().delete(); // 清理臨時文件
}
}
}
@Controller("baseAction")
@Scope("prototype")
public class BaseAction<T> extends ActionSupport implements ModelDriven<T> {
protected FileImage fileImage;
@Resource protected FileUpload fileUpload;
// Getter/Setter 省略
}
所有需要上傳功能的 Action 繼承 BaseAction 即可直接使用。
public void save() throws Exception {
String pic = fileUpload.uploadFile(fileImage);
model.setPic(pic);
model.setDate(new Date());
productService.save(model);
}
public void update() throws Exception {
String pic = fileUpload.uploadFile(fileImage);
model.setPic(pic);
model.setDate(new Date());
productService.update(model);
}
業務邏輯零侵入,上傳細節完全屏蔽。
$.extend($.fn.validatebox.defaults.rules, {
format: {
validator: function(value, param) {
var ext = value.substring(value.lastIndexOf('.') + 1);
return param[0].split(",").includes(ext);
},
message: '文件後綴必須為: {0}'
}
});
$("input[name='fileImage.upload']").validatebox({
required: true,
validType: "format['gif,jpg,jpeg,png']"
});
自定義驗證規則 format,僅允許圖片格式,提升用戶體驗與服務器安全。
struts.xml 無需額外配置,文件上傳攔截器默認在 defaultStack 中struts.multipart.maxSize=2097152(2MB,可調)組件化封裝讓文件上傳從「業務雜項」變為「基礎設施」,新增上傳需求只需注入 FileUpload 即可復用,體現了單一職責與開閉原則。