国产精品电影_久久视频免费_欧美日韩国产激情_成年人视频免费在线播放_日本久久亚洲电影_久久都是精品_66av99_九色精品美女在线_蜜臀a∨国产成人精品_冲田杏梨av在线_欧美精品在线一区二区三区_麻豆mv在线看

淺談對Struts2上傳文件的理解

開發 后端
本文將為大家談談對Struts2上傳文件的理解,并結合實際工作中出現的異常,進行講解。

孫鑫的書《Struts2 深入詳解》509頁是關于限制Struts2上傳文件的***長度的內容。 其中談到fileUpload攔截器只是當文件上傳到服務器上之后,才進行的文件類型和大小判斷。Struts2框架底層默認用的是apache的commons-fileupload組件對上傳文件進行接受處理。

通過struts.multipart.maxSize屬性來對文件大小進行限定時,將直接影響到commons-fileupload組件的文件大小設定,默認是2M。當上傳文件超過了這個尺寸時,將從commons-fileupload組件中拋出SizeLimitExceededException異常。Struts2上傳文件攔截器捕獲到這個異常后,將直接把該異常信息設置為Action級別的錯誤信息。

經過我的測試和對源代碼的Debug,發現確實如孫鑫書中所言,如果上傳文件大于2M時,在頁面上就出現了一堆英文的錯誤信息,大致是:the request was rejected because its size....exceeds the configured maximum...并且在fieUpload中將來自MultiPartRequestWrapper型request對象的錯誤信息給加到了Action的錯誤中。

這時候,你在ApplicationResources.properties中自定義的上傳文件過大的錯誤信息根本不起作用。原因就如書上所言,在底層commons-fileupload組件中就把異常給拋出來了文件根本沒被上傳,所以到了fileUpload攔截器時,根據取不到文件,當然也就沒法對文件的類型和大小進行判斷了。

然而,這個異常直接帶來兩個問題:

1、在頁面上顯示了英文的錯誤信息。這樣的信息顯然不是我們想要的。

2、由于錯誤的產生,原來頁面上輸入的其他文本內容也都不見了,也就是說params注入失敗。

帶著這兩個問題,我們來探尋一下Struts2對于請求的處理過程。

注:這并不是一篇關于Struts2請求過程的介紹,主要是為了解決以上兩個問題,才引起的簡單分析。

首先當然我們要拿FilterDispatcher開刀。

在doFilter方法中調用了prepareDispatcherAndWrapRequest方法,為了包裝出Struts2自己的request對象,在prepareDispatcherAndWrapRequest方法中調用Dispatcher類的wrapRequest方法,在這個方法里,會根據請求內容的類型(提交的是文本的,還是multipart/form-data格式),決定是使用tomcat的HttpServletRequestWrapper類分離出請求中的數據,還是使用Struts2的MultiPartRequestWrapper來分離請求中的數據。

注:向服務器請求時,數據是以流的形式向服務器提交,內容是一些有規則東東,我們平時在jsp中用request內置對象取parameter時,實際上是由tomcat的HttpServletRequestWrapper類分解好了的,無需我們再分解這些東西了。

當然,在這里,我們研究的是上傳文件的情況,所以,由于form中設定的提交內容是媒體格式的,所以,Dispatcher類的wrapRequest方法會將請求交由MultiPartRequestWrapper類來處理。

MultiPartRequestWrapper這個類是Struts2的類,并且繼承了tomcat的HttpServletRequestWrapper類,也是我們將用來代替HttpServletRequest這個類的類,看名字也知道,是對多媒體請求的包裝類。

Struts2本身當然不會再造個輪子,來解析請求,而是交由Apache的commons-fileupload組件來解析了。

在MultiPartRequestWrapper的構造方法中,會調用MultiPartRequest(默認為JakartaMultiPartRequest類)的parse方法來解析請求。

