springMVC项目自定义注解token防重复提交验证(也可用于验证请求有效性)

有时我们在项目框架搭建时并没有注意方重复提交的问题,在项目开发一半后发现许多地方需要方重复提交拦截功能,常规做法是在每个需要校验的请求接口中一一加上验证,但这样做的话工作量大并且代码入侵太严重如果后期需要改动那你会疯的。

有个简便的方法和大家分享下(自定义注解+拦截器),自用在需要防重复提交的接口中加上注解即可。

 

1.自定义注解只有两个方法,获取token和验证token

package com.***;

 

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 SubmitToken {

/**

* 获得token

* @return

*/

boolean save() default false;

 

/**

* 验证token有效性并使token失效

* @return

*/

boolean remove() default false;

}

2.拦截器两个功能,save()=true时生成token并存储在缓存中,remove()=true时验证token并清除缓存中的token

import java.lang.reflect.Method;

import java.util.HashMap;

import java.util.Map;

import java.util.UUID;

 

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

 

import org.apache.log4j.Logger;

import org.springframework.web.method.HandlerMethod;

import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

 

import com.bingchuangapi.common.base.SubmitToken;

import com.bingchuangapi.common.constant.Constants;

import com.bingchuangapi.common.util.JsonUtil;

 

 

public class TokenInterceptor extends HandlerInterceptorAdapter {

private static final Logger LOG = Logger.getLogger(SubmitToken.class);

@Override

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

if (handler instanceof HandlerMethod) {

HandlerMethod handlerMethod = (HandlerMethod) handler;

Method method = handlerMethod.getMethod();

SubmitToken annotation = method.getAnnotation(SubmitToken.class);

if (annotation != null) {

boolean needSaveSession = annotation.save();

if (needSaveSession) {//在缓存中存储token

request.getSession(true).setAttribute("SubmitToken", UUID.randomUUID().toString());

}

boolean needRemoveSession = annotation.remove();

if (needRemoveSession) {//需要验证防重复提交

if (isRepeatSubmit(request)) {//符合重复提交

LOG.warn("please don't repeat submit,url:"+ request.getServletPath());

Map out = new HashMap();

out.put(Constants.RET_CODE, "900");

out.put(Constants.RET_MSG, "重复提交");

JsonUtil.writeJson(response,out);

return false;

}

request.getSession(true).removeAttribute("SubmitToken");

}

}

return true;

} else {

return super.preHandle(request, response, handler);

}

}

 

private boolean isRepeatSubmit(HttpServletRequest request) {

String serverToken = null;

serverToken = (String) request.getSession(true).getAttribute("SubmitToken");

//缓存中没有有效的token

if (serverToken == null) {

return true;

}

String clinetToken = request.getParameter("SUBMITTOKEN");

//未接收到有效的token

if (clinetToken == null) {

return true;

}

//缓存中的token和接收到的token没有匹配上

if (!serverToken.equals(clinetToken)) {

return true;

}

return false;

}

}

3.写一个获取token的请求提供给前台调用

//获取submitToken

@RequestMapping("/getSubmitToken.do")

@SubmitToken(save=true)//添加获取token的自定义注解

public ModelAndView getSubmitToken(HttpServletRequest request,HttpServletResponse response,Model model) throws Exception{

Map out = new HashMap();

out.put("SUBMITTOKEN", getSessionObj("SubmitToken"));

out.put(Constants.RET_CODE, Constants.RET_SUCCESS_CODE);

out.put(Constants.RET_MSG, Constants.RET_SUCCESS_MSG);

JsonUtil.writeJson(response,out);

return null;

}

4.后面只需要在我们需要防重复提交的请求中加入@SubmitToken(remove=true)即可

//验证submitToken

@RequestMapping("/setSubmitToken.do")

@SubmitToken(remove=true)

public ModelAndView setSubmitToken(HttpServletRequest request,HttpServletResponse response,Model model) throws Exception{

Map out = new HashMap();

out.put(Constants.RET_CODE, Constants.RET_SUCCESS_CODE);

out.put(Constants.RET_MSG, Constants.RET_SUCCESS_MSG);

JsonUtil.writeJson(response,out);

 

return null;

}

5.拦截器的配置文件

<!-- 拦截器配置 -->

<mvc:interceptors>

<!-- 配置Token拦截器,防止用户重复提交数据 -->

<mvc:interceptor>

<mvc:mapping path="/**"/><!--这个地方时你要拦截得路径 我这个意思是拦截所有得URL-->

<bean class="com.*****.TokenInterceptor"/><!--class文件路径改成你自己写得拦截器路径!! -->

</mvc:interceptor>

</mvc:interceptors>

完成以上几部就可以实现自定义注解少入侵的添加放重复提交,如果大家需要验证请求的合法性只需要修改拦截器中的代码逻辑即可实现。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值