解决方案:提交数据表单前在请求和会话中生成相同的随机令牌字符串,在表单中添加一个隐藏域保存同样的随机令牌字符串,提交表单后,在Servlet中判定请求中的令牌字符串和会话中的令牌是否一致,如果一致则说明是第一次提交,则处理数据,并删除会话中的令牌字符串,重复刷新时由于会话中的字符串已经被删除,和请求中保存的令牌不一致,则略过数据处理流程。在展现数据提交表单前,通过一个Servlet创建随机令牌字符串,然后跳转到表单页面:
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String token = UUIDrandomUUID()toString();
requestgetSession(true)setAttribute(REPEAT_SUBMIT_TOKEN_NAME,__【1】____);
requestsetAttribute("token",___【2】___);
requestgetRequestDispatcher("/jsppage/repeatsubmitdealingjsp")forward(____【3】________, _____【4】______);
}
表单页面中需要使用一个隐藏域来随请求提交刚才生成的令牌字符串:
<form method="post" action="RepeatSubmitDealingStep2Quickstart">
账 号:<input type="text" name="username" /><br />
密码:<input type="password" name="password" /><br />
<input type="hidden" name="token" value="${___【5】____}" />
<input type="submit" value="确定" />
</form>
最后在数据处理的Serlvet中验证令牌字符串是否一致来判定是不是出现了重复提交的问题:
String sessionToken = requestgetSession(true)
getAttribute(RepeatSubmitDealingStep1QuickstartREPEAT_SUBMIT_TOKEN_NAME)toString();
String requestToken = requestgetParameter("__【6】__");
if (requestTokenequals(______【7】______)) {
…
}