網(wǎng)上有許多關(guān)于Struts2與JSON的文章,Google加百度,查閱了許多,有各種各樣的做法。其中,大部分的文章都說(shuō)要加進(jìn)一個(gè)叫jsonplugin的插件,在Google Code可以下載。以前我有做過(guò)測(cè)試,也是用它,但著實(shí)麻煩,要讓Struts2的package繼承一個(gè)叫“json-default”的父package。網(wǎng)上的文章,大部分都是說(shuō)從Struts的Action如何把JSON數(shù)據(jù)發(fā)送回瀏覽器端(Ajax),而我想要一個(gè)跟它們相反的過(guò)程(即從Ajax端發(fā)送數(shù)據(jù)到服務(wù)器端的Action并解析出來(lái)),卻找不到合適的答案。摸索了三個(gè)晚上,未果。今天終于讓我找到了思路。
其中,不管是從瀏覽器端(JS,Ajax,Jquery等)發(fā)送給服務(wù)器端,還是從服務(wù)器端(Struts的Action,Servlet等)發(fā)送回客戶端,都要識(shí)別一點(diǎn):發(fā)送的都應(yīng)該是JSON格式的字符串。
下面,我們先來(lái)重寫登錄模塊中的loginform.jsp文件,原來(lái)的代碼,請(qǐng)看Struts 2.1.6 精簡(jiǎn)實(shí)例系列教程(2):用戶登錄模塊的實(shí)現(xiàn),現(xiàn)在修改的代碼如下:












































關(guān)鍵的兩句是:
var jsonUser = {loginName:loginName1, password:password1}; (1) var strUser = JSON.stringify(jsonUser); (2) |
第(1)句是組裝JSON對(duì)象,關(guān)于JSON對(duì)象的格式,建議大家到http://www.json.org/網(wǎng)站上學(xué)習(xí)一下,要驗(yàn)證你寫的JSON對(duì)象是否正確,可在http://json.bloople.net/網(wǎng)站上驗(yàn)證。上面寫的JSON對(duì)象其實(shí)是非常簡(jiǎn)單的一種,jsonUser對(duì)象里有兩個(gè)屬性,分別是loginName和password,而表示這兩個(gè)屬性,用key-value的形式,loginName1和password1分別是接收表單中的賬號(hào)、密碼的值。
第(2)句,相當(dāng)重要,通過(guò)JavaScript內(nèi)置對(duì)象JSON的stringify方法,將JSON對(duì)象轉(zhuǎn)換成字符串。因?yàn)椋覀儌魉徒o服務(wù)器端的要是JSON格式的字符串。
$.post("login!valid.action", {json: strUser}, callback, "json"); |
這一句,Jquery用POST方法向服務(wù)器端發(fā)送數(shù)據(jù),login!valid.action是我們要發(fā)送到的目的URI,也即直達(dá)loginAction的valid方法。而{…}是我們要發(fā)送的數(shù)據(jù)(data),{json:strUser},其實(shí)也是一個(gè)JSON對(duì)象,Key:value的形式,大家注意,我們把strUser這個(gè)json串發(fā)過(guò)去,在Action那里接收時(shí),要接收“json”這個(gè)變量,這個(gè)變量的值就是我們發(fā)送的strUser字符串。
回調(diào)函數(shù)(callback)是指服務(wù)器端成功發(fā)回時(shí),在JS端執(zhí)行的函數(shù)。最后一個(gè)參數(shù)“json”是返回?cái)?shù)據(jù)類型的一種,另外,還有”text”、“xml”等。而function callback函數(shù)體的內(nèi)容,大家看完LoginAction類后,自然會(huì)明白。
好,Show一下修改后的LoginAction.java,代碼如下:






























































我們說(shuō)過(guò)了,JS與Action互相傳送的是JSON格式的字符串,故在LoginAction里,我們定義了private String json這個(gè)成員屬性及其getter和setter方法。
大家注意,在valid方法體中,引進(jìn)了org.json.JSONObject,這個(gè)類哪里來(lái)?請(qǐng)看:http://www.json.org/java/index.html,這里有幾個(gè)處理JSON數(shù)據(jù)常用的類:JSONObject.java
,JSONArray.java
,JSONStringer.java
,JSONWriter.java
,JSONTokener.java
,JSONException.java
,JSONString.java
,將它們下載下來(lái),放到項(xiàng)目中,如下:
或者,打成jar包,放到項(xiàng)目lib目錄下。我們就可以使用JSON類庫(kù)提供給我們的方法了。
網(wǎng)上有另一個(gè)JSON的類庫(kù):json-lib,大家也可下載使用一下,不過(guò),它要引進(jìn)幾個(gè)其他的jar包,詳細(xì)請(qǐng)見(jiàn)http://json-lib.sourceforge.net/。個(gè)人使用它的感受,也真有點(diǎn)郁悶,測(cè)試它時(shí),想找一個(gè)從JSON字符串轉(zhuǎn)換成JSON對(duì)象的方法,找了半天也沒(méi)找到。不過(guò),它對(duì)Java的Bean,Map,List等與JSONObject的互轉(zhuǎn)換做得還好。
sendMsg方法,是從Struts的Action中調(diào)用回原生Servlet的response來(lái)向?yàn)g覽器端發(fā)送數(shù)據(jù)。
還有一點(diǎn),大家應(yīng)該注意到,我們?cè)贚oginAction中寫的valid方法返回類型是void型的,跟我們以前做的返回“success”、”input”之類的String類型不同。當(dāng)我們通過(guò) “!valid”來(lái)方法它時(shí),它不作跳轉(zhuǎn),而是像我們平時(shí)Servlet中那種直接顯示HTML類似。這一點(diǎn)達(dá)成了Ajax與Struts的成功交互。而網(wǎng)上許多寫jsonplugin插件使用的文章,所調(diào)用的方法都是返回String類型,然后,再來(lái)個(gè)<result type=”json”>,那樣感覺(jué)挺麻煩的,不如直接讓Ajax發(fā)來(lái)的請(qǐng)求與void類型的方法交互,不直接爽快?
好,讓我們運(yùn)行一下,看看效果吧:
大家看看fireFox的debug的控制臺(tái)中顯示的:
好,我們來(lái)輸入一個(gè)正確的賬號(hào)和密碼,如下:
點(diǎn)確定后,網(wǎng)頁(yè)就跳到了后臺(tái)主頁(yè)。
這樣,Ajax(Jquery)與Struts2.1.6的交互,通過(guò)JSON格式的字符串傳遞數(shù)據(jù),這一實(shí)踐就完成了。有一點(diǎn)需要說(shuō)明一下:本例中的JSON對(duì)象都是相對(duì)比較簡(jiǎn)單,還有一些復(fù)雜的JSON對(duì)象,如{company:{building:”五角大樓”,employees:[{name:”tom”,age:21},{name:”marry”,age:18} ] } }。至于這些,該怎么處理呢?其實(shí),處理方法也一樣的。只是在Action中調(diào)用JSON類庫(kù)的一些對(duì)象和方法,就能很好地處理。
關(guān)于Struts2,JSON,Jquery的話題,我們會(huì)在Struts2.1.6精簡(jiǎn)實(shí)例系列教程之外,繼續(xù)討論。
本文原創(chuàng),轉(zhuǎn)載請(qǐng)注明出處,謝謝!http://www.aygfsteel.com/rongxh7(心夢(mèng)帆影JavaEE技術(shù)博客)