欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

SSH框架網(wǎng)上商城項目第24戰(zhàn)之Struts2中處理多個Model請求的方法

 更新時間:2016年06月06日 15:33:21   作者:eson_15  
這篇文章主要為大家詳細介紹了SSH框架網(wǎng)上商城項目第24戰(zhàn)之Struts2中處理多個Model請求的方法,感興趣的小伙伴們可以參考一下

1. 問題的提出

  Struts2中如果實現(xiàn)了ModelDriven<model>接口就可以將傳來的參數(shù)注入到model中了,就可以在Action中使用該model,但是如果現(xiàn)在有兩個model都需要在同一個Action中使用該咋整呢?比如上一節(jié)我們完成了在線支付功能,但是支付完成了還沒結束,我們需要接收從第三方那邊反饋回來的信息,比如成功支付后,我們需要給付款方發(fā)送郵件和短信等。所以我們還需要在payAction中獲取從第三方傳過來的參數(shù),由于從第三方傳過來的參數(shù)與我們傳過去的參數(shù)是不同的,所以接收那些參數(shù)我們也得寫一個Model(BackData),那么問題來了,我們的PayAction已經(jīng)寫成這樣子了:public class PayAction extends BaseAction<SendData>,即已經(jīng)在BaseAction中實現(xiàn)了ModelDriven<SendData>接口了,那么如何在一個action中再接收一個Model,并且還得對它們進行不同的處理呢?
  有種解決辦法(其實也不能稱為解決辦法……因為根本就沒解決……)就是寫一個Model,然后讓SendData和BackData繼承它,但是問題是這兩個Model根本就沒關系,為啥要繼承同一個Model,所以這種解決辦法實際上是在逃避上面的問題。
  在SpringMVC(SpringMVC還沒真正開始學,如果有說錯,請指正!)很好的解決了這個問題,因為SpringMVC中每個方法對應一個Model,而不是每個Action對應一個Model,這就方便了,我在同一個Action中寫兩個方法即可,不同的方法處理不同的Model。

2. 問題的解決

  針對這個問題,Struts2也提供了一種解決辦法:
  Struts2在ActionContext中存儲了很多個Map,比如之前提到的request, session, application等,其中還有個parameterMap,該Map中存儲了request所有的請求參數(shù),只要我們的Action實現(xiàn)了parameterAware接口,就能拿到這個parameterMap,這就跟ModelDriven的道理是一樣的,如果我們實現(xiàn)了ModelDriven<Model>接口,那么我們在Action中就能獲得該Model,即定義一個Model并實現(xiàn)set方法即可。
  好了,那現(xiàn)在問題好辦了,支付的參數(shù)和返回的參數(shù)是不同的,也就是說兩次進入PayAcition中的參數(shù)是不同的,即兩次的parameterMap中裝的數(shù)據(jù)不一樣,那只要我們在Action中選取一個參數(shù)(該參數(shù)只要能區(qū)分兩次是不同的request請求即可)作為判斷,就知道當前該用哪個Model來接收參數(shù)(SendData還是BackData)。下面我們改寫一下PayAction中的代碼:

@Controller("payAction")
@Scope("prototype")
public class PayAction extends BaseAction<Object> implements ParameterAware {
//注意上面繼承的BaseAction中不能寫SendData了,要寫Object,等下我們再判斷具體使用哪個 

 //定義一個Map接收request的請求參數(shù)
 private Map<String, String[]> parameters;
 @Override
 public void setParameters(Map<String, String[]> parameters) {
  this.parameters = parameters;

 } 
 /*在struts-default.xml文中,ServletConfig攔截器在ModelDriven之前先執(zhí)行,所以我們在注入model的時候,
 request參數(shù)已經(jīng)有了,這樣我們就可以在getModel()方法中通過參數(shù)來判斷是哪個請求了*/
 @Override
 public Object getModel() {
 //付款的時候有支付通道編碼的參數(shù)(pd_FrpId),返回的時候沒有
 //這樣我們就可以通過該參數(shù)判斷是支付還是返回了
  if(parameters.get("pd_FrpId") != null) {
   model = new SendData();
  } else {
   model = new BackData();
  }
  return model;
 }