在Struts2的JakartaMultiPartRequest類的parse方法中才會真正來調用commons-fileupload組件的ServletFileUpload類對請求進行解析,至此,Struts2已經實現了將請求轉交commons-fileupload組件對請求解析的全過程。剩下的就是等commons-fileupload組件對請求解析完畢后,拿到分解后的數據,根據field名,依次將分解后的field名和值放到params(HashMap類型)里,同時JakartaMultiPartRequest類重置了HttpServletRequest的好多方法,比如熟知的getParameter、getParameterNames、getParameterValues,實際上都是從解析后得到的那個params對象里拿數據,在這個過程,commons-fileupload組件也乖乖的把上傳的文件分析好了,JakartaMultiPartRequest也毫不客氣的把分解后的文件一個一個的放到了files(HashMap類型)中,實際上此時,commons-fileupload組件已經所有要上傳的文件上傳完了。

至此,Struts2實現了對HttpServletRequest類的包裝,當回到MultiPartRequestWrapper類后,再取一下上述解析過程中發生的錯誤,然后把錯誤加到了自己的errors列表中了。同樣我們會發現在MultiPartRequestWrapper類中,也把HttpServletRequest類的好多方法重載了,畢竟是個包裝類嘛,實際上對于上傳文件的請求,在Struts2后期的處理中用到的request都是MultiPartRequestWrapper類對象,比如我們調用getParameter時,直接調用的是MultiPartRequestWrapper的getParameter方法,間接調的是JakartaMultiPartRequest類對象的getParameter方法。

注:從這里,我們就可以看出,JakartaMultiPartRequest是完全設計成可以替換的類了。

然后繼續向回返,到了Dispatcher類的wrapRequest方法,直接把MultiPartRequestWrapper對象返回了,我們就終于回到了FilterDispatcher類的prepareDispatcherAndWrapRequest方法,此時,我們拿到了完全解析好了的request對象(MultiPartRequestWrapper類),該對象又進一步被返回到了FilterDispatcher類的doFilter方法,也就是回到了出發點,至此,doFilter中拿到的request對象就是一個將請求中的數據分解好的了HttpServletRequest對象,我們完全可以用getParameter方法取其中的數據了,同時,我們也可以用getFiles得到文件數組了。

doFilter方法中,會進一步調用actionMapper的getMapping方法對url進行解析,找出命名空間和action名等,以備后面根據配置文件調用相應的攔截器和action使用。

關于doFilter方法中下一步對Dispatcher類的serviceAction方法的調用,不再描述,總之在action被調用之前,會首先走到fileUpload攔截器(對應的是FileUploadInterceptor類),在這個攔截器中,會先看一下request是不是 MultiPartRequestWrapper,如果不是,就說明不是上傳文件用的request,fildUpload攔截器會直接將控制權交給下一個攔截器;如果是,就會把request對象強轉為MultiPartRequestWrapper對象,然后調用hasErrors方法,看看有沒有上傳時候產生的錯誤,有的話,就直接加到了Action的錯誤(Action級別的)中了。

另外,在fileUpload攔截器中會將MultiPartRequestWrapper對象中放置的文件全取出來,把文件、文件名、文件類型取出來,放到request的parameters中,這樣到了params攔截器時,就可以輕松的將這些內容注入到Action中了,這也就是為什么fileUpload攔截器需要放在params攔截器前面的理由。在文件都放到request的parameters對象里之后,fileUpload攔截器會繼續調用其他攔截器直到Action等執行完畢,他還要做一個掃尾的工作:把臨時文件夾中的文件刪除(這些文件是由commons-fileupload組件上傳的,供你在自己的Action中將文件copy到指定的目錄下,當action執行完了后,這些臨時文件當然就沒用了)。

你好,你還在看嗎?呵呵,是不是太多了,也太亂了,沒辦法,Struts2就是這樣的調用的。也不知道Struts2有沒有公開其Sequence圖,我是想畫一個,不過,太懶,還是看著代碼說說吧。

