您的位置:首页 > 编程语言 > Java开发

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>


                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: