ActFramework – 如何用不到 70 行 Java 程式碼擼一個文件上傳管理服務
- 2020 年 3 月 9 日
- 筆記
ActFramework 1.8.32 發布了(歡迎圍觀新聞), 這個版本中我們優化了 storage service 部分, 文件上傳管理程式碼變得更加簡潔. 下面我們來看看如果用不到 70 行 Java 程式碼來實現一個完整的上傳文件管理服務.
定義上傳文件對象:
@Entity(name="file") public class UploadFile { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) public Integer id; public String description; /** * key to fetch the file from {@link org.osgl.storage.IStorageService} */ public String ssKey; }
文件上傳服務
@UrlContext("fm") public class FileManager extends Controller.Util { @Inject private IStorageService ss; // 注入存儲服務實例 @Inject JPADao<Integer, UploadFile> dao; // 注入 Dao /** * 文件上傳服務頁面 - 使用模板生成頁面 */ @GetAction public void home() { Iterable<UploadFile> files = dao.findAll(); renderTemplate("/fm.html", files); } /** * 上傳一個文件 * @param file 上傳文件 */ @PostAction("upload") public void upload(ISObject file, String description) { String key = ss.getKey(); // 生成一個 unique 的 key ss.put(key, file); // 將文件存入存儲服務 UploadFile uf = new UploadFile(); // 生成一個上傳數據記錄 uf.ssKey = key; uf.description = description; dao.save(uf); // 將上傳數據記錄存入本地資料庫 redirect("/fm"); // 重定向到文件上傳服務頁面 } /** * 下載文件 * @param __path URL 路徑里在 download 之後的部分, 這是獲得文件存儲的 key * @return 從存儲系統中獲得的文件. */ @GetAction("download/...") // 注意 ... 的寫法, 這樣可以將 `...` 部分放入 `__path` 中 public ISObject download(String __path) { return ss.get(__path); } /** * 刪除一個上傳文件 */ @DeleteAction("{uploadFile}") public void delete(@DbBind @NotNull UploadFile uploadFile) { ss.remove(uploadFile.ssKey); // 從存儲系統中刪除 dao.delete(uploadFile); // 從本地資料庫中刪除 } }
文件上傳服務頁面程式碼
<!DOCTYPE html> <html lang="en"> <head> <title>File Manager Home</title> <style> label { display: inline-block; width: 200px; text-align: right; padding: 5px 15px; } input { padding: 5px 15px; } #submit { margin-left: 249px; } </style> <script src="/~/asset/js/jquery.js"></script> <script src="/~/asset/js/jquery.ext.js"></script> </head> <body> <h1>Simple File Manager</h1> <h3>Upload new file</h3> <form method="post" action="/fm/upload" enctype="multipart/form-data"> <div> <label for="description">Description</label> <input type="text" name="description" id="description" style="margin-left: 15px"> </div> <div> <label for="file">Select file</label> <input id="file" name="file" type="file"> </div> <div> <button id="submit" type="submit">Submit</button> </div> </form> @args Iterable<demo.act.fm.UploadFile> files @if(files) { <h3>Upload file list</h3> <ul id="file-list"> @for(files) { <li> <a href="/fm/download/@_.ssKey" target="_blank">@_.description</a> <button type="button" class="btn_delete" data-id="@_.id">Delete</button> </li> } </ul> <script> $('.btn_delete').on('click', function() { $.delete('/fm/' + $(this).data('id'), function(){ window.location.reload() }) }) </script> } </body> </html>
配置存儲服務
銳利的看官可能要問了, 上面程式碼裡面的 private IStorageService ss
是個什麼東東. 這個是由 osgl-storage 庫提供的存儲服務. 開發人員可以根據需要對該實例進行配置
下面是在本地文件系統上的配置:
ss.impl=act.storage.FileSystemStoragePlugin ss.storage.fs.home.dir=upload # 這將會在項目目錄中創建一個 upload 子目錄
osgl-storage 的一個優勢是你可以隨時將文件存儲從本地文件系統切換到雲端存儲, 比如下面就是一個基於 AWS S3 bucket 的配置:
ss.impl=act.storage.S3StoragePlugin ss.storage.s3.keyId={key id} ss.storage.s3.keySecret={key secret} ss.storage.s3.bucket={s3 bucket name} ss.storage.s3.get.noGet=false ss.storage.s3.defStorageClass=standard ss.storage.s3.maxErrorRetry=5 ss.storage.s3.tcpKeepAlive=true ss.storage.s3.maxConnection=30
osgl-storage 還支援更多的雲端服務, 包括 Azure 的 Blob 系統和七牛雲.
運行演示:

點擊 A PDF file

總結
本文講述了如何在 ActFramework 中用短短的不到 70 行 Java 程式碼來實現一個文件上傳服務管理.
看官: 口說無憑, 你說不到 70 行就不到 70 行啊?
老碼農: 元芳, 上證據:

@紅薯 完整項目已經提交 Gitee: https://gitee.com/greenlaw110/file-manager