如果上面看煩了,也完全可以不看了,直接看下面的。

在上面一番分析之后,文件上傳的全過程就結束了。
我們回到我們的問題上來。

先看***個:

1、在頁面上顯示了英文的錯誤信息。這顯然不是我們想要的。

沒辦法了,commons-fileupload組件沒想到國際化,在FileUploadInterceptor攔載器中,也沒想著國際化,直接放到Action的錯誤中了,就沒他事了,三種做法:

(1)在錯誤顯示之前,把這條錯誤給換掉,應該難度不大,我沒做留給你做了。

(2)或者重寫一下JakartaMultiPartRequest這個類,把捕捉到的異常信息換成自己的,然后,通過Struts2的配置文件,把我們重寫的這個parser換上去用。

(3)直接改commons-fileupload組件的類,換成中文的。

我具體說一下第(3)種做法:找到FileUploadBase類,把902行~908行改一下。
FileUploadException ex =
    new SizeLimitExceededException(
        "the request was rejected because"
        + " its size (" + pCount
        + ") exceeds the configured maximum"
        + " (" + pSizeMax + ")",
        pCount, pSizeMax);
=>
FileUploadException ex = new SizeLimitExceededException(
"服務器拒絕了您的請求,原因可能是向服務器提交的數據發生了丟失。", pCount, pSizeMax);

