1
2
3
4
5 package gboat2.base.plugin.struts.interceptor;
6
7 import gboat2.base.bridge.GboatAppContext;
8 import gboat2.base.plugin.exception.InternalInvalidException;
9
10 import java.util.HashSet;
11 import java.util.Set;
12 import java.util.regex.Pattern;
13
14 import javax.servlet.http.HttpServletRequest;
15 import javax.servlet.http.HttpSession;
16
17 import org.apache.commons.collections.map.LRUMap;
18 import org.apache.commons.lang3.StringUtils;
19 import org.apache.commons.lang3.math.NumberUtils;
20 import org.slf4j.Logger;
21 import org.slf4j.LoggerFactory;
22
23 import com.opensymphony.xwork2.ActionInvocation;
24 import com.opensymphony.xwork2.interceptor.AbstractInterceptor;
25 import com.opensymphony.xwork2.util.TextParseUtil;
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56 public class RequestIntervalCheckInterceptor extends AbstractInterceptor {
57
58 private static final long serialVersionUID = 1L;
59
60 private static final Logger logger = LoggerFactory.getLogger(RequestIntervalCheckInterceptor.class.getClass());
61
62
63 public static final String URI_MAP = "uri_map";
64
65 public static final int DEFAULT_MAX_SIZE = 1000;
66
67 public static final String TIME_INTERVAL_EXCLUDE_URL = "time.interval.exclude.url";
68
69
70 long timeInterval = 1000;
71
72
73 private Set<Pattern> excludeParams = new HashSet<Pattern>();
74
75
76 private static volatile boolean flag ;
77
78 @Override
79 public String intercept(ActionInvocation invocation) throws Exception {
80 HttpServletRequest request = GboatAppContext.getRequest();
81 HttpSession session = request.getSession();
82 String requestURI = request.getRequestURI();
83
84 String parameter = request.getParameter("metadata");
85
86 if (parameter != null && parameter.equals("")) {
87 return invocation.invoke();
88 }
89
90
91 if (!flag) {
92 setExcludeParams(request.getSession().getServletContext().getInitParameter(TIME_INTERVAL_EXCLUDE_URL));
93 flag = Boolean.TRUE;
94 }
95
96
97 if (isExcluded(request.getServletPath())) {
98 return invocation.invoke();
99 }
100
101 LRUMap uriMap = null;
102
103 synchronized (session) {
104 uriMap = (LRUMap) session.getAttribute(URI_MAP);
105 if (uriMap == null) {
106 uriMap = new LRUMap(DEFAULT_MAX_SIZE);
107 session.setAttribute(URI_MAP, uriMap);
108 }
109 }
110
111 Long systemMill = (Long)uriMap.get(requestURI);
112 long currentTimeMillis = System.currentTimeMillis();
113 if (systemMill != null) {
114 if ((currentTimeMillis - systemMill) <= timeInterval) {
115 logger.warn("{} request interval is less than {}s", requestURI, timeInterval / 1000);
116 throw new InternalInvalidException("连续请求时间不能少于" + timeInterval / 1000 + "秒,请稍后再试。");
117 }
118 }
119 uriMap.put(requestURI, currentTimeMillis);
120 return invocation.invoke();
121 }
122
123
124
125
126
127 public void setTimeInterval(String timeInterval) {
128 if(StringUtils.isNotBlank(timeInterval)){
129 this.timeInterval = NumberUtils.toLong(timeInterval.trim(), this.timeInterval);
130 }
131 }
132
133
134
135
136
137 public void setExcludeParams(String commaDelim) {
138 if (StringUtils.isBlank(commaDelim))
139 return;
140
141 Set<String> excludePatterns = TextParseUtil.commaDelimitedStringToSet(commaDelim);
142 if (!excludePatterns.isEmpty()) {
143 for (String pattern : excludePatterns) {
144 excludeParams.add(Pattern.compile(pattern));
145 }
146 }
147 }
148
149
150
151
152
153
154 protected boolean isExcluded(String requestUri) {
155 if (!this.excludeParams.isEmpty()) {
156 for (Pattern pattern : excludeParams) {
157 if (pattern.matcher(requestUri).matches()) {
158 return true;
159 }
160 }
161 }
162 return false;
163 }
164
165 }