1、 通过重定向的方式:把地址栏的地址显示为最后的地址。
2、 禁止客户端刷新:通过JS来控制,禁用刷新的功能、清除访问历史纪录。
3、 Struts自带的方式(令牌):
服务器端发放一次性使用的令牌方式,服务器端给客户端每次请求发一个令牌,在客户端提交之后,检查令牌,
如果这个令牌是第一次使用,就ok;否则,提示重复提交。
Action中有个几个相关方法: SaveToken(request):生成一个新的令牌,并保存到客户端的请求对象中。
IsTokenValid(request,true):检查客户端的令牌是否是第一次使用,并且使该令牌失效。
ResetToken(request):重置客户端的令牌。
在 提交的时候在Servlet中根据用户的sessionid和当前时间的long值生成一个令牌(每次提交都会生成一个新令牌),将令牌保存在 该用户的会话中,并将令牌的值以request属性形式传到前端页面,在前端页面的form中增加传递令牌的隐藏域<input type="hidden" name="clientToken" value="<%=clientToken%>" />,提交form的时候,也会将clientToken传入Servlet,如果session中保存的令牌值与传入的不同,则是重复提交,因为 每次请求Servlet都会生成新的令牌,刷新时的令牌值是旧的令牌值,不是最新的令牌值。
- jsp:
- //获取令牌、防止刷新重复提交
- <form>中增加<input type="hidden" name="clientToken" value="${clientToken}>" />
- java:
- /**
- * 令牌验证防止刷新提交
- */
- private String clientToken;
- /**
- * 验证防止刷新重复提交
- * @return
- */
- private boolean validateToken()
- {
- boolean bl = false;
- try
- {
- String sessionToken = (String) getHttpRequest().getSession().getAttribute(
- "token");
- if (StringUtils.isNotEmpty(sessionToken) && !clientToken.equals(sessionToken))
- {
- // 禁止刷新
- bl = false;
- }
- else
- {
- // 正常的操作
- bl = true;
- // 生成新令牌
- String sToken = UUID.randomUUID().toString().toUpperCase();
- getHttpRequest().getSession().setAttribute("clientToken", sToken);
- // 替换旧令牌
- getHttpRequest().getSession().setAttribute("token", sToken);
- }
- }
- catch (Exception e)
- {
- LOGGER.error(e.getMessage());
- }
- return bl;
- }