struts拦截器运用

最近闲来无事,从网上download struts2的源代码来看看,由于这里讲的是拦截器机制,我们直接进入DefaultActionInvocation类的核心方法invoke

注:本人语言表达能力一般,技术一般,属于刚毕业的菜鸟,有错的地方还请前辈大牛们多多指定



 

 

 我们知道Invocation是struts2是核心调试器,在这个类中,可以看到invoke方法依次迭代拦截器有(上图黄色部分)



 

,最后执行invokeActionOnly方法(红色部分,在invokeActonOlny中实例化我们定义的Action类,通过方法反射调用我们在Action中业务逻辑方法。这里不多讲)

 

struts2源代码就到这里,我们来看一张被大家经常使用的struts2执行流程图



 

 

图中红色圈圈部分对应上面的DefaultActionInvocation类,我们看到一个拦截器包围另一个拦截器,层层包围,最后到最里面的Action层,但具体代码该怎么写呢,上面的代码太复杂,我们把它简化一下

 

 

来我们来用最简单的代码演示

 

package com.jetway.gateway.system.utils.test;

import java.util.Iterator;

public class MyInvocation {
	private Iterator<Interceptor> interceptors;

	public String invoke() {
		if (interceptors.hasNext()) {
			Interceptor interceptor = interceptors.next();
			return interceptor.interceptor(MyInvocation.this);
		}
		return "success";

	}
}

class Interceptor {

	public String interceptor(MyInvocation invocation) {
		// 在这里做拦截,如果想继续执行后面的拦截器继续就调用invocation.invke(),
                 //也可以直接返回一个字符串,后面的拦截器将不再执行,
              return invocation.invoke();  
		//如果这样还不好理解,那就这样写
                 //   String result=invocation.invoke;
              // return result;

	}

}

 

这样就更清晰了,上面的代码我想大家都会写,仔细琢磨,好像跟有策略模式很像(本人也不怎么懂设计模式,姑且这样称呼)
这又让我们想起了前不久我在iteye上提的一个问题,怎么消除代码中过多的if{}else{},来看看我之前贴的代码
@Description(info = "登陆系统", actionId = "1")
	public String login() {

		boolean loginpass = false;
		Pckey pckey = null;
		// 密码验证标识
		int validate = 0;
		Integer keyright = 1;
		HttpServletRequest request = ServletActionContext.getRequest();
		String passFlag = request.getParameter("validate");
		if (StringUtils.isNotEmpty(passFlag)) {
			validate = Integer.parseInt(passFlag);
		}
		if (StringUtils.isNotEmpty(username)) {
			keyright = Integer.parseInt(userright);
			pckey = pckeyService.findKey(username, keyright);
		}
		if (pckey != null) {
			boolean locked = pckeyService.isLocked(pckey);
			// 没锁定
			if (!locked) {

				if (pckeyService.reachMaxCount(pckey)) {
					pckeyService.clearErrorCount(pckey);
				}
				// 验证密码标识
				if (validate == 100) {
					pckeyService.clearErrorCount(pckey);
					HttpSession session = ServletActionContext.getRequest()
							.getSession();
					session.setAttribute("keyname", username);
					session.setAttribute("keyright", userright);
					Calendar c = Calendar.getInstance();
					c.add(Calendar.HOUR_OF_DAY, 10);
					session.setAttribute("logintime", c.getTime().toString());
					loginpass = true;
				} else {

					int errorCount = pckeyService.addErrorCount(pckey);
					if (errorCount > 0) {
						msg = "密码错误,剩余<font style='font-size:18px;font-weight:bold;'>"
								+ errorCount + "</font>次key将被锁定";
					} else {
						msg = "密码错误,此key已被限制登陆," + pckey.getLimitdate()
								+ "分钟后系统自动解锁";
						pckeyService.setLockDate(pckey);
					}
				}
			} else {
				// 锁定
				msg = "此key已经被锁定,您无法登陆系统";
			}
		} else {
			// key 不合法
			msg = "请插入合法key";
		}

		return loginpass == true ? SUCCESS : "error";
	}
 
一个简单的登陆验证功能,代码中充斥着if,else,很不好读。怎样模仿struts2的拦截器让上面的代码看起来更beautiful些呢
可以这样(不管是不是策略模式,小弟在这里就借用一下命名哈)
1:定义一个策略接口(里面只有一个execute方法)
package com.jetway.gateway.system.utils.test;

public interface Strategy {
	public String execute(StrategyExecutor executor);

}
 
2.定义一个策略执行者类(实际上也就是struts2中的调度者),假设如果所有验证都通过,则返回"success",如果有一个验证不通过,则返回对应的错误信息
package com.jetway.gateway.system.utils.test;

import java.util.Arrays;
import java.util.Iterator;
import java.util.List;

public class StrategyExecutor {
	private Iterator<Strategy> sIterator;

	public StrategyExecutor(Strategy... strategies) {
		if (strategies.length > 0) {
			List<Strategy> list = Arrays.asList(strategies);
			sIterator = list.iterator();
		}
	}

	public String invoke() {
		if (sIterator != null) {
			if (sIterator.hasNext()) {
				Strategy strategy = sIterator.next();
				return strategy.execute(StrategyExecutor.this);
			}
		}
		return "success";
	}
}
 
3.定义两个策略实现类,也就是具体的验证逻辑,比如验证密码,登陆次数,,这里只是简单模拟
 
a.用户名密码验证
package com.jetway.gateway.system.utils.test;

import org.apache.commons.lang.StringUtils;

public class AuthorityStraty implements Strategy {
	private String name;
	private String pwd;

	public AuthorityStraty(String name, String pwd) {
		this.name = name;
		this.pwd = pwd;
	}

	public String execute(StrategyExecutor executor) {
		
		// demo
		if (StringUtils.isNotBlank(name) && StringUtils.isNotBlank(pwd)
				&& name.equals("11") && pwd.equals("11")) {
			return executor.invoke();
		}
		return "用户名或密码错误";
	}
 
b.再来一个时间验证
package com.jetway.gateway.system.utils.test;

public class TimeOutStrategy implements Strategy {

	private int hours;

	public TimeOutStrategy(int hours) {
		this.hours = hours;
	}

	public String execute(StrategyExecutor executor) {
		if (hours > 9) {
			return executor.invoke();
		}
		return "时间不能小于9小时";

	}

}
 
4:最后就是我们的客户端调用
package com.jetway.gateway.system.utils.test;

public class Client {

	public static void main(String[] args) {

		Strategy logincheck = new AuthorityStraty("11", "11");
		Strategy timecheck = new TimeOutStrategy(10);
		String resultInfo = new StrategyExecutor(logincheck, timecheck)
				.invoke();
		System.out.println(resultInfo);

	}

}
 
在不改变代码的情况下,我们可以添加,删除任意接口实现,并且业务逻辑更清晰。
 
 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值