【SSH网上商城项目实战24】Struts2中如何处理多个Model请求
2017-01-13 08:38
465 查看
目录(?)[+]
问题的提出
问题的解决
Struts2的处理流程
完善接收数据的方法
Struts2中如果实现了
有种解决办法(其实也不能称为解决办法……因为根本就没解决……)就是写一个Model,然后让
在SpringMVC(SpringMVC还没真正开始学,如果有说错,请指正!)很好的解决了这个问题,因为SpringMVC中每个方法对应一个Model,而不是每个Action对应一个Model,这就方便了,我在同一个Action中写两个方法即可,不同的方法处理不同的Model。
针对这个问题,Struts2也提供了一种解决办法:
Struts2在
好了,那现在问题好办了,支付的参数和返回的参数是不同的,也就是说两次进入
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
[/code]
我们再来分析一下Struts2的执行流程,这样更加利于理解上面的原理。Struts处理流程:
获取请求后,先创建Action的代理,在创建代理的时候顺便创建了Action;
执行18个拦截器,拦截器执行成功后再调用Action的方法;
Action的方法执行完毕后,再调用18个拦截器
所以根据这个流程,我们知道:先创建Action–>再执行拦截器(先执行
用下面简单的时序图来直观的表示一下上面的处理流程吧:
Created with Raphaël 2.1.0struts2启动struts2启动Action代理和Action对象Action代理和Action对象18个拦截器18个拦截器创建按顺序执行执行其他拦截器……执行ServletConfig拦截器,将request参数放到parameterMap中执行ModelDriven拦截器,初始化model(我们就在这里拿上面参数进行判断的)执行其他拦截器……再去执行Action中相应的方法再按顺序执行一次拦截器
这就很直观的看出Struts2的处理流程了,那么对于上面处理多个Model请求也很好理解了。到这里,Struts2处理多个Model请求的方法部分已经分析完了,下面针对本项目中的一个小逻辑,做一下完善。
上面遗留了一个逻辑的实现,即处理返回的数据,这里的逻辑主要有:更新订单状态(已付款,已发货等),发送邮件,发送短信等。我们先把更新订单状态完成,主语发送邮件和发送短信的功能,我们后面再写。
先完善
2
3
4
5
6
7
8
9
10
11
12
13
14
1
2
3
4
5
6
7
8
9
10
11
12
13
14
[/code]
然后我们完成payService中的
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
[/code]
最后我们完成ForderService中的
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
[/code]
这样就能在顾客付款后更新订单状态了。
相关阅读:http://blog.csdn.net/column/details/str2hiberspring.html
整个项目的源码下载地址:http://blog.csdn.net/eson_15/article/details/51479994
—–乐于分享,共同进步!
—–更多文章请看:http://blog.csdn.net/eson_15
(function () {('pre.prettyprint code').each(function () {
var lines = (this).text().split(′\n′).length;varnumbering = $('').addClass('pre-numbering').hide();
(this).addClass(′has−numbering′).parent().append(numbering);
for (i = 1; i
问题的提出
问题的解决
Struts2的处理流程
完善接收数据的方法
1. 问题的提出 |
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在
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请求这个知识点 } }1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
[/code]
3. Struts2的处理流程 |
获取请求后,先创建Action的代理,在创建代理的时候顺便创建了Action;
执行18个拦截器,拦截器执行成功后再调用Action的方法;
Action的方法执行完毕后,再调用18个拦截器
所以根据这个流程,我们知道:先创建Action–>再执行拦截器(先执行
ServletConfig,再执行
ModelDriven,因为
ServletConfig拦截器配在
ModelDriven的前面)。所以在上面的代码中,我们才可以在
getModel()方法中去拿
parameterMap中的数据来进行判断。
用下面简单的时序图来直观的表示一下上面的处理流程吧:
Created with Raphaël 2.1.0struts2启动struts2启动Action代理和Action对象Action代理和Action对象18个拦截器18个拦截器创建按顺序执行执行其他拦截器……执行ServletConfig拦截器,将request参数放到parameterMap中执行ModelDriven拦截器,初始化model(我们就在这里拿上面参数进行判断的)执行其他拦截器……再去执行Action中相应的方法再按顺序执行一次拦截器
这就很直观的看出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!!!----"); } }1
2
3
4
5
6
7
8
9
10
11
12
13
14
1
2
3
4
5
6
7
8
9
10
11
12
13
14
[/code]
然后我们完成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()); } }1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
[/code]
最后我们完成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(); } }1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
[/code]
这样就能在顾客付款后更新订单状态了。
相关阅读:http://blog.csdn.net/column/details/str2hiberspring.html
整个项目的源码下载地址:http://blog.csdn.net/eson_15/article/details/51479994
—–乐于分享,共同进步!
—–更多文章请看:http://blog.csdn.net/eson_15
(function () {('pre.prettyprint code').each(function () {
var lines = (this).text().split(′\n′).length;varnumbering = $('').addClass('pre-numbering').hide();
(this).addClass(′has−numbering′).parent().append(numbering);
for (i = 1; i
相关文章推荐
- 【SSH网上商城项目实战24】Struts2中如何处理多个Model请求
- 【SSH网上商城项目实战24】Struts2中如何处理多个Model请求
- 【SSH网上商城项目实战24】Struts2中如何处理多个Model请求
- SSH框架网上商城项目第24战之Struts2中处理多个Model请求的方法
- 【SSH网上商城项目实战07】Struts2和Json的整合
- 【SSH网上商城项目实战01】整合Struts2、Hibernate4.3和Spring4.2
- 【SSH网上商城项目实战13】Struts2实现文件上传功能
- 【SSH网上商城项目实战13】Struts2实现文件上传功能
- 【SSH网上商城项目实战13】Struts2实现文件上传功能
- 【SSH网上商城项目实战16】Hibernate的二级缓存处理首页的热门显示
- 【SSH网上商城项目实战07】Struts2和Json的整合
- 【SSH网上商城项目实战07】Struts2和Json的整合
- 【SSH网上商城项目实战16】Hibernate的二级缓存处理首页的热门显示
- 【SSH网上商城项目实战01】整合Struts2、Hibernate4.3和Spring4.2
- 【SSH网上商城项目实战01】整合Struts2、Hibernate4.3和Spring4.2
- 【SSH网上商城项目实战01】整合Struts2、Hibernate4.3和Spring4.2(转载)
- 【SSH网上商城项目实战13】Struts2实现文件上传功能
- 【SSH网上商城项目实战16】Hibernate的二级缓存处理首页的热门显示
- 【SSH网上商城项目实战01】整合Struts2、Hibernate4.3和Spring4.2
- 【SSH网上商城项目实战16】Hibernate的二级缓存处理首页的热门显示