ActFramework – 如何用不到 70 行 Java 代碼擼一個文件上傳管理服務

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>    &nbsp;            <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