使用Token(令牌机制)解决重提交的问题

Posted bky-lxm

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用Token(令牌机制)解决重提交的问题相关的知识,希望对你有一定的参考价值。

1.

技术图片

第一步:创建一个注解判断请求方法是否支持防重提交

注意:注解的作用就是用于标识方法是否需要防重提交!!!

(1)获得Token

(2)删除Token

package cn.lxm.edu.annotation;

 

import java.lang.annotation.Documented;

import java.lang.annotation.ElementType;

import java.lang.annotation.Retention;

import java.lang.annotation.RetentionPolicy;

import java.lang.annotation.Target;

 

/**

 * 声明一个防重提的注解

 * @author ranger

 *

 */

@Target(ElementType.METHOD)

@Retention(RetentionPolicy.RUNTIME)

@Documented

public @interface TokenForm {

 

/**

 * 用于标识创建token

 * @return

 */

boolean create() default false;

/**

 * 用于标识删除token

 * @return

 */

boolean remove() default false;

 

}

 

 

第二步:编写一个拦截器,处理什么是否创建Token,什么时候删除Token,什么时候跳回指定页面

/**

 *  防重提交拦截器的实现

 * @author ranger

 *

 */

public class TokenFormInterceptor implements HandlerInterceptor {

 

private static final Logger logger =LogManager.getLogger(TokenFormInterceptor.class);

 

@Override

public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)

throws Exception {

HttpSession session = request.getSession();

//表单传递过来的Token

String requestToken = request.getParameter("token");

String invoke = request.getParameter("token.invoke");

//1.获得调用方法的注解

HandlerMethod handlerMethod=(HandlerMethod)handler;

//2.获得调用方法的动态方法类对象

Method method = handlerMethod.getMethod();

TokenForm tokenForm = method.getDeclaredAnnotation(TokenForm.class);

if(tokenForm!=null) {

//判断如果是一个创建Token的方法,创建一个Token方法session里面

if (tokenForm.create()==true) {

//创建一个UUID,随机的唯一字符串

String token = UUID.randomUUID().toString();

session.setAttribute("token",token);

logger.debug("创建令牌:"+token);

//允许访问

return true;

}

 

if (tokenForm.remove()==true) {

String sessionToken = (String) session.getAttribute("token");

//判断是否相同

if(requestToken.equals(sessionToken)) {

session.removeAttribute("token");

//允许访问

return true;

}

 

}

//跳转到页面指定的路径

response.sendRedirect(request.getContextPath()+invoke);

return false;

}else {

//如果不需要防重提的请求,直接跳过

return true;

}

}

 

@Override

public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,

ModelAndView modelAndView) throws Exception {

 

}

 

@Override

public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)

throws Exception {

 

}

}

--配置拦截器的代码

 技术图片

 

 

第三步:页面需要指定两个参数支持防重提交

 技术图片

 

以上是关于使用Token(令牌机制)解决重提交的问题的主要内容,如果未能解决你的问题,请参考以下文章

struts token令牌机制

如何重命名 Struts 2 令牌参数

使用Redis实现接口防重复提交

使用Redis实现接口防重复提交

请教Java 登录token的代码

使用set_user_by_token设计问题