SSH框架網(wǎng)上商城項(xiàng)目第24戰(zhàn)之Struts2中處理多個(gè)Model請(qǐng)求的方法
1. 問(wèn)題的提出
Struts2中如果實(shí)現(xiàn)了ModelDriven<model>接口就可以將傳來(lái)的參數(shù)注入到model中了,就可以在Action中使用該model,但是如果現(xiàn)在有兩個(gè)model都需要在同一個(gè)Action中使用該咋整呢?比如上一節(jié)我們完成了在線支付功能,但是支付完成了還沒(méi)結(jié)束,我們需要接收從第三方那邊反饋回來(lái)的信息,比如成功支付后,我們需要給付款方發(fā)送郵件和短信等。所以我們還需要在payAction中獲取從第三方傳過(guò)來(lái)的參數(shù),由于從第三方傳過(guò)來(lái)的參數(shù)與我們傳過(guò)去的參數(shù)是不同的,所以接收那些參數(shù)我們也得寫(xiě)一個(gè)Model(BackData),那么問(wèn)題來(lái)了,我們的PayAction已經(jīng)寫(xiě)成這樣子了:public class PayAction extends BaseAction<SendData>,即已經(jīng)在BaseAction中實(shí)現(xiàn)了ModelDriven<SendData>接口了,那么如何在一個(gè)action中再接收一個(gè)Model,并且還得對(duì)它們進(jìn)行不同的處理呢?
有種解決辦法(其實(shí)也不能稱(chēng)為解決辦法……因?yàn)楦揪蜎](méi)解決……)就是寫(xiě)一個(gè)Model,然后讓SendData和BackData繼承它,但是問(wèn)題是這兩個(gè)Model根本就沒(méi)關(guān)系,為啥要繼承同一個(gè)Model,所以這種解決辦法實(shí)際上是在逃避上面的問(wèn)題。
在SpringMVC(SpringMVC還沒(méi)真正開(kāi)始學(xué),如果有說(shuō)錯(cuò),請(qǐng)指正?。┖芎玫慕鉀Q了這個(gè)問(wèn)題,因?yàn)镾pringMVC中每個(gè)方法對(duì)應(yīng)一個(gè)Model,而不是每個(gè)Action對(duì)應(yīng)一個(gè)Model,這就方便了,我在同一個(gè)Action中寫(xiě)兩個(gè)方法即可,不同的方法處理不同的Model。
2. 問(wèn)題的解決
針對(duì)這個(gè)問(wèn)題,Struts2也提供了一種解決辦法:
Struts2在ActionContext中存儲(chǔ)了很多個(gè)Map,比如之前提到的request, session, application等,其中還有個(gè)parameterMap,該Map中存儲(chǔ)了request所有的請(qǐng)求參數(shù),只要我們的Action實(shí)現(xiàn)了parameterAware接口,就能拿到這個(gè)parameterMap,這就跟ModelDriven的道理是一樣的,如果我們實(shí)現(xiàn)了ModelDriven<Model>接口,那么我們?cè)贏ction中就能獲得該Model,即定義一個(gè)Model并實(shí)現(xiàn)set方法即可。
好了,那現(xiàn)在問(wèn)題好辦了,支付的參數(shù)和返回的參數(shù)是不同的,也就是說(shuō)兩次進(jìn)入PayAcition中的參數(shù)是不同的,即兩次的parameterMap中裝的數(shù)據(jù)不一樣,那只要我們?cè)贏ction中選取一個(gè)參數(shù)(該參數(shù)只要能區(qū)分兩次是不同的request請(qǐng)求即可)作為判斷,就知道當(dāng)前該用哪個(gè)Model來(lái)接收參數(shù)(SendData還是BackData)。下面我們改寫(xiě)一下PayAction中的代碼:
@Controller("payAction") @Scope("prototype") public class PayAction extends BaseAction<Object> implements ParameterAware { //注意上面繼承的BaseAction中不能寫(xiě)SendData了,要寫(xiě)Object,等下我們?cè)倥袛嗑唧w使用哪個(gè) //定義一個(gè)Map接收request的請(qǐng)求參數(shù) private Map<String, String[]> parameters; @Override public void setParameters(Map<String, String[]> parameters) { this.parameters = parameters; } /*在struts-default.xml文中,ServletConfig攔截器在ModelDriven之前先執(zhí)行,所以我們?cè)谧⑷雖odel的時(shí)候, request參數(shù)已經(jīng)有了,這樣我們就可以在getModel()方法中通過(guò)參數(shù)來(lái)判斷是哪個(gè)請(qǐng)求了*/ @Override public Object getModel() { //付款的時(shí)候有支付通道編碼的參數(shù)(pd_FrpId),返回的時(shí)候沒(méi)有 //這樣我們就可以通過(guò)該參數(shù)判斷是支付還是返回了 if(parameters.get("pd_FrpId") != null) { model = new SendData(); } else { model = new BackData(); } return model; } //向易寶發(fā)送數(shù)據(jù)的方法 public String goBank() { //對(duì)應(yīng)發(fā)送的model:SendData SendData sendData = (SendData)model; //處理發(fā)送數(shù)據(jù)的邏輯,前一節(jié)已經(jīng)實(shí)現(xiàn)過(guò)了…… } //接收返回的數(shù)據(jù)的方法 public void backBank() { //對(duì)應(yīng)接收的model:BackData BackData backData = (BackData)model; //處理返回?cái)?shù)據(jù)的邏輯……后面再來(lái)實(shí)現(xiàn), //先講Struts2處理多個(gè)Model請(qǐng)求這個(gè)知識(shí)點(diǎn) } }
3. Struts2的處理流程
我們?cè)賮?lái)分析一下Struts2的執(zhí)行流程,這樣更加利于理解上面的原理。Struts處理流程:
1)、獲取請(qǐng)求后,先創(chuàng)建Action的代理,在創(chuàng)建代理的時(shí)候順便創(chuàng)建了Action;
2)、執(zhí)行18個(gè)攔截器,攔截器執(zhí)行成功后再調(diào)用Action的方法;
3)、Action的方法執(zhí)行完畢后,再調(diào)用18個(gè)攔截器
所以根據(jù)這個(gè)流程,我們知道:先創(chuàng)建Action–>再執(zhí)行攔截器(先執(zhí)行ServletConfig,再執(zhí)行ModelDriven,因?yàn)镾ervletConfig攔截器配在ModelDriven的前面)。所以在上面的代碼中,我們才可以在getModel()方法中去拿parameterMap中的數(shù)據(jù)來(lái)進(jìn)行判斷?! ?
用下面簡(jiǎn)單的時(shí)序圖來(lái)直觀的表示一下上面的處理流程吧:
這就很直觀的看出Struts2的處理流程了,那么對(duì)于上面處理多個(gè)Model請(qǐng)求也很好理解了。到這里,Struts2處理多個(gè)Model請(qǐng)求的方法部分已經(jīng)分析完了,下面針對(duì)本項(xiàng)目中的一個(gè)小邏輯,做一下完善。
4. 完善接收數(shù)據(jù)的方法
上面遺留了一個(gè)邏輯的實(shí)現(xiàn),即處理返回的數(shù)據(jù),這里的邏輯主要有:更新訂單狀態(tài)(已付款,已發(fā)貨等),發(fā)送郵件,發(fā)送短信等。我們先把更新訂單狀態(tài)完成,主語(yǔ)發(fā)送郵件和發(fā)送短信的功能,我們后面再寫(xiě)。
先完善backBank()方法:
public void backBank() { BackData backData = (BackData)model; System.out.println(model); boolean isOK = payService.checkBackData(backData); if(isOK) { //1. 更新訂單狀態(tài),參數(shù)是自己根據(jù)數(shù)據(jù)庫(kù)中的情況傳進(jìn)去的,用來(lái)測(cè)試 forderService.updateStatusById(Integer.valueOf(201605006), 2); //2. 根據(jù)user郵箱地址,發(fā)送郵件 //3. 發(fā)送手機(jī)短信 System.out.println("----success!!----"); } else { System.out.println("----false!!!----"); } }
然后我們完成payService中的checkBackData(backData)方法(邏輯和21節(jié)中的基本一樣):
@Service("payService") public class PayServiceImpl implements PayService { //省略不相關(guān)代碼 /******************************上面是發(fā)送請(qǐng)求的方法**************************************/ // 完成返回?cái)?shù)據(jù)的追加 private String joinBackDataParam(BackData backData) { // 追加字符串,為加密驗(yàn)證做準(zhǔn)備 StringBuffer infoBuffer = new StringBuffer(); infoBuffer.append(backData.getP1_MerId()); infoBuffer.append(backData.getR0_Cmd()); infoBuffer.append(backData.getR1_Code()); infoBuffer.append(backData.getR2_TrxId()); infoBuffer.append(backData.getR3_Amt()); infoBuffer.append(backData.getR4_Cur()); infoBuffer.append(backData.getR5_Pid()); infoBuffer.append(backData.getR6_Order()); infoBuffer.append(backData.getR7_Uid()); infoBuffer.append(backData.getR8_MP()); infoBuffer.append(backData.getR9_BType()); return infoBuffer.toString(); } // 對(duì)返回來(lái)的數(shù)據(jù)進(jìn)行加密,并且和傳過(guò)來(lái)的密文進(jìn)行比較,如果OK則說(shuō)明數(shù)據(jù)沒(méi)有被篡改 public boolean checkBackData(BackData backData){ String joinParam=this.joinBackDataParam(backData); // 加密后得到自己的密文 String md5 = DigestUtil.hmacSign(joinParam.toString(),key); // 密文和傳過(guò)來(lái)密文比較 return md5.equals(backData.getHmac()); } }
最后我們完成ForderService中的updateStatusById方法:
//ForderService接口 public interface ForderService extends BaseService<Forder> { //省略其他無(wú)關(guān)代碼…… //根據(jù)訂單編號(hào),更新訂單狀態(tài) public void updateStatusById(int id, int sid); } //ForderServiceImpl實(shí)現(xiàn)類(lèi) @Service("forderService") public class ForderServiceImpl extends BaseServiceImpl<Forder> implements ForderService { //省略其他無(wú)關(guān)代碼 @Override public void updateStatusById(int id, int sid) { String hql = "update Forder f set f.status.id=:sid where f.id=:id"; getSession().createQuery(hql) .setInteger("sid", sid) .setInteger("id", id) .executeUpdate(); } }
這樣就能在顧客付款后更新訂單狀態(tài)了。
原文鏈接:http://blog.csdn.net/eson_15/article/details/51465067
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- php網(wǎng)上商城購(gòu)物車(chē)設(shè)計(jì)代碼分享
- php 網(wǎng)上商城促銷(xiāo)設(shè)計(jì)實(shí)例代碼
- struts2中action實(shí)現(xiàn)ModelDriven后無(wú)法返回json的解決方法
- java中struts2實(shí)現(xiàn)文件上傳下載功能實(shí)例解析
- SSH網(wǎng)上商城之使用ajax完成用戶(hù)名是否存在異步校驗(yàn)
- java網(wǎng)上商城開(kāi)發(fā)之郵件發(fā)送功能(全)
- SSH框架網(wǎng)上商城項(xiàng)目第1戰(zhàn)之整合Struts2、Hibernate4.3和Spring4.2
- SSH框架網(wǎng)上商城項(xiàng)目第4戰(zhàn)之EasyUI菜單的實(shí)現(xiàn)
- SSH框架網(wǎng)上商城項(xiàng)目第5戰(zhàn)之商品類(lèi)別級(jí)聯(lián)查詢(xún)和分頁(yè)功能
- SSH框架網(wǎng)上商城項(xiàng)目第8戰(zhàn)之查詢(xún)和刪除商品類(lèi)別功能實(shí)現(xiàn)
相關(guān)文章
mybatis取別名typeAliases標(biāo)簽的位置放錯(cuò)導(dǎo)致報(bào)錯(cuò)的解決
這篇文章主要介紹了mybatis取別名typeAliases標(biāo)簽的位置放錯(cuò)導(dǎo)致報(bào)錯(cuò)的解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-09-09java web將數(shù)據(jù)導(dǎo)出為pdf格式文件代碼片段
這篇文章主要為大家詳細(xì)介紹了java web將數(shù)據(jù)導(dǎo)出為pdf格式文件代碼片段,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-01-01SpringBoot2.0實(shí)現(xiàn)多圖片上傳加回顯
這兩天公司有需求讓做一個(gè)商戶(hù)注冊(cè)的后臺(tái)功能,其中需要商戶(hù)上傳多張圖片并回顯,本文就使用SpringBoot2.0實(shí)現(xiàn),具有一定的參考價(jià)值,感興趣的可以了解一下2021-07-07Java讀寫(xiě)文件創(chuàng)建文件夾多種方法示例詳解
這篇文章主要介紹了Java讀寫(xiě)文件創(chuàng)建文件夾等多種操作的方法,大家參考使用吧2013-11-11淺談在springboot中使用定時(shí)任務(wù)的方式
今天給大家?guī)?lái)的是關(guān)于Java的相關(guān)知識(shí),文章圍繞著在springboot中使用定時(shí)任務(wù)的方式展開(kāi),文中有非常詳細(xì)的介紹及代碼示例,需要的朋友可以參考下2021-06-06Activiti7與Spring以及Spring Boot整合開(kāi)發(fā)
這篇文章主要介紹了Activiti7與Spring以及Spring Boot整合開(kāi)發(fā),在Activiti中核心類(lèi)的是ProcessEngine流程引擎,與Spring整合就是讓Spring來(lái)管理ProcessEngine,有感興趣的同學(xué)可以參考閱讀2023-03-03