 //向易寶發(fā)送數(shù)據(jù)的方法
 public String goBank() {
  //對應發(fā)送的model:SendData
  SendData sendData = (SendData)model;
  //處理發(fā)送數(shù)據(jù)的邏輯,前一節(jié)已經(jīng)實現(xiàn)過了……
 }

 //接收返回的數(shù)據(jù)的方法
 public void backBank() {
  //對應接收的model:BackData
  BackData backData = (BackData)model;
  //處理返回數(shù)據(jù)的邏輯……后面再來實現(xiàn),
  //先講Struts2處理多個Model請求這個知識點
 }
}

3. Struts2的處理流程

  我們再來分析一下Struts2的執(zhí)行流程,這樣更加利于理解上面的原理。Struts處理流程:

1)、獲取請求后,先創(chuàng)建Action的代理,在創(chuàng)建代理的時候順便創(chuàng)建了Action;
2)、執(zhí)行18個攔截器,攔截器執(zhí)行成功后再調用Action的方法;
3)、Action的方法執(zhí)行完畢后,再調用18個攔截器
所以根據(jù)這個流程,我們知道:先創(chuàng)建Action–>再執(zhí)行攔截器(先執(zhí)行ServletConfig,再執(zhí)行ModelDriven,因為ServletConfig攔截器配在ModelDriven的前面)。所以在上面的代碼中,我們才可以在getModel()方法中去拿parameterMap中的數(shù)據(jù)來進行判斷?! ?
  用下面簡單的時序圖來直觀的表示一下上面的處理流程吧:

這就很直觀的看出Struts2的處理流程了,那么對于上面處理多個Model請求也很好理解了。到這里,Struts2處理多個Model請求的方法部分已經(jīng)分析完了,下面針對本項目中的一個小邏輯,做一下完善。

4. 完善接收數(shù)據(jù)的方法

  上面遺留了一個邏輯的實現(xiàn),即處理返回的數(shù)據(jù),這里的邏輯主要有:更新訂單狀態(tài)(已付款,已發(fā)貨等),發(fā)送郵件,發(fā)送短信等。我們先把更新訂單狀態(tài)完成,主語發(fā)送郵件和發(fā)送短信的功能,我們后面再寫。
先完善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ù)庫中的情況傳進去的,用來測試
  forderService.updateStatusById(Integer.valueOf(201605006), 2);
  //2. 根據(jù)user郵箱地址,發(fā)送郵件
  //3. 發(fā)送手機短信
  System.out.println("----success!!----");
 } else {
  System.out.println("----false!!!----");
 }
}

然后我們完成payService中的checkBackData(backData)方法(邏輯和21節(jié)中的基本一樣):

@Service("payService")
public class PayServiceImpl implements PayService {
  //省略不相關代碼
  /******************************上面是發(fā)送請求的方法**************************************/
  // 完成返回數(shù)據(jù)的追加
  private String joinBackDataParam(BackData backData) {
   // 追加字符串,為加密驗證做準備
   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();
  }

  // 對返回來的數(shù)據(jù)進行加密,并且和傳過來的密文進行比較,如果OK則說明數(shù)據(jù)沒有被篡改
  public boolean checkBackData(BackData backData){
   String joinParam=this.joinBackDataParam(backData);
   // 加密后得到自己的密文
   String md5 = DigestUtil.hmacSign(joinParam.toString(),key);
   // 密文和傳過來密文比較
   return md5.equals(backData.getHmac());
  } 
}

最后我們完成ForderService中的updateStatusById方法:

//ForderService接口
public interface ForderService extends BaseService<Forder> {
 //省略其他無關代碼……
 //根據(jù)訂單編號,更新訂單狀態(tài)
 public void updateStatusById(int id, int sid);
}

//ForderServiceImpl實現(xiàn)類
@Service("forderService")
public class ForderServiceImpl extends BaseServiceImpl<Forder> implements ForderService {

 //省略其他無關代碼

 @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

以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。

相關文章

最新評論