springmvc中自己实现的token防表单重复提交,防止二次提交
2016-03-22 16:57
786 查看
出处:http://www.oschina.net/code/snippet_100825_21906
一:首先创建一个token处理类,这里的类名叫TokenHandler
private
static
Loggerlogger=Logger.getLogger(TokenHandler.
class
);
static
Map<String,String>springmvc_token=
null
;
//生成一个唯一值的token
@SuppressWarnings
(
"unchecked"
)
public
synchronized
static
String generateGUID(HttpSessionsession){
Stringtoken=
""
;
try
{
Objectobj=session.getAttribute(
"SPRINGMVC.TOKEN"
);
if
(obj!=
null
)
springmvc_token=(Map<String,String>)session.getAttribute(
"SPRINGMVC.TOKEN"
);
else
springmvc_token=
new
HashMap<String, String>()
token=
new
BigInteger(
165
,
new
Random()).toString(
36
)
.toUpperCase();
springmvc_token.put(Constants.DEFAULT_TOKEN_NAME+
"."
+ token,token);
session.setAttribute(
"SPRINGMVC.TOKEN"
, springmvc_token);
Constants.TOKEN_VALUE=token;
}
catch
(IllegalStateExceptione){
logger.error(
"generateGUID()mothodfindbug,bytokensession..."
);
}
return
token;
}
//验证表单token值和session中的token值是否一致
@SuppressWarnings
(
"unchecked"
)
public
static
boolean
validToken(HttpServletRequest request){
StringinputToken=getInputToken(request);
if
(inputToken==
null
) {
logger.warn(
"tokenisnotvalid!inputTokenisNULL"
);
return
false
;
}
HttpSessionsession=request.getSession();
Map<String,String>tokenMap=(Map<String,String>)session.getAttribute(
"SPRINGMVC.TOKEN"
);
if
(tokenMap==
null
|| tokenMap.size()<
1
){
logger.warn(
"tokenisnotvalid!sessionTokenisNULL"
);
return
false
;
}
StringsessionToken=tokenMap.get(Constants.DEFAULT_TOKEN_NAME+
"."
+inputToken);
if
(!inputToken.equals(sessionToken)){
logger.warn(
"tokenisnotvalid!inputToken='"
+ inputToken
+
"',sessionToken='"
+sessionToken
+
"'"
);
return
false
;
}
tokenMap.remove(Constants.DEFAULT_TOKEN_NAME+
"."
+ inputToken);
session.setAttribute(
"SPRINGMVC.TOKEN"
, tokenMap);
return
true
;
}
//获取表单中token值
@SuppressWarnings
(
"unchecked"
)
public
static
StringgetInputToken(HttpServletRequest request){
Mapparams=request.getParameterMap();
if
(!params.containsKey(Constants.DEFAULT_TOKEN_NAME)){
logger.warn(
"Couldnotfindtokennameinparams."
);
return
null
;
}
String[]tokens=(String[])(String[])params
.get(Constants.DEFAULT_TOKEN_NAME);
if
((tokens==
null
) ||(tokens.length<
1
)){
logger.warn(
"Gotanulloremptytokenname."
);
return
null
;
}
return
tokens[
0
];
}
二:自己实现一个自定义标签这里我自定义的标签叫:<dy:token/>(自定义标签的代码实现,我放csdn上了,不会的赶紧去下载,这里我不讲了),页面中使用如下:
1
:引入标签库:<%@taglibprefix=
"dy"
uri=
"/dy-tags"
%>
2
:jsp页面中的表单,注意加上token标签!!!如下:
index.jsp!!!
<%@taglibprefix=
"dy"
uri=
"/dy-tags"
%>
<html>
<head>
<title>springmvc</title>
</head>
<body>
welcometospringmvc!<br/>
<formname=
"mvcForm"
action=
"indexSubmit.do"
method=
"post"
>
<dy:token/>
username:<inputname=
"username"
type=
"text"
value=
"${user.username}"
/>
password:<inputname=
"password"
type=
"text"
value=
"${user.password}"
/>
email:<inputname=
"email"
type=
"text"
value=
"${user.email}"
/>
<inputtype=
"submit"
value=
"提交"
>
</form>
</body>
</html>
三、用到的常量:
public
static
StringDEFAULT_TOKEN_MSG_JSP=
"unSubmit.jsp"
;
public
static
StringTOKEN_VALUE;
public
static
StringDEFAULT_TOKEN_NAME=
"springMVC.token"
;
四:我MyController类的以下
2
个方法要用到token,防止表单重复提交
@RequestMapping
(value=
"index.do"
)
public
Stringindex(HttpServletRequestrequest){
return
"index"
;
}
@RequestMapping
(value=
"indexSubmit.do"
,method
=RequestMethod.POST)
public
StringindexSubmit(Useruser,HttpServletRequestrequest){
try
{
myService.insert(user);
logger.info(
"info=新增成功"
);
}
catch
(Exceptione){
logger.error(
"exception:"
+e);
}
五:以下是我拦截器的实现,注意有两个拦截器,一个生成token,一个验证token。
/**
*@Title
*@authordengyang
*@date2013-6-4
*/
public
class
TokenHandlerInterceptor
implements
HandlerInterceptor{
public
void
afterCompletion(HttpServletRequest arg0,
HttpServletResponsearg1,Objectarg2,Exceptionarg3)
throws
Exception{
}
public
void
postHandle(HttpServletRequestrequest,
HttpServletResponseresponse,
Objectarg2,ModelAndViewarg3)
throws
Exception {
TokenHandler.generateGUID(request.getSession());
}
public
boolean
preHandle(HttpServletRequest
request,HttpServletResponseresponse,
Objectarg2)
throws
Exception{
return
true
;
}
}
/**
*@Title
*@authordengyang
*@date2013-6-4
*/
public
class
TokenValidInterceptor
implements
HandlerInterceptor{
public
void
afterCompletion(HttpServletRequest request,
HttpServletResponseresponse,Objectarg2,Exceptionarg3)
throws
Exception{
}
public
void
postHandle(HttpServletRequestarg0,
HttpServletResponsearg1,
Objectarg2,ModelAndViewarg3)
throws
Exception {
}
public
boolean
preHandle(HttpServletRequest
request,HttpServletResponseresponse,
Objectarg2)
throws
Exception{
if
(!TokenHandler.validToken(request)){
response.sendRedirect(Constants.DEFAULT_TOKEN_MSG_JSP);
return
false
;
}
return
true
;
}
}
spring拦截器配置
<mvc:interceptor>
<mvc:mappingpath=
"/index.do"
/>-->这个请求返回的是你有token的页面
<bean
class
=
"com.dengyang.interceptor.TokenHandlerInterceptor"
/>
</mvc:interceptor>
<mvc:interceptor>
<mvc:mappingpath=
"/indexSubmit.do"
/>-->这个是提交请求
<bean
class
=
"com.dengyang.interceptor.TokenValidInterceptor"
/>
</mvc:interceptor>
相关文章推荐
- Mysql tinyint长度为1时在java中被转化成boolean型
- SpringMVC+spring-security+sitemesh+hibernate+freemarker整合
- dubbo + zookeeper + spring
- java 1.8 ArrayList容量增长方式
- JAVA第二次作业展示与学习心得
- ketlle中调用User Defined Java Class插件链接数据库并操作
- 基于Springmvc支付宝接口
- java给iphone应用实现推送
- Java基础知识点总结
- spring jms topic
- Java学习
- maven学习笔记 maven的安装和配置
- spring的功能
- Java内部DNS查询实现和参数设置
- Spring Security(11)——匿名认证
- java super 和this的用法
- java中的自增问题
- 在Spring下集成ActiveMQ
- Java Native
- windows下配置JDK环境