jyy
2021-09-11 a4694bf4e0384df517464624748b366f533fda0f
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
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
package com.matrix.system.common.interceptor;
 
import com.matrix.core.anotations.RemoveRequestToken;
import com.matrix.core.anotations.SaveRequestToken;
import com.matrix.core.exception.GlobleException;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
 
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.lang.reflect.Method;
import java.util.UUID;
 
/**
 * 防止重复提交的拦截器
 * 
 * @author jiangyouyao 2016.08.19
 *
 */
public class DuplicateSubmitInterceptor extends HandlerInterceptorAdapter {
 
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
            throws Exception {
        HandlerMethod handlerMethod = (HandlerMethod) handler;
        Method method = handlerMethod.getMethod();
        SaveRequestToken saveToken = method.getAnnotation(SaveRequestToken.class);
        RemoveRequestToken removeToken = method.getAnnotation(RemoveRequestToken.class);
        HttpSession session = request.getSession();
        if (saveToken != null) {
            String token = UUID.randomUUID().toString();
            String tokenUrl = request.getServletPath();
            session.setAttribute("token", token);
            session.setAttribute("tokenUrl", tokenUrl);
            session.setAttribute(tokenUrl, token);
            // 保存操作,验证是否重复提交
        } else if (removeToken != null) {
            String clinetToken = request.getParameter("token");
            String url = request.getParameter("tokenUrl");
            String serverToken = (String) session.getAttribute(url);
            // 判断是否是重复提交了,是的话抛出异常
            boolean isReapet = isRepeatSubmit(clinetToken, serverToken);
            if (isReapet) {
                throw new GlobleException("重复提交");
            }
        }
        return super.preHandle(request, response, handler);
    }
 
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
            ModelAndView modelAndView) throws Exception {
        HandlerMethod handlerMethod = (HandlerMethod) handler;
        Method method = handlerMethod.getMethod();
        RemoveRequestToken removeToken = method.getAnnotation(RemoveRequestToken.class);
        if (removeToken != null) {
            // 提交后则清除session
            HttpSession session = request.getSession();
            String url = request.getParameter("tokenUrl");
            session.removeAttribute(url);
        }
        super.postHandle(request, response, handler, modelAndView);
    }
 
    private boolean isRepeatSubmit(String clinetToken, String serverToken) {
        // 没有进入编辑页面,直接访问url,则服务端的token为空,不允许提交,视为重复提交
        if (serverToken == null) {
            return true;
        }
        if (clinetToken == null) {
            return true;
        }
        // 传过来的和保存在session中的token不一致的话是重复
        if (!serverToken.equals(clinetToken)) {
            return true;
        }
        return false;
    }
 
}