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

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中的数据来进行判断。  
  用下面简单的时序图来直观的表示一下上面的处理流程吧:

这就很直观的看出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

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • SSH框架网上商城项目第5战之商品类别级联查询和分页功能

    上文我们完成了EasyUI菜单的实现,点击这里查看,这一节我们主要来写一下CategoryServiceImpl实现类,完成数据库的级联查询.一般项目从后往前做,先做service(我们没有抽取Dao,最后再抽取),做完了再做上面层. 在写之前,先看一下数据库中的表的情况: drop database if exists shop; /*创建数据库,并设置编码*/ create database shop default character set utf8; use shop; /*删除管理员

  • php 网上商城促销设计实例代码

    大体的思想,每一个促销要新建一个促销类,有专门的开关来控制是否生效. 用商品里面的促销识别码来判断具体调用哪一个促销实例. 首先,在添加商品的时候,分两步,第一步是添加状态,第二步是把购物车内的商品显示这个状态. 一,添加步骤几个重要的点: 1,添加商品之前,遍历所有的促销互斥条件. 例如,某一款商品不可以和另一个商品同时在一个购物车内:或者某个用户权限,不可以购买特定的一件商品等等. 2,添加商品之前,选择特定的促销实例,来进行添加之前的操作. 注:第二点与第一点的区别在于1是要遍历所有的促销

  • SSH框架网上商城项目第8战之查询和删除商品类别功能实现

    上一节我们完成了使用DataGrid显示所有商品信息,这节我们开始添加几个功能:添加.更新.删除和查询.首先我们实现下前台的显示,然后再做后台获取数据. 1. 添加.更新.删除和查询功能的前台实现 DataGrid控件里有个toolbar属性,是添加工具栏的,我们可以在toolbar属性中添加这些按钮来实现相应的功能.先看一下官方文档对toolbar的定义: 我们使用数组的方式定义工具栏,在query.jsp页面中新添加如下代码: <%@ page language="java"

  • java网上商城开发之邮件发送功能(全)

    最近在学习网上商城时,接触到了一个邮件发送的功能.之前一直在使用邮箱进行发送邮件,但是其中的具体如何运转的却不知道是怎么回事.那么邮件发送究竟是怎么一回事呢? 邮件发送过程: 过程描述:首先是发送人将邮件通过客户端软件发送到特定的服务器上,然后通过电子邮件简单传输协议(SMTP)来进行传输,收件人通过POP3协议将邮件从服务器上接受回来.这样就实现了邮件之间的相互传送. 实现过程: 在有网络的情况下,我们可以直接使用搜狐.网易等邮箱进行发送.那么如何在没有网络的情况下,实现内部之间的发送呢? 首

  • php网上商城购物车设计代码分享

    首先,购物车的数据库设计: 1. id 2. goods_id 商品ID 3. session_id 购物车ID 4. goods_sn 商品编码 5. goods_name 商品名称 6. shop_price 商品商城售价 7. goods_price 商品真实售价(与shop_price的区别在于,当打折的时候,shop_price是打折之前商品的售价,而goods_price是打折之后的) 8. goods_number 数量 9. weight 商品重量 10. goods_attr

  • SSH网上商城之使用ajax完成用户名是否存在异步校验

    小伙伴在上网的时候,需要下载或者观看某些视频资料,更或者是在逛淘宝的时候,我们都需要注册一个用户,当我们填写好各种信息,点击确定的时候,提示用户名已经存在,小编就想,为什么当我们填写完用户名的时候,她就自动提示用户名已经存在,我们也不需要浪费那么多感情,直到填写完那么多的信息之后在提示,在小编最近的项目中,就碰到这个问题,我们可以使用ajax完成用户名是否存在,今天这篇博客,小编就简单的总结一下,如何使用ajax来完成校验,还请小伙伴多多指教哦`(*∩_∩*)′! 首先ajax完成用户名是否存在

  • struts2中action实现ModelDriven后无法返回json的解决方法

    复制代码 代码如下: public class DeviceAction extends AbstractAction implements ModelDriven<Device> {    private static Log log = LogFactory.getLog(DeviceAction.class);    private Device device=new Device(); //只能json化 模型驱动的bean    private String result; //无法

  • java中struts2实现文件上传下载功能实例解析

    本文实例讲述了java中struts2实现文件上传下载功能实现方法.分享给大家供大家参考.具体分析如下: 1.文件上传 首先是jsp页面的代码 在jsp页面中定义一个上传标签 复制代码 代码如下: <tr>      <td align="right" bgcolor="#F5F8F9"><b>附件:</b></td>      <td bgcolor="#FFFFFF">

  • SSH框架网上商城项目第1战之整合Struts2、Hibernate4.3和Spring4.2

    本文开始做一个网上商城的项目,首先从搭建环境开始,一步步整合S2SH.这篇博文主要总结一下如何整合Struts2.Hibernate4.3和Spring4.2. 整合三大框架得先从搭建各部分环境开始,也就是说首先得把Spring,Hibernate和Struts2的环境搭建好,确保它们没有问题了,再做整合.这篇博文遵从的顺序是:先搭建Spring环境-->然后搭建Hibernate环境--> 整合Spring和Hibernate --> 搭建Struts2环境 --> 整合Spri

  • SSH框架网上商城项目第4战之EasyUI菜单的实现

    上篇文章我们使用EasyUI搭建了后台页面的框架,点击这里查看,这一节我们主要使用EasyUI技术简单实现后台菜单,先将简单功能做出来,后期再继续丰富. 1. 实现左侧菜单 首先看一下效果图: 我们可以点击"基本操作"和"其他操作"来切换菜单选项,在具体的选项内,点击不同的连接,会在右侧显示出来.我们先把左边的菜单做出来. 左侧菜单内容主要有两个:"类别管理"和"商品管理".我们知道,上一节中,在aindex.jsp中应将后台

随机推荐