通过拦截器对 struts2 的action操作进行监控和限制。 (管理端限制频繁查询操作)

      做系统经常会碰到一些运营人员在后台频繁查询海量数据的操作,导致生产环境奔溃的情况。除了对数据库做优化,已及对查询时间跨度做限制外, 还有一个可行的方法,就是对 action操作数做限制。

      既然都是程序员,还是贴代码直观,  直接上代码。

拦截器类  QueryLimitInterceptor   其中sesison中的operNo是用户名。

public class QueryLimitInterceptor extends MethodFilterInterceptor {

	private static final long serialVersionUID = 1L;

	private static final int LIMIT_COUNT = 1;
	private static final String RETURN_MSG = "您的前一个查询未完成,请不要频繁查询";
	private static final int SLOW_TIME = 30;

	@Override
	protected String doIntercept(ActionInvocation arg0) throws Exception {
		HttpSession session = ServletActionContext.getRequest().getSession();
		String operNo = (String) session.getAttribute("operNo");
		String url = ServletActionContext.getRequest().getRequestURI();
		AtomicInteger count = null;
		long time1 = System.currentTimeMillis();
		if (!"".equals(operNo)) {
			if (session.getAttribute("queryLimit") != null
					&& session.getAttribute("queryLimit") instanceof AtomicInteger) {
				count = (AtomicInteger) session.getAttribute("queryLimit");
				if (count.get() >= LIMIT_COUNT) {
					// 限制当前查询不能超过最大查询;
					System.out.println(operNo +  " " + url + " 当前查询数 " + count.get()
							+ " 限制查询");
					return returnError(ServletActionContext.getRequest());
				} else {
					// 计数增加1
					count.incrementAndGet();
					System.out.println(operNo +  " " + url + " 当前查询数 " + count.get());
				}
			} else {
				synchronized (session) {
					if (session.getAttribute("queryLimit") == null) {
						count = new AtomicInteger(1);
						System.out.println(operNo +  " " + url + " 当前初始化查询数 " + count.get());
						session.setAttribute("queryLimit", count);
					}
				}
			}
		}
		String result = null;
		try {
			result = arg0.invoke();
		} finally {
			// 执行完后减少1
			count.decrementAndGet();
			System.out.println(operNo +  " " + url + " 执行后查询数 " + count.get());
			long time2 = System.currentTimeMillis();
			if ((time2 - time1)/1000 >= SLOW_TIME ) {
				System.out.println(operNo +  " " + url + " 慢查询操作,耗时 " + (time2 - time1)/1000 + "秒");
			}
		}
		return result;
	}

	private String returnError(HttpServletRequest request) {
		request.setAttribute("errorMsg", "<script language=javascript>alert('"
				+ RETURN_MSG + "');history.back()</script>");
		return "errorMsg";
	}
}

配置文件 struts2.xml    其中 includeMethods里包含的都是要做查询限制的action方法。  


<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
    "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
    "http://struts.apache.org/dtds/struts-2.0.dtd">

<struts>
	<package name="basePackage" extends="struts-default">
		<interceptors>
			<interceptor name="queryLimt"
			class="com.kanesoft.interceptor.QueryLimitInterceptor" />			
			<interceptor-stack name="mydefault">
				<interceptor-ref name="defaultStack" />
				<interceptor-ref name="queryLimt" >
					 <param name="includeMethods">frzBillList,acctInfoList,getPayBillList,queryINBill,queryDetail,getOrderFile,transDetail</param>
				</interceptor-ref>
			</interceptor-stack>
		</interceptors>
		<default-interceptor-ref name="mydefault" />
	</package>
<struts>	


最终实现的效果就是 用户做一次查询,如果查询时间较长,然后用户再一次做查询,系统则会对提示“您的前一个查询未完成,请不要频繁查询”的提示,并终止操作。

另外一功能便是对 操作员,操作URL 和超过30秒的查询操作进行记录,加以警示。



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值