如何優雅的文件上傳

前言:java

  寫給java入門的人,寫給在職須要提升廣度的人。web

  你須要有以下知識:json

    你要知道什麼是數據流,瀏覽器到底都能幹什麼,java有哪些IO相關的操做類。servlet與運行服務器環境(tomcat,weblogic等)有什麼關係。瀏覽器

  若是你沒有上述知識點,不要緊,儘可能往下看,若是你知識爲了工做須要。tomcat

  我會按照以下格式書寫:服務器

    他們的實現是根據什麼實現的,依賴什麼,如何操做,最後會描述如何創建以個完整的項目中共通的文件上傳功能。網絡


 

  咱們的目標:session

    (沒有蛀牙?)對於任何一條數據,應該有一個對應文件的擴展字段,而不是一套業務一套文件上傳,換言之,一個文件上傳的功能,須要適用於項目中全部的文件上傳,如圖:  blog

    

 

   這是咱們認爲文件上傳的一個簡單的過程。事件

   第一步,咱們要在頁面上直接上傳文件到服務器,緣由是某些文件須要及時預覽一下,又或者爲了提升客戶體驗,有時候咱們會在一個表單中添加附件上牀,更多的作法是,當用戶選擇一個文件以後,旁邊有一個上傳按鈕,點擊上傳按鈕,開始出現進度條,當進度條完成以後,客戶開始繼續填寫表單,然而對於web開發,實時顯示上傳進度是很是不簡單的事情,好比你可能須要flash的幫助,然而H5的世界說,flash正在被人類抨擊。so,你肯讓最終顯示的是一個等待界面而已,無論如何,咱們應該讓用戶先看到文件上傳的等待,而不是最終一併提交,而且上傳,由於這個過程頗有可能出現問題,好比網絡錯誤,服務器BUG,用戶誤操做等.....

  由於有了預先上傳這個過程,最後用戶可能獲取到這個文件在服務器上的數據ID,便可進行提交,甚至你可讓用戶填寫表單到一半的時候繼續填寫,不用再次上傳附件。

  一個典型的demo,就是aliyun 的備案(好吧,你說是萬網的我也無話可說),當你的掃描件上傳以後,關掉頁面,下次進來是不須要你再次上傳的,由於這已是屬於你的資源。


 

  第二步,咱們須要根據業務來控制數據在服務器的位置,以及其餘屬性,一般,咱們會把文件第一次上傳到服務器上的一個臨時存儲目錄,緣由以下:

      1.你不能直接肯定這個文件須要用在什麼地方,由於你的文件上傳多是公用的,申報須要,註冊須要,甚至後臺管理也須要,因此你要有一個臨時目錄,什麼文件都方進去,等知道這個文件是幹嗎的以後,再移動出去。就比如新兵蛋子跟後期篩選同樣。

      2.你可能最終不須要用這個文件,他是個垃圾,他不過是一些傻逼浪蕩的用戶上傳的垃圾附件,上傳完了,就完了,根本沒提交表單(別罵人家,你也幹過。)

      3.若是你的上傳是共用的,那麼若是你一開始就把文件上傳到目標文件夾下面,或者其餘什麼文件系統下面,會很麻煩。(不解釋)


 

  第三步,你須要讓用戶操做這個文件了,一般,這個文件上傳以後會返回客戶端一個文件ID,最終用戶只是提交了這樣一個文件ID,並非提交表單的時候同時上傳附件。so,問題來了,萬一上傳的附件錯了,從新上傳怎麼辦?萬一上傳的附件。。。問題太多,咱們寫個FAQ

      FAQ:

    • 上傳錯了,又點上傳,怎麼辦?  
      服務器在每一次接收上傳的時候,至少要保存【業務標記】【操做用戶】【文件狀態】,若是在當前業務下,該用戶已經擁有一個臨時文件,那麼應該刪掉本來文件,上傳新的文件,使用以前的附件ID返回客戶端;若是沒有,那麼直接上傳新附件,而且生成附件數據ID,返回給客戶端。保證用戶在一個業務下只有一個臨時文件。這裏說的業務一般是一個表單字段,甚至是一個字段中的一個節點,好比註冊用戶,須要身份證反正面上傳,這個時候可能反正面的附件ID,在同一個字段,如「cid_ufile_id_json」,他多是一個json格式的字段,用來存儲用戶上傳的身份驗證附件。

    • 上傳後沒有使用,直接關掉瀏覽器了?  
            首先這不是個事,由於一般咱們的項目,都會監聽session關閉事件(多嘴一句,並非瀏覽器關掉就會session銷燬,這須要瀏覽器想服務器發送通知的,若是直接斷電,頗有可能沒有這個通知。)你須要在session關閉的時候去清理session給服務器帶來的垃圾。就好像你家客人走了以後你要收拾衛生同樣。(這跟你揹着你老婆找野女人不同!!!!)若是是斷電呢,不能及時清理,或者服務器就會有垃圾,無論什麼緣由,服務器頗有可能存在一些「你覺得」清理掉的垃圾,OK,作個corn定時清理下吧,這就是爲何剛纔說每一個文件數據都要有文件狀態,他至少要有幾種狀態【臨時態】,【完成態】,【垃圾態】。
            當用戶session關閉,或者上傳新的附件以後,不要直接去清理剛纔的垃圾,你能夠試着把他標記爲【垃圾】,晚上服務器作清理(就好像咱們早上拉大便同樣)的時候進行清理,這個好像叫什麼來的?(掃描-標記,字眼熟悉嗎?看看think in java,題外話,這就是看這些書有啥用,記住他的實現機制一點用沒有,然而拿出來用在別的地方纔是真的)。
    • 我怎麼讓客戶端顯示等待畫面?
      面對這種問題,我只能說「湊,你想怎麼弄我怎麼知道,看心情」
    • 垃圾

 

 

 

 

 

 

 

 

 

 

 

 

 

待續

相關文章
相關標籤/搜索