token防重复提交

来源:互联网 发布:iphone6s数据漫游 编辑:程序博客网 时间:2024/05/16 18:17

网上方式有好几种,还是觉得token令牌方式更高大上更严谨一些

新建一个注解Token,默认是false

import java.lang.annotation.ElementType;import java.lang.annotation.Retention;import java.lang.annotation.RetentionPolicy;import java.lang.annotation.Target;@Target(ElementType.METHOD)@Retention(RetentionPolicy.RUNTIME)public @interface Token {boolean save() default false;boolean remove() default false;}

新建一个类TokenInterceptor
import java.lang.reflect.Method;import java.util.UUID;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import org.springframework.web.method.HandlerMethod;import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;public class TokenInterceptor extends HandlerInterceptorAdapter{@Overridepublic boolean preHandle(HttpServletRequest request,HttpServletResponse response,Object handler) throws Exception{if (handler instanceof HandlerMethod) {HandlerMethod handlerMethod=(HandlerMethod) handler;Method method=handlerMethod.getMethod();Token annotation=method.getAnnotation(Token.class);System.out.println(annotation+"--1");if (annotation!=null) {boolean needSaveSession=annotation.save();System.out.println(needSaveSession+"--2");if (needSaveSession) {request.getSession(true).setAttribute("token", UUID.randomUUID().toString());}boolean needRemoveSession=annotation.remove();System.out.println(needRemoveSession+"--3");if (needRemoveSession) {if (isRepeatSubmit(request)) {System.out.println("6");return false;}System.out.println("7");request.getSession(true).removeAttribute("token");}}return true;}else{return super.preHandle(request, response, handler);}}private boolean isRepeatSubmit(HttpServletRequest request){String serverToken=(String) request.getSession(true).getAttribute("token");System.out.println(serverToken+"--4");if (serverToken==null) {return true;}String clinetToken=request.getParameter("token");System.out.println(clinetToken+"--5");if (clinetToken==null) {return true;}if (!serverToken.equals(clinetToken)) {return true;}return false;}}


<!-- 配置token 拦截器--><mvc:interceptors><!-- 防止用户重复提交数据 --><mvc:interceptor><mvc:mapping path="/**"/><!-- 拦截所有url --><bean class="com.game.token.TokenInterceptor"></bean></mvc:interceptor></mvc:interceptors>


注解@Token(save=true)的意思是进入界面时的动作,@Token(remove=true)是业务执行的动作

举例:

当我点击充值选项时,打印结果如下:

@com.game.token.Token(save=true, remove=false)--1
true--2
false--3
首先拦截url到TokenInterceptor,needSaveSession=true,随机生成一个token令牌保存到session中,needRemoveSession=false不执行,return true,进入controller中执行代码,在jsp中接收token,充值时将token传递到后台,也是拦截url到TokenInterceptor,这时的打印如下:
@com.game.token.Token(save=false, remove=true)--1
false--2
true--3
9b0713d2-c12a-47aa-9631-740cb44201fe--4
9b0713d2-c12a-47aa-9631-740cb44201fe--5
7
@com.game.token.Token(save=true, remove=false)--1
true--2
false--3

这时的save=false,remove=true,不随机生成token,needRemoveSession=true,执行isRepeatSubmit(request) 取得session中的token,取得前台传过来的token,如果两者为null或者不相等就return true,否则return false ,这里return false;跳过if这时执行7销毁token,return true;执行controller代码 ,所以这里保持前后台传递token的正确很重要,执行controller后我是返回当前jsp界面,所以又走了一遍save(),多查几篇文章理解更深一些
越努力,越幸运,我相信我的运气不会差的




原创粉丝点击