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

来源:互联网 发布:高洛峰 细说php 编辑:程序博客网 时间:2024/05/22 16:45

      做系统经常会碰到一些运营人员在后台频繁查询海量数据的操作,导致生产环境奔溃的情况。除了对数据库做优化,已及对查询时间跨度做限制外, 还有一个可行的方法,就是对 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;@Overrideprotected 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 {// 计数增加1count.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 {// 执行完后减少1count.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秒的查询操作进行记录,加以警示。



原创粉丝点击