JavaWeb防止用户的重复请求提交
这里实现这个重复提交的防止,是通过在一个FIlter过滤器中生成一个令牌token,保存在Session域中,然后在对这个token加密得到ciphertext(密文),将密文保存在request域中。如果在login.jsp中的一个隐藏表单项中取得这个request域中的密文(ciphertext)。提交到一个LoginServlet,进行判断令牌是否匹配成功,成功的话,就到数据库中查询操作,否则的话就打出提示消息。这样的话,就不会导致每一个请求均去数据库进行查询,导致系统超负荷的工作,不至于导致进行不必要的工作。
代码如下:
FilterToken.java
package cn.geore.token; import java.io.IOException; import java.util.UUID; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpSession; public class FilterToken implements Filter { @Override public void destroy() { } @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { // 取得token String token = uuid(); // 将uuid加密,得到密文 String ciphertext = MD5AndSHAEncrypt.cipherKey("MD5", token); // 将生成的token保存在session中 HttpServletRequest req = (HttpServletRequest) request; HttpSession session = req.getSession(); session.setAttribute("token", token); // 将ciphertext保存在request域中 request.setAttribute("ciphertext", ciphertext); chain.doFilter(request, response); } @Override public void init(FilterConfig arg0) throws ServletException { } // 生成一个token private static String uuid() { return UUID.randomUUID().toString().replace("-", "").toUpperCase(); } }
login.jsp
<body> <form action="<%=request.getContextPath() %>/LoginServlet" method="get"> <input type="text" name="discription" /> <input type="hidden" name="ciphertext" value="${requestScope.ciphertext}"> <input type="submit" value="提交" /> </form>
</body>
LoginServlet.java
package cn.geore.token; import java.io.IOException; import java.io.PrintWriter; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class LoginServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.setCharacterEncoding("utf-8"); response.setContentType("text/html;charset=utf-8"); PrintWriter pw = response.getWriter(); String token = (String) request.getSession().getAttribute("token"); // 对token进行加密,判断传来的参数是否为同一个token String ciphertext = request.getParameter("ciphertext"); if (ciphertext != null && token != null) { if (ciphertext.equals(MD5AndSHAEncrypt.cipherKey( MD5AndSHAEncrypt.ENCRYPT_ALGORITHM_MD5, token))) { // 令牌正确匹配后,要将令牌从Session域中移除 request.getSession().removeAttribute("token"); pw.write("令牌正确,没有进行重复表单的提交"); } }else { pw.write("您正在进行非法的访问"); } } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { } }