<b>閱讀目錄</b>
<a href="http://www.cnblogs.com/java-class/p/4798204.html#_label0">1. 背景處理的java 方法</a>
<a href="http://www.cnblogs.com/java-class/p/4798204.html#_label1">2. sping mvc架構實作下載下傳遇到的“坑” </a>
<a href="http://www.cnblogs.com/java-class/p/4798204.html#_label2">3. 生成zip包成功,在前端跳轉下載下傳頁面</a>
<a href="http://www.cnblogs.com/java-class/p/4798204.html#_label3">4. 流在不同web容器的妥善處理</a>
該部落格記錄java web項目将word打包zip并提供下載下傳功能的實作和其中遇到的坑,友善後續自己的檢視的參照。
項目架構背景: jquery + bootstarp + springmvc
實作思路:首先将所有的word生成到uploadword目錄下面,然後指定被壓縮的檔案夾為uploadword,并将生成的zip指定到uploadzip檔案夾(在配置目錄路徑的時候記得注意幾種不同的伺服器路徑寫法),當時也考慮過在同一個檔案夾下面生成word ,然後壓縮為一個 zip,但很可惜壓縮出來的檔案,總是莫名奇妙的疊代了很多相同的壓縮包,可能是将生成的壓縮包,也作為了檔案不斷循環在壓縮,是以果斷分開檔案夾。在将檔案循環壓縮入壓縮包中後,删除原uploadword檔案夾中的檔案,是以當程式正确執行完後,伺服器中的uploadword這個檔案夾都是清空的(畢竟這個功能是權限比較大的管理者進行的操作,有且隻有一個超級管理者,現在還沒有考慮多使用者同時并發生成壓縮包的情況)
壓縮方法上代碼:
可能以前做過這功能朋友的會産生疑問,為什麼要跳轉到前端的下載下傳頁面去,不直接在後端生成下載下傳流,放入httpservletresponse對象,傳回給前端直接彈出下載下傳框。當時我也是這樣想的,但事實總是很殘酷。
原來實作的代碼是這樣的:
加入背景這段代碼後,并沒有達到我想要的效果,可能是我對spring mvc了解的不夠,還請各位看官賜教。
既然後端不能直接傳回下載下傳流,并彈出下載下傳框,在前端接受傳回的下載下傳所需(zippath,zipfilename,servername)的關鍵參數,跳轉到下載下傳jsp頁面。
相應跳轉(跳轉方式多種多樣,這裡采用表單送出到download.jsp頁面):
下載下傳頁面:
剛開始程式在tomcat 上跑時,總出現報錯:
org.apache.jasper.jasperexception: java.lang.illegalstateexception: getoutputstream() has already been called for this response
百度一番,發現body()的作用是儲存目前的out對象,并更新pagecontext中page範圍内out對象。jsp容器在處理完成請求後會調用releasepageconter方法釋放所有的
pagecontestobject,并且同時調用getwriter方法。由于getwriter方法與在jsp頁面中使用流相關的getoutputstream方法沖突,解決方法也很簡單,重新生成pagecontext中page範圍内out對象。
在代碼最後添加 :
out.clear();
out = pagecontext.pushbody();
好了,自己本地測試不會報錯了,将項目打包到weblogic,出現報錯:
servlet failed with exception java.lang.illegalstateexception: response already committed at weblogic.servlet.internal.servletresponseimpl.objectifcommitted(servletresponseimpl.java:1602) ......
雖然不影響功能的使用,還是看着不爽,百度一番,發現是自己添加的上兩句的的原因(tomcat 和 weblogic 容器的差異性,應該是weblogic并不會調用releasepageconter方法釋放所有的pagecontestobject)
這就是下載下傳頁面出現這幾行代碼的原因:
如果能判斷是在哪個web容器中,然後進行特殊判斷就好了,同樣是百度一番,發現 portal-kernel.jar中的類serverdetector.java 能完美判斷多達10種以上的容器類型,但我又不想将這個jar 引入到項目中(俺就用一個類,引一個jar,太虧了),然後jd-gui反編譯,單獨拉出這個類,修改修改添加到我的項目中。
上代碼(修改完的代碼,不依賴任何類,可以拿來直接用):
ok ,到此完美解決了 spring mvc 中zip包下載下傳、避開後端直接寫入前端下載下傳流、妥善解決各web容器的差異性。
如果,您認為閱讀這篇部落格讓您有些收獲,不妨點選一下右下角的【推薦】
如果,您希望更容易地發現我的新部落格,不妨點選一下左下角的【關注我】
如果,您對我的部落格内容感興趣,請繼續關注我的後續部落格,我是【orson】
本文版權歸作者和部落格園共有,歡迎轉載,但未經作者同意必須保留此段 聲明,且在文章頁面明顯位置給出原文連接配接,否則保留追究法律責任的權利。
轉載:http://www.cnblogs.com/java-class/p/4798204.html