@Controller("PictureAction")
@Scope("prototype")
public class PictureAction extends ActionSupport {
private File image; // 上傳文件(Struts2 自動注入)
private String imageFileName; // 原始文件名
private String imageContentType; // MIME 類型
// ... 其他字段、getter/setter
public String uploadPicture() throws IOException {
String s = UUID.randomUUID().toString(); // 1. 生成唯一文件名主體
String lastName = imageFileName.substring(imageFileName.lastIndexOf(".") + 1); // 2. 獲取擴展名
String name = s + "." + lastName; // 3. 組合新文件名
String realpath = ServletActionContext.getServletContext().getRealPath("/upload"); // 4. 獲取服務器物理路徑
File saveDir = new File(realpath);
if (!saveDir.exists()) saveDir.mkdirs(); // 5. 確保目錄存在
File saveFile = new File(saveDir, name); // 6. 目標文件對象
FileUtils.copyFile(image, saveFile); // 7. 核心:將臨時文件複製到目標路徑
String imagePath = "/sDemo/upload/" + name; // 8. 構建相對訪問路徑
Picture picture = new Picture(); // 9. 封裝業務對象
picture.setUserId(user.getId());
picture.setUserName(user.getUsername());
picture.setPictureUrl(imagePath);
ser.insertPicture(picture); // 10. 持久化到數據庫
return "upload"; // 對應 struts.xml 中的 result
}
}
enctype="multipart/form-data" 表單上傳的文件保存到臨時目錄,並將 File、String fileName、String contentType 三屬性自動注入 Action 同名字段(image, imageFileName, imageContentType)。UUID + 原擴展名,避免同名覆蓋、特殊字符問題。getRealPath("/upload") 獲取 Web 應用部署路徑下的 upload 目錄絕對路徑。mkdirs() 遞歸創建,防止首次部署目錄不存在報錯。FileUtils.copyFile(Apache Commons IO)高效複製流,比手寫 InputStream/OutputStream 更健壯。@Controller("MusicAction")
@Scope("prototype")
public class MusicAction extends ActionSupport {
private File musicFile; // 上傳的音樂文件
private String musicFileName;
private String musicContentType;
// 新增:歌名、歌手、時長、封面等業務字段
private String title;
private String artist;
private Integer duration;
// ... getter/setter
public String uploadMusic() throws IOException {
// 1-7 步驟完全同圖片上傳,僅變量名改為 musicFile 等
String s = UUID.randomUUID().toString();
String ext = musicFileName.substring(musicFileName.lastIndexOf(".") + 1);
String name = s + "." + ext;
String realpath = ServletActionContext.getServletContext().getRealPath("/upload/music");
File saveDir = new File(realpath);
if (!saveDir.exists()) saveDir.mkdirs();
File saveFile = new File(saveDir, name);
FileUtils.copyFile(musicFile, saveFile);
String musicPath = "/sDemo/upload/music/" + name;
// 8. 封裝音樂業務對象
Music music = new Music();
music.setTitle(title);
music.setArtist(artist);
music.setDuration(duration);
music.setMusicUrl(musicPath);
music.setUploader(user.getUsername());
musicService.insertMusic(music); // 注入 MusicService
return "upload";
}
}
<form action="music_uploadMusic.action" method="post" enctype="multipart/form-data">
<input type="file" name="musicFile" accept="audio/*" />
<input type="text" name="title" placeholder="歌名" />
<input type="text" name="artist" placeholder="歌手" />
<input type="number" name="duration" placeholder="時長(秒)" />
<button type="submit">上傳</button>
</form>
musicContentType 以 audio/ 開頭,ext 在 mp3,wav,ogg,flac 白名單中。jaudiotagger 或 ffmpeg 解析 ID3 標籤(標題、歌手、專輯、封面),自動填充字段,減少用戶輸入。HTML5 <audio> 或 Audio.js、Howler.js 播放,URL 指向 musicPath。**文件上傳核心邏輯通用**:接收 → 重命名 → 存儲 → 記錄元數據。音樂上傳只需將「圖片」替換為「音頻」,擴展業務字段(標題、歌手、時長),並針對音頻特性添加類型校驗、異步上傳、元數據提取等增強功能。Struts2 的自動注入機制讓遷移極為簡單。