SSH框架网上商城项目第24战之Struts2中处理多个Model请求的方法

作者:eson_15 时间:2023-02-14 20:49:21 

1. 问题的提出

Struts2中如果实现了ModelDriven<model>接口就可以将传来的参数注入到model中了,就可以在Action中使用该model,但是如果现在有两个model都需要在同一个Action中使用该咋整呢?比如上一节我们完成了在线支付功能,但是支付完成了还没结束,我们需要接收从第三方那边反馈回来的信息,比如成功支付后,我们需要给付款方发送邮件和短信等。所以我们还需要在payAction中获取从第三方传过来的参数,由于从第三方传过来的参数与我们传过去的参数是不同的,所以接收那些参数我们也得写一个Model(BackData),那么问题来了,我们的PayAction已经写成这样子了:public class PayAction extends BaseAction<SendData>,即已经在BaseAction中实现了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所有的请求参数,只要我们的Action实现了parameterAware接口,就能拿到这个parameterMap,这就跟ModelDriven的道理是一样的,如果我们实现了ModelDriven<Model>接口,那么我们在Action中就能获得该Model,即定义一个Model并实现set方法即可。
好了,那现在问题好办了,支付的参数和返回的参数是不同的,也就是说两次进入PayAcition中的参数是不同的,即两次的parameterMap中装的数据不一样,那只要我们在Action中选取一个参数(该参数只要能区分两次是不同的request请求即可)作为判断,就知道当前该用哪个Model来接收参数(SendData还是BackData)。下面我们改写一下PayAction中的代码:


@Controller("payAction")
@Scope("prototype")
public class PayAction extends BaseAction<Object> implements ParameterAware {
//注意上面继承的BaseAction中不能写SendData了,要写Object,等下我们再判断具体使用哪个

//定义一个Map接收request的请求参数
private Map<String, String[]> parameters;
@Override
public void setParameters(Map<String, String[]> parameters) {
 this.parameters = parameters;

}
/*在struts-default.xml文中,ServletConfig * 在ModelDriven之前先执行,所以我们在注入model的时候,
request参数已经有了,这样我们就可以在getModel()方法中通过参数来判断是哪个请求了*/
@Override
public Object getModel() {
//付款的时候有支付通道编码的参数(pd_FrpId),返回的时候没有
//这样我们就可以通过该参数判断是支付还是返回了
 if(parameters.get("pd_FrpId") != null) {
  model = new SendData();
 } else {
  model = new BackData();
 }
 return model;
}

//向易宝发送数据的方法
public String goBank() {
 //对应发送的model:SendData
 SendData sendData = (SendData)model;
 //处理发送数据的逻辑,前一节已经实现过了……
}

//接收返回的数据的方法
public void backBank() {
 //对应接收的model:BackData
 BackData backData = (BackData)model;
 //处理返回数据的逻辑……后面再来实现,
 //先讲Struts2处理多个Model请求这个知识点
}
}

3. Struts2的处理流程

我们再来分析一下Struts2的执行流程,这样更加利于理解上面的原理。Struts处理流程:

1)、获取请求后,先创建Action的代理,在创建代理的时候顺便创建了Action;
2)、执行18个 * , * 执行成功后再调用Action的方法;
3)、Action的方法执行完毕后,再调用18个 *
所以根据这个流程,我们知道:先创建Action–>再执行 * (先执行ServletConfig,再执行ModelDriven,因为ServletConfig * 配在ModelDriven的前面)。所以在上面的代码中,我们才可以在getModel()方法中去拿parameterMap中的数据来进行判断。
用下面简单的时序图来直观的表示一下上面的处理流程吧:

SSH框架网上商城项目第24战之Struts2中处理多个Model请求的方法

这就很直观的看出Struts2的处理流程了,那么对于上面处理多个Model请求也很好理解了。到这里,Struts2处理多个Model请求的方法部分已经分析完了,下面针对本项目中的一个小逻辑,做一下完善。

4. 完善接收数据的方法

上面遗留了一个逻辑的实现,即处理返回的数据,这里的逻辑主要有:更新订单状态(已付款,已发货等),发送邮件,发送短信等。我们先把更新订单状态完成,主语发送邮件和发送短信的功能,我们后面再写。
先完善backBank()方法:


public void backBank() {
BackData backData = (BackData)model;
System.out.println(model);
boolean isOK = payService.checkBackData(backData);
if(isOK) {
 //1. 更新订单状态,参数是自己根据数据库中的情况传进去的,用来测试
 forderService.updateStatusById(Integer.valueOf(201605006), 2);
 //2. 根据user邮箱地址,发送邮件
 //3. 发送手机短信
 System.out.println("----success!!----");
} else {
 System.out.println("----false!!!----");
}
}

然后我们完成payService中的checkBackData(backData)方法(逻辑和21节中的基本一样):


@Service("payService")
public class PayServiceImpl implements PayService {
 //省略不相关代码
 /******************************上面是发送请求的方法**************************************/
 // 完成返回数据的追加
 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();
 }

// 对返回来的数据进行加密,并且和传过来的密文进行比较,如果OK则说明数据没有被篡改
 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> {
//省略其他无关代码……
//根据订单编号,更新订单状态
public void updateStatusById(int id, int sid);
}

//ForderServiceImpl实现类
@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();
}
}

这样就能在顾客付款后更新订单状态了。

原文链接:http://blog.csdn.net/eson_15/article/details/51465067

标签:SSH,框架,网上商城,Struts2,Model
0
投稿

猜你喜欢

  • Android百度地图定位、显示用户当前位置

    2021-08-20 04:47:05
  • Spring Cloud Zuul路由网关服务过滤实现代码

    2021-08-26 10:56:07
  • Android实现EditText图文混合插入上传功能

    2022-08-27 10:19:50
  • 基于Luhn算法的银行卡校验规则

    2022-06-05 00:56:15
  • C#绘制飞行棋地图小程序

    2021-11-20 23:19:10
  • C++形参与实参的区别实例解析

    2023-11-02 23:39:05
  • Java中Elasticsearch 实现分页方式(三种方式)

    2022-03-04 06:19:08
  • spring 注解如何开启声明式事务

    2023-04-09 23:07:42
  • Android开发之ProgressBar字体随着进度条的加载而滚动

    2023-12-28 03:06:53
  • Spring MVC入门_动力节点Java学院整理

    2023-11-03 20:35:31
  • AJAX SpringBoot 前后端数据交互的项目实现

    2023-11-24 05:49:48
  • android开发教程之实现listview下拉刷新和上拉刷新效果

    2022-07-29 20:42:42
  • Java 实现微信和支付宝支付功能

    2023-03-08 23:18:04
  • C# datagridview、datagrid、GridControl增加行号代码解析

    2023-02-03 10:42:56
  • 使用GSON库将Java中的map键值对应结构对象转换为JSON

    2022-10-21 14:51:47
  • C#检测是否有危险字符的SQL字符串过滤方法

    2023-10-11 12:48:48
  • Android实现Back功能代码片段总结

    2021-05-27 01:33:06
  • C# 鼠标穿透窗体功能的实现方法

    2021-09-26 04:24:38
  • Android入门简单实例

    2021-07-26 16:34:04
  • C#中使用ADOMD.NET查询多维数据集的实现方法

    2023-10-27 05:38:15
  • asp之家 软件编程 m.aspxhome.com