看了一下网上的案例,大部分都是自定义注解加拦截器实现防止表单重复提交
自定义注解:
@Inherited
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface FormToken {
boolean save() default false;
boolean remove() default false;
}
拦截器:
public class TokenInterceptor extends HandlerInterceptorAdapter {
14 private static final Logger LOG = Logger.getLogger(Token.class);
15 @Override
16 public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
17 if (handler instanceof HandlerMethod) {
18 HandlerMethod handlerMethod = (HandlerMethod) handler;
19 Method method = handlerMethod.getMethod();
20 Token annotation = method.getAnnotation(Token.class);
21 if (annotation != null) {
22 boolean needSaveSession = annotation.save();
23 if (needSaveSession) {
24 request.getSession(true).setAttribute("token", UUID.randomUUID().toString());
25 }
26 boolean needRemoveSession = annotation.remove();
27 if (needRemoveSession) {
28 if (isRepeatSubmit(request)) {
29 LOG.warn("please don't repeat submit,url:"+ request.getServletPath());
30 return false;
31 }
32 request.getSession(true).removeAttribute("token");
33 }
34 }
35 return true;
36 } else {
37 return super.preHandle(request, response, handler);
38 }
39 }
40
41 private boolean isRepeatSubmit(HttpServletRequest request) {
42 String serverToken = (String) request.getSession(true).getAttribute("token");
43 if (serverToken == null) {
44 return true;
45 }
46 String clinetToken = request.getParameter("token");
47 if (clinetToken == null) {
48 return true;
49 }
50 if (!serverToken.equals(clinetToken)) {
51 return true;
52 }
53 return false;
54 }
55 }
24行
request.getSession(true).setAttribute("token", UUID.randomUUID().toString());
将token保存到session这里不是很理解,这里session的key已经写死了,如果多个人同时进行表单提交,那么session会不会被覆盖(因为key是一样的,后面新的session会覆盖前面的session)?