自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

WebWork文件上傳問題解析

開發(fā) 后端
本文向您介紹作者在進(jìn)行WebWork文件上傳時(shí)遇到的問題和解決方法。WebWork上傳文件是兩次拷貝過程,首先從request的輸入流中將文件流輸出到一個(gè)臨時(shí)文件,然后你再將此臨時(shí)文件拷貝到你需要指定的路徑。

今天遇到一個(gè)webwork文件上傳的問題,上傳 txt 文件的時(shí)候,如果文件內(nèi)容為空,則上傳后的文件為null,上傳不成功。試了一下,如果給txt文件寫一個(gè)二進(jìn)制的0x00字符,即可以上傳成功,如果是上傳一個(gè)沒有內(nèi)容的word文檔,也可以成功,分析原因應(yīng)該是word格式自帶了很多隱藏格式數(shù)據(jù),所以其實(shí)沒有文字內(nèi)容的word文檔也是有東西的。這樣看來,只要文件實(shí)際內(nèi)容為空,即不帶任何字符,上傳就有問題。

隨后,我查看了一下webwork.properties文件,發(fā)現(xiàn)我們項(xiàng)目的webwork.multipart.parser選用的是jakarta,

于是我依次換用了另外兩種parser:pell和cos。最后發(fā)現(xiàn),只有cos不會(huì)出錯(cuò),能夠上傳成功??磥恚蔷唧wparser對(duì)上傳文件流的解析不一樣。

三種parser都是市面上早已存在的,webwork只不過是對(duì)它們進(jìn)行了封裝調(diào)用,并不是靠自己來實(shí)現(xiàn)的。webwork提供了一個(gè)通用的訪問接口MultiPartRequest,然后針對(duì)三種parser,分別繼承實(shí)現(xiàn)了CosMultiPartRequest、PellMultiPartRequest、JakartaMultiPartRequest。默認(rèn)情況下,如果你不在webwork.properties文件中設(shè)置parser,webwork會(huì)選擇pell作為parser。

三種parser的區(qū)別是:只有Jakarta能做多文件的同時(shí)上傳;

只有pell能自動(dòng)支持中文名文件的上傳,其他兩種需要你自己手動(dòng)做encoding;cos功能比較強(qiáng)大,比如我上面提到的txt文件內(nèi)容為空,cos可以上傳成功,但其他兩種parser就不行,不過webwork的封裝使它喪失了很多功能。

另外,webwork.properties文件里還有其他幾個(gè)與文件上傳相關(guān)的參數(shù),比如webwork.multipart.saveDir用于設(shè)定上傳文件的臨時(shí)文件保存目錄,webwork.multipart.maxSize用于設(shè)置上傳文件的最大字節(jié)數(shù)。

我又上網(wǎng)找了一篇文章,深入介紹了WebWork文件上傳的機(jī)制和過程,還找了一篇剖析webwork源碼的pdf《Anatomy Webwork Source Code》,大家可以去下載看看 http://public.iecn.net/Along/Anatomy%20Webwork%20Source%20Code_V0.9.pdf