把914行~918行改一下。
throw new SizeLimitExceededException(
        "the request was rejected because its size ("
        + requestSize
        + ") exceeds the configured maximum ("
        + sizeMax + ")",
=>
throw new SizeLimitExceededException("服務器拒絕了您的請求,原因是提交數據量過大(通常是由于上傳文件過大),請返回上頁重試。"
+ " (***字節數:" + sizeMax / 1024
+ "K)", requestSize, sizeMax);


再看一下第二個問題。

2、由于錯誤的產生,原來頁面上輸入的內容也全部不見了,也就是說params注入失敗。
關于這個問題我在javaeye上搜索到一篇文章(使用的commons-fileupload組件的jar包似乎比較老)。
http://www.javaeye.com/topic/197345

雖然按照此文,當上傳失敗時,能夠將其他輸入內容顯示出來,但是這樣做的結果是全部的文件肯定會上傳到服務器上,也就是說,雖然是頁面上報了文件因為太大,請求被拒絕的錯,但是文件依然會被上傳到服務器上,commons-fileupload組件根本沒會去攔文件的上傳。

在這里要說明一下,如果你不拋出這個異常,請求的流會繼續向服務器上傳,只有當整個流上傳完了之后,commons-fileupload組件才能正確的分析出文件部分、文本部分。所以,在這里拋出異常是不得已的作法,如果不拋異常,后果是雖然頁面報錯,但文件還是會被傳到服務器的上,這一步根本沒擋住輸入流的上傳,如果沒擋住的話,大家想想會有什么后果?

所以,綜上所述,對于第二個問題,如果出現了這個異常,我們根本無法讓原來輸入的內容還顯示出來的,因為commons-fileupload組件并沒有解析全部的輸入內容,直接給出異常了,到了params攔截器中,request里就是空的,根本取不到parameter,所以也就無法注入到Action中了。這種情況下,只能顯示一個告知用戶由于提交數據量過大,服務器拒絕了請求的錯誤信息,比較好的方法是,直接跳到一個專門的頁面,提示用戶,然后讓用戶點返回來再次輸入,否則用戶會感覺上傳文件大就大吧,怎么連我輸入的其他一些內容也沒給保存住。當然,如果能用Ajax來上傳文件,對客戶的操作體驗可能是***的,但是,這樣可能會導致服務器上有些掛空的文件(上傳后從來沒被用過),需要想法清除的。

整個分析下來,我們說第二個問題基本上是無法避免的。

 【編輯推薦】

  1. 在Eclipse中開發struts應用程序
  2. 手把手教你在Eclipse中配置開發Struts
  3. Eclipse下開發struts完整解決亂碼問題
  4. Struts相關背景介紹
  5. 使用Easy Struts for Eclipse開發Struts
責任編輯:張燕妮 來源: blogjava
相關推薦

2009-06-08 16:44:00

Struts2文件上傳

2009-06-25 15:50:03

Struts2教程上傳任意多個文件

2009-02-04 14:00:59

2009-07-14 17:10:44

struts2webwork

2009-06-04 08:45:01

Struts2下載

2009-06-05 09:58:20

struts2驗證用戶注冊

2009-06-08 16:44:00

struts2 ogn

2009-06-04 08:34:24

Struts2配置struts.xml

2009-06-04 08:01:25

Struts2攔截器原理

2009-07-29 09:54:34

struts2和str

2009-06-08 16:44:00

2011-06-28 09:14:23

Struts 2WebWork

2011-05-05 10:16:06

struts2

2009-06-25 15:11:28

Struts2教程Struts2程序

2012-05-10 14:00:06

StrutsjsonJava

2009-06-05 10:52:45

struts2深入詳解配置文件

2009-02-04 10:51:07

2009-06-04 09:20:19

struts2 if標使用

2009-07-03 09:35:57

Struts2 JSP

2009-06-05 10:55:07

struts2 web
點贊
收藏

51CTO技術棧公眾號

亚洲裸体视频| 大胆人体一区| 国产91丝袜在线18| 亚洲午夜在线| 在线日韩精品视频| 91九色国产社区在线观看| 成人免费观看www在线| 国产精品扒开腿做爽爽爽视频软件| 亚洲乱码日产精品bd| 亚洲成年人专区| 欧美va亚洲va日韩∨a综合色| 又紧又大又爽精品一区二区| 最近免费观看高清韩国日本大全| 丁香花电影在线观看完整版| 免费亚洲婷婷| 国产精品视频精品| 国产一区二区三区黄网站| 亚洲精品在线一区二区| 噜噜噜噜噜在线视频| 伊人开心综合网| 成人免费毛片在线观看| 成人深夜福利| 3d成人h动漫网站入口| 最猛黑人系列在线播放| 亚洲第一偷拍| 欧美极品欧美精品欧美视频| 中文字幕这里只有精品| 日韩视频在线永久播放| 狠狠色伊人亚洲综合网站l| 1024国产精品| av观看免费在线| 东方aⅴ免费观看久久av| 亚洲日本精品| 久久精品av麻豆的观看方式| 亚洲日本中文字幕免费在线不卡| 黄色一级片网址| 亚洲黄色天堂| 亚洲毛片在线免费观看| 欧美xxx黑人xxx水蜜桃| 国产精品自拍在线| 深夜福利成人| 亚洲免费影视| 日本不卡久久| 琪琪一区二区三区| 色噜噜狠狠一区二区三区| 久久精品电影| 神马影院一区二区| 青青青伊人色综合久久| 亚洲欧美久久久久一区二区三区| 久久亚洲色图| 美女性感视频久久久| 日本精品在线中文字幕| 中文字幕日韩电影| 欧美三级电影网址| 另类专区欧美制服同性| 精品福利网址导航| 欧美日韩精品高清| 中文字幕在线播放| 91丝袜美腿高跟国产极品老师 | 欧美精品在线第一页| 久久久国产精品入口麻豆| 欧美刺激性大交免费视频| 亚洲综合色婷婷在线观看| 国内精品小视频在线观看| 夜夜春成人影院| 7777精品伊久久久大香线蕉语言| 亚洲三级色网| 大桥未久一区二区三区| 欧美高清在线一区二区| 黄页网站免费在线观看| 欧美日韩国产免费| 超碰97国产精品人人cao| 中文字幕欧美亚洲| 男人的天堂久久| 日韩免费成人网| 澳门成人av网| 98精品国产高清在线xxxx天堂| 成人短片线上看| 日韩综合中文字幕| 久久精品色播| 精品视频高清无人区区二区三区| 韩国毛片一区二区三区| 成人欧美一区二区| 日本女人一区二区三区| 成人在线观看黄| 欧美日韩精品在线| 北条麻妃视频在线| 亚洲成人福利片| 欧美1—12sexvideos| 久久97久久97精品免视看| 女人天堂亚洲aⅴ在线观看| 国产女人18毛片| 黄色成人精品网站| 欧美日韩亚洲国产成人| 亚洲女女做受ⅹxx高潮| 欧美日韩经典丝袜| 91精品国产91久久久久| 羞羞答答国产精品www一本| 精品一卡二卡三卡| 欧美日产国产精品| 国产 日韩 欧美 综合 一区| 美脚丝袜一区二区三区在线观看| 国产农村妇女精品| 久久久一本二本三本| 午夜精品福利久久久| 国产一伦一伦一伦| 欧美日韩国产小视频| 国产剧情一区二区在线观看| 亚洲已满18点击进入在线看片 | 国产suv精品一区二区| 日韩电影在线一区二区三区| 成人av网页| 亚洲欧洲中文天堂| 欧美日韩ab| 国产精品免费视频久久久| 免费精品99久久国产综合精品| 在线成人私人影院| 日韩av在线一区二区| 国产黄a三级三级三级av在线看| 亚洲一区二区高清| 黄色在线免费观看网站| 91美女片黄在线观看游戏| 久久久精品日韩欧美| 草草影院在线| 亚洲xxx视频| 亚洲欧美激情一区二区| 国产精品久久乐| 日韩一区免费观看| 天堂影院一区二区| jk破处视频在线| 久久精品国产2020观看福利| 久久青草久久| 男女av在线| 国产经典一区二区| 久久精品一二三| 黄色成人在线视频| 五月天丁香综合久久国产| 一区二区三区**美女毛片| 色悠久久久久综合先锋影音下载| 一本色道久久99精品综合| 欧美精品tushy高清| 99久久综合狠狠综合久久aⅴ| 国产日韩欧美中文| 国产欧美一二三区| 久久精品国产精品亚洲毛片| 国产精品美女在线播放| 欧美挠脚心视频网站| 欧美.www| 久草福利在线| 高清国产在线一区| 日本精品一区二区三区高清| 91精选在线| 日韩精品视频观看| 午夜在线精品偷拍| 在线国产91| 国产精品一区二区在线观看| 欧美性猛交99久久久久99按摩| 日韩毛片视频| 日韩妆和欧美的一区二区| 色婷婷av一区二区三区之一色屋| 欧美日韩在线网站| 蜜桃臀av在线| 国产日本欧美一区二区三区在线| 一区二区三区不卡视频在线观看| 国产精品一区二区三区美女| 欧美1819sex性处18免费| 538国产精品一区二区免费视频| 欧美a级一区| 国自产拍在线网站网址视频| 99re在线观看视频| 91久久精品一区二区| 影音先锋日韩资源| 二区在线播放| 亚洲资源在线网| 最新亚洲国产精品| 久久久久久久精| 国产探花在线精品一区二区| 亚洲精品视频在线免费| 国产chinese精品一区二区| 欧美一区二区视频在线观看| 久久精品国产免费| 日本黄色成人| 91手机在线观看| 欧美在线观看你懂的| 奇米一区二区三区| av在线亚洲一区| 天堂男人av| 欧美日韩精品免费观看| 亚洲天堂男人的天堂| 真实国产乱子伦精品一区二区三区| 久久久久久久9| 久久久久久久一| 亚洲国产精品久久艾草纯爱| 亚洲一区中文| 日韩伦理一区二区| 最后生还者第二季在线观看| 亚洲精品久久区二区三区蜜桃臀| 美女黄色丝袜一区| 欧美性猛片xxxx免费看久爱| 国产传媒欧美日韩成人|