1. 程式人生 > >struts2+jquery ajax問題彙總與解決辦法

struts2+jquery ajax問題彙總與解決辦法

如何將jquery裡的ajax技術使用到struts2裡:
ajax裡主要涉及幾個概念:
1、請求url,即要執行的後臺程式碼url,可以是servlet,jsp,也可以是struts裡的action
2、資料,向url提交請求時,可能會需要向其中傳參。這些引數是以json格式組織的,傳入的時候作為parameter傳入;
3、提交方式,get或者post;
4、回撥函式:即當請求完成後,如何得到返回的資料,以及如何處理返回資料。有error,success,complete等幾種;

在不使用struts2的時候,可以直接使用servlet或者jsp來實現。輸出的資料一般用json格式,直接使用out.print列印到客戶端,在客戶端會被封裝成一個物件,然後在回撥函式中直接使用即可。使用示例見《javaweb開發王者歸來》裡hibernate高階查詢中,有相應的例子;

在使用struts2的時候,因為struts2本身對servlet機制做了重新的封裝,使得原來直接使用servlet來實現非同步請求的思路在這裡不適用。以前我在一個處理使用者上傳頭像的功能中,將struts2的action返回到一個jsp頁面,由jsp頁面來實現out.print資料,這樣也可以實現對返回資料的獲取與處理。然而是單純使用struts2時,卻遇到了一些問題。有人提議讓action直接返回null,然後通過上下文得到response再得到Writer物件,然後直接把資料寫到out流中的辦法。這樣不失為一種方法,但為了更清楚地搞明白struts與jquery結合工作的方式,有必要搞清楚如何不借助servlet或jsp,只使用action實現ajax功能。

在實際使用過程中,$.ajax函式呼叫url沒有出現什麼問題,問題主要出現在如何獲得返回值以及如何處理返回的問題裡。
最初嘗試使用返回SUCCESS,同時使用Writer輸出json格式的字串的方式,但是結果很奇怪,回撥函式可以執行,但是卻取不到任何資料。而且,回撥函式只能寫成success()這樣的形式,無法為其賦參。一旦賦參就不執行。非常奇怪,估計是返回的資料有問題。

後來不斷去查資料,見有人提到說需要在struts的配置檔案裡把action的返回結果的type需要置成"json"格式才能像servlet那樣返回資料。
在實際嘗試時出現了幾個問題:
1、首先,要使用<result name="xxx" type="json"></result>這樣返回結果,需要package繼承json-default包。這個包一來預設沒有包含在struts庫中,需要單獨去下,包名為:struts2-json-plugin-xxxx.jar這種。然後還需要一個包,這個包是專門用於struts轉換json物件的:ezmorph-xxxx.jar。其它需要的就是一些struts2常見包了,如core,convention,json-lib,common-系列包等。
依賴關係解決了,還需要解決struts-default與json-default的衝突問題。
struts-default可以設定result型別為type="stream",這在動態生成驗證碼的時候有用,然而json-default卻並不支援它。
解決辦法是設定兩個package,區別命名,並將繼承json-default的那個package指定一個namespace="json"之類與main包區別。
這些工作完成後,直接訪問json下的返回SUCCESS的action,會直接得到一個json格式的輸出結果。輸出的內容為此action裡所有含有getter和setter方法的域。
前面得到了json格式的輸出結果,但是還是在success回撥函式那裡出現問題。剛才也發現,輸出的json包含了頁面裡所有的帶setter、getter方法的域,實際上用這種方法配置的結果,只需要一個某些結果。受servlet方式的影響,很多人以為返回的應該是json格式的string,實際上需要返回的是一個JSONObject的物件。也就是需要給action配置一個JSONObject的域,並帶上getter、setter方法。不僅如此,還需要給url所指向的action方法對應的struts配置檔案裡,在<result name="" type="json"></result>里加一個param標籤:<param name="root">field_name</param>其中name為root這個屬性有什麼用尚不清楚,但是field_name這個必須與在action裡配置的JSONObject物件的名字相同。這時再在瀏覽器位址列輸入ajax的url所指向的action,就會僅返回這個JSONObject變數的toString()結果。這時再在$_ajax的success裡設定函式:function(data){},data裡就存放著正確的json資料了。還有些部落格文章裡寫道,要用一個eval方法將data轉換成一個json物件,這裡並不需要這樣做,直接用data.變數名就可以訪問到其中的資料。如data.username就可以訪問到json物件裡username域的值。

在解決問題期間參考了一些文章,都或多或少對解決問題有所幫助,尊重並感謝原作者,連結如下:

還有些別的文章,不一一列舉了。