那篇深入介紹Webwork文件上傳機(jī)制的文章(http://www.wangchao.net.cn/bbsdetail_267965.html)如下:

點(diǎn)擊上傳按鈕后,webwork的程序流如下:

  1. step1)進(jìn)入ServletDispatcher.service  
  2. publicvoidservice  
  3. (HttpServletRequestrequest,HttpServletResponseresponse)  
  4. throwsServletException{  
  5. ........  
  6. request=wrapRequest(request);  
  7. .........  
  8. }  
  9. step2)進(jìn)入ServletDispatcher.wrapRequest  
  10. protectedHttpServletRequestwrapRequest  
  11. (HttpServletRequestrequest)throwsIOException{  
  12. ........................  
  13. if(MultiPartRequest.isMultiPart(request)){  
  14. request=newMultiPartRequestWrapper  
  15. (request,getSaveDir(),getMaxSize());  
  16. }  
  17. returnrequest;  
  18. }  
  19. step3)進(jìn)入MultiPartRequestWrapper的構(gòu)造方法  
  20. publicMultiPartRequestWrapper  
  21. (HttpServletRequestrequest,StringsaveDir,intmaxSize)  
  22. throwsIOException{  
  23. .....................  
  24. //step3.1)獲取webwork.preperties配置的parser  
  25. Stringparser="";  
  26. parser=Configuration.getString("webwork.multipart.parser");  
  27. //Ifit'snotset,usePell  
  28. if(parser.equals("")){  
  29. log.warn("Propertywebwork.multipart.parsernotset."+  
  30. "Usingcom.opensymphony.webwork.dispatcher.multipart.  
  31. PellMultiPartRequest");  
  32. parser="com.opensymphony.webwork.dispatcher.  
  33. multipart.PellMultiPartRequest";  
  34. }  
  35. //legacysupportforoldstylepropertyvalues  
  36. elseif(parser.equals("pell")){  
  37. parser="com.opensymphony.webwork.dispatcher.  
  38. multipart.PellMultiPartRequest";  
  39. }elseif(parser.equals("cos")){  
  40. parser="com.opensymphony.webwork.dispatcher.  
  41. multipart.CosMultiPartRequest";  
  42. }elseif(parser.equals("jakarta")){  
  43. parser="com.opensymphony.webwork.dispatcher.  
  44. multipart.JakartaMultiPartRequest";  
  45. }  
  46. //step3.2)獲取后通過反射實(shí)例化parser  
  47. try{  
  48. ClassbaseClazz=com.opensymphony.webwork.dispatcher.  
  49. multipart.MultiPartRequest.class;  
  50. Classclazz=Class.forName(parser);  
  51. //makesureitextendsMultiPartRequest  
  52. if(!baseClazz.isAssignableFrom(clazz)){  
  53. addError("Class'"+parser+"'doesnotextendMultiPartRequest");  
  54. return;  
  55. }  
  56. //gettheconstructor  
  57. Constructorctor=clazz.getDeclaredConstructor(newClass[]{  
  58. Class.forName("javax.servlet.http.HttpServletRequest"),  
  59. java.lang.String.class,int.class  
  60. });  
  61. //buildtheparameterlist  
  62. Object[]parms=newObject[]{  
  63. request,saveDir,newInteger(maxSize)  
  64. };  
  65. //instantiateit  
  66. multi=(MultiPartRequest)ctor.newInstance(parms);  
  67. .................................................  
  68. }  

//step4 進(jìn)入JakartaMultiPartRequest的構(gòu)造方法(我在webwork配置的parser是Jakarta所以進(jìn)入了這個(gè)方法,如果你配置不同的parser回進(jìn)入不同的parser

  1. public JakartaMultiPartRequest  
  2. (HttpServletRequest servletRequest,   
  3. String saveDir, int maxSize)  
  4. throws IOException {  
  5. //設(shè)置保存參數(shù)  
  6. DiskFileUpload upload = new DiskFileUpload();  
  7. // we must store all uploads on disk because   
  8. the ww multipart API is missing streaming  
  9. // capabilities  
  10. upload.setSizeThreshold(0);  
  11. upload.setSizeMax(maxSize);  
  12. if (saveDir != null) {  
  13. upload.setRepositoryPath(saveDir);  
  14. }  
  15. // Parse the request  
  16. try {  

//此方法生成文件,將請(qǐng)求中的每個(gè)參數(shù)都生成一個(gè)臨時(shí)文件比如upload_00000017.tmp, upload_00000018.tmp等,就算是form提交的參數(shù)也如此

  1. List items = upload.parseRequest(servletRequest);  
  2. ......................  
  3. }  

執(zhí)行完第四步,然后推出ServletDispatcher.wrapRequest,進(jìn)入serviceAction方法,開始action及其攔截器的棧調(diào)用

進(jìn)入action和調(diào)用棧后,攔截器或action可通過如下代碼訪問上傳的臨時(shí)文件

  1. MultiPartRequestWrapper wrapper =   
  2. (MultiPartRequestWrapper) req;  
  3. File doc = wrapper.getFiles("doc")[0];  

從上面的分析可以看出:

1)WebWork文件上傳在進(jìn)入action棧之前不修改源碼或者做一些擴(kuò)展、覆蓋之類的動(dòng)作,在進(jìn)入action棧的時(shí)候文件已經(jīng)上傳,而且其文件名很難跟蹤(upload_00000017.tmp,到底是00000017,0000018,或者0000022等等),畢竟有很多人上傳文件,所以臨時(shí)文件名很難確定,所以如果你想知道上傳的進(jìn)度很難。


2)利用WebWork文件上傳是兩次拷貝過程,webwork首先從request的輸入流中將文件流輸出到一個(gè)臨時(shí)文件,然后你再將此臨時(shí)文件拷貝到你需要指定的路徑。

【編輯推薦】

  1. WebWork框架原理與應(yīng)用(1)
  2. 用WebWork注冊(cè)頁面建立過程
  3. WebWork注入Servlet方法詳解
  4. WebWork中返回INPUT的原因
  5. WebWork如何實(shí)現(xiàn)文件上傳配置過程
責(zé)任編輯:冰荷 來源: blog
相關(guān)推薦

2009-07-20 14:04:27

WebWork標(biāo)簽嵌套

2010-05-20 13:58:34

2009-07-14 17:20:31

Webwork文件上傳

2009-07-08 09:29:58

WebWork

2009-07-14 15:52:00

WebWork文件下載

2009-09-04 10:55:34

2010-04-29 12:42:09

Unix系統(tǒng)

2009-07-09 15:55:18

WebWork配置文件

2012-07-24 17:10:10

Linux操作系統(tǒng)

2012-05-23 13:11:10

架構(gòu)存儲(chǔ)

2010-01-28 13:15:43

C++參數(shù)

2010-02-23 17:57:58

Python部署

2010-11-23 15:50:44

MySQL中文建表

2009-11-05 15:36:58

WCF service

2010-01-08 17:12:03

VB.NET短路判斷

2010-04-19 13:54:43

Unix操作系統(tǒng)

2010-04-06 09:31:52

Windows 7顯示白點(diǎn)

2009-09-03 15:33:13

RHEL紅帽linux

2010-05-24 14:04:48

JavaSwing多線程

2009-12-31 15:08:22

Silverlight
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)