第一种方法:判断session中保存的token
比较麻烦,每次在提交表单时都必须传入上次的token。而且当一个页面使用ajax时,多个表单提交就会有问题。
注解Token代码:
- package .repeat_form_validator;
-
- import ;
- import ;
- import ;
- import ;
-
-
-
-
-
-
- @Target()
- @Retention()
- public @interface FormToken {
-
- boolean save() default false;
-
- boolean remove() default false;
- }
拦截器TokenInterceptor代码:
- package .repeat_form_validator;
-
- import ;
- import ;
-
- import ;
- import ;
-
- import ;
- import ;
-
- public class FormTokenInterceptor extends HandlerInterceptorAdapter {
-
- @Override
- public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
- if (handler instanceof HandlerMethod) {
- HandlerMethod handlerMethod = (HandlerMethod) handler;
- Method method = ();
- FormToken annotation = (FormToken.class);
- if (annotation != null) {
- boolean needSaveSession = ();
- if (needSaveSession) {
- (false).setAttribute("formToken", ().toString());
- }
- boolean needRemoveSession = ();
- if (needRemoveSession) {
- if (isRepeatSubmit(request)) {
- return false;
- }
- (false).removeAttribute("formToken");
- }
- }
- return true;
- } else {
- return super.preHandle(request, response, handler);
- }
- }
-
- private boolean isRepeatSubmit(HttpServletRequest request) {
- String serverToken = (String) (false).getAttribute("formToken");
- if (serverToken == null) {
- return true;
- }
- String clinetToken = ("formToken");
- if (clinetToken == null) {
- return true;
- }
- if (!(clinetToken)) {
- return true;
- }
- return false;
- }
- }
然后在Spring MVC的配置文件里加入:
- <mvc:interceptors>
- <mvc:interceptor>
- <mvc:mapping path="/**"/>
- <bean class=".repeat_form_validator.FormTokenInterceptor"/>
- </mvc:interceptor>
- </mvc:interceptors>
相关代码已经注释,相信你能看懂。
关于这个方法的用法是:在需要生成token的controller上增加@FormToken(save=true),而在需要检查重复提交的controller上添加@FormToken(remove=true)就可以了。
另外,你需要在view里在form里增加下面代码:
- <inputtypeinputtype="hidden"name="formToken"value="${formToken}" />
已经完成了,去试试看你的数据还能重复提交了吧。
注意在ajax提交时 要加上 formToken参数
第二种方法(判断请求url和数据是否和上一次相同)
推荐,非常简单,页面不需要任何传入,只需要在验证的controller方法上写上自定义注解即可
写好自定义注解
- package .repeat_form_validator;
-
- import ;
- import ;
- import ;
- import ;
-
-
-
-
-
-
- @Target()
- @Retention()
- public @interface SameUrlData {
-
-
- }
写好拦截器
- package .repeat_form_validator;
-
- import ;
- import ;
- import ;
-
- import ;
- import ;
-
- import ;
- import ;
-
- import ;
-
-
-
-
-
-
-
- public class SameUrlDataInterceptor extends HandlerInterceptorAdapter{
-
- @Override
- public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
- if (handler instanceof HandlerMethod) {
- HandlerMethod handlerMethod = (HandlerMethod) handler;
- Method method = ();
- SameUrlData annotation = (SameUrlData.class);
- if (annotation != null) {
- if(repeatDataValidator(request))
- return false;
- else
- return true;
- }
- return true;
- } else {
- return super.preHandle(request, response, handler);
- }
- }
-
-
-
-
-
- public boolean repeatDataValidator(HttpServletRequest httpServletRequest)
- {
- String params=(());
- String url=();
- Map<String,String> map=new HashMap<String,String>();
- (url, params);
- String nowUrlParams=();
-
- Object preUrlParams=().getAttribute("repeatData");
- if(preUrlParams==null)
- {
- ().setAttribute("repeatData", nowUrlParams);
- return false;
- }
- else
- {
- if(().equals(nowUrlParams))
- {
-
- return true;
- }
- else
- {
- ().setAttribute("repeatData", nowUrlParams);
- return false;
- }
-
- }
- }
-
- }
- <mvc:interceptor>
- <mvc:mapping path="/**"/>
- <bean class=".repeat_form_validator.SameUrlDataInterceptor"/>
- </mvc:interceptor>
进行代码控制拦截器
@Configuration
public class MvcInterceptorConfig extends WebMvcConfigurerAdapter {
@Override
public void addInterceptors(InterceptorRegistry registry) {
(new LoginInterceptor()).addPathPatterns("*").excludePathPatterns("/licardUser/loginRegister")
.excludePathPatterns("/licardUser/getImgCaptcha").excludePathPatterns("/licardcommon/captcha");
(new FormTokenInterceptor()).addPathPatterns("/licardbussiness/analogCal", "/licardbussiness/cashApply");
(new SameUrlDataInterceptor()).addPathPatterns("/licardApply/limitApply");
}
}
判断session中保存的token
生成token
@RequestMapping(value = "/analogCal", method = RequestMethod.POST)
@FormToken(save=true)
public ApiResponse analogCal(String custId, String prodId, Integer periods, double amount, Integer type) {
}
一次token
@RequestMapping(value = "/cashApply", method = RequestMethod.POST)
@FormToken(remove=true)
public ApiResponse cashApply(HttpSession session,CashApplyVO cashApplyVO) {
}
判断请求url和数据是否和上一次相同调用
@SuppressWarnings("unchecked")
@RequestMapping(value = "/limitApply",method = RequestMethod.POST)
@SameUrlData
public ApiResponse<String> limitApply(String custId,String applyType){
}
第二种方法必须保证不能一个用户在多个浏览器上同时登录,否则不能保证同一个用户一个session
转载自:/u013378306/article/details/52944780