博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Spring MVC拦截器+注解方式实现防止表单重复提交
阅读量:6278 次
发布时间:2019-06-22

本文共 2150 字,大约阅读时间需要 7 分钟。

hot3.png

原理:在新建页面中Session保存token随机码,当保存时验证,通过后删除,当再次点击保存时由于服务器端的Session中已经不存在了,所有无法验证通过。

注解Token代码:

@Target(ElementType.METHOD)

@Retention
(RetentionPolicy.RUNTIME)
public
@interface
Token {
 
    
boolean
save()
default
false
;
 
    
boolean
remove()
default
false
;
}

拦截器TokenInterceptor代码:

public
class
TokenInterceptor
extends
HandlerInterceptorAdapter {
 
    
@Override
    
public
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
);
            
if
(annotation !=
null
) {
                
boolean
needSaveSession = annotation.save();
                
if
(needSaveSession) {
                    
request.getSession(
false
).setAttribute(
"token"
, UUID.randomUUID().toString());
                
}
                
boolean
needRemoveSession = annotation.remove();
                
if
(needRemoveSession) {
                    
if
(isRepeatSubmit(request)) {
                        
return
false
;
                    
}
                    
request.getSession(
false
).removeAttribute(
"token"
);
                
}
            
}
            
return
true
;
        
}
else
{
            
return
super
.preHandle(request, response, handler);
        
}
    
}
 
    
private
boolean
isRepeatSubmit(HttpServletRequest request) {
        
String serverToken = (String) request.getSession(
false
).getAttribute(
"token"
);
        
if
(serverToken ==
null
) {
            
return
true
;
        
}
        
String clinetToken = request.getParameter(
"token"
);
        
if
(clinetToken ==
null
) {
            
return
true
;
        
}
        
if
(!serverToken.equals(clinetToken)) {
            
return
true
;
        
}
        
return
false
;
    
}
}

然后在Spring MVC的配置文件里加入:

<!-- 拦截器配置 -->
<
mvc:interceptors
>
    
<!-- 配置Shiro拦截器,实现注册用户的注入 -->
    
<
mvc:interceptor
>
        
<
mvc:mapping
path
=
"/**"
/>
        
<
bean
class
=
"com.storezhang.video.shiro.ShiroInterceptor"
/>
    
</
mvc:interceptor
>
    
<!-- 配置Token拦截器,防止用户重复提交数据 -->
    
<
mvc:interceptor
>
        
<
mvc:mapping
path
=
"/**"
/>
        
<
bean
class
=
"com.storezhang.web.spring.TokenInterceptor"
/>
    
</
mvc:interceptor
>
</
mvc:interceptors
>

相关代码已经注释,相信你能看懂。

关于这个方法的用法是:在需要生成token的controller上增加@Token(save=true),而在需要检查重复提交的controller上添加@Token(remove=true)就可以了。
另外,你需要在view里在form里增加下面代码:

<
   
input
   
type
   
=
   
"hidden"
   
name
   
=
   
"token"
   
value
   
=
   
"${token}"
   
/>

已经完成了,去试试看你的数据还能重复提交了吧。

转载于:https://my.oschina.net/u/273598/blog/191666

你可能感兴趣的文章
《设计模式解析(第2版•修订版)》目录—导读
查看>>
《Web前端开发精品课 HTML与CSS进阶教程》——2.2 标题语义化
查看>>
Java核心技术卷I基础知识3.5.3 强制类型转换
查看>>
可与Mirai比肩的恶意程序Hajime,竟是为了保护IoT设备?
查看>>
《Spring Data 官方文档》6. Cassandra 存储库
查看>>
聊聊并发(十)生产者消费者模式
查看>>
R语言数据挖掘2.2.4.2 FP-growth算法
查看>>
人工智能概念诞生60年,哪些大牛堪称“一代宗师”?
查看>>
《游戏大师Chris Crawford谈互动叙事》一9.5 真实案例
查看>>
Mybatis与Spring整合连接MySQL
查看>>
GCC知识
查看>>
实验4 IIC通讯与EEPROM接口
查看>>
几个smarty小技巧
查看>>
Cocos2d-x3.2 Grid3D网格动作
查看>>
Java (for循环综合应用)
查看>>
NodeJs——(10)REST风格的路由规则
查看>>
软件可扩展性:来自星巴克的经验
查看>>
Java Cache系列之Guava Cache实现详解
查看>>
深入Log4J源码之LoggerRepository和Configurator
查看>>
System V 消息队列—复用消息
查看>>