使用session在服务端防止表单重复提交
2018-01-26 18:19
375 查看
相较于在客户端使用js等方式防止用户重复点击或者通过别的方式重复提交表单,在服务端使用session防止表单重复提交更能解决问题。当然前后端结合使用会给用户更好的体验
思路:
1、获取一个独一无二的token(防止重复提交的key),我们这里使用一个自己封装好的方(TokenProccessor),把获取到的token加到session中。
2、新建form.jsp页面。使用servlet将token转发(必须是转发)到form表单页面,在页面上使用隐藏域的方式把后台传来的token放到form标签<input type="hidden" name="token" value="${token}">
中,提交时随表单一起提交。
3、在后台分三种情况
3.1首先验证传来的token是否为空,为空的情况意思是用户没有通过正常的操作获取到表单,故表单中提交的token为空,这种情况我们认为不合法,此处return false处理。(防盗链也是这么搞得,这里就不细讲了,感兴趣的同学可以自己看看,结合本文,很容易就搞出来了)
3.2验证服务端中session里存的token是否为空(当第一次验证通过后会把session中的token清掉),为空说明已经提交过一次了,所以是重复提交,这里return false处理
3.3验证获取到的token是否与session中的token一致,一致则通过验证提交表单,同时清掉session里的token。下面该干嘛干嘛。不一致的情况就不聊了
思路理清后,下面上代码,顺序都一样的哦。
目录结构web.xml
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" version="3.1"> <servlet> <servlet-name>formSession</servlet-name> d244 <servlet-class>ser.david.useSessionFormRepeatDemo.FormSession</servlet-class> </servlet> <servlet-mapping> <servlet-name>formSession</servlet-name> <url-pattern>/formSession</url-pattern> </servlet-mapping> <servlet> <servlet-name>doformSession</servlet-name> <servlet-class>ser.david.useSessionFormRepeatDemo.DoFormServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>doformSession</servlet-name> <url-pattern>/doformSession</url-pattern> </servlet-mapping> </web-app>
TokenProccessor.java 使用单例模式
package ser.david.useSessionFormRepeatDemo; import sun.misc.BASE64Encoder; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.util.Random; public class TokenProccessor { /* 单例化 1、构造方法私有 2、自己创建自己对象 3、对外暴露一个方法,可以获取上面自己创建的自己的对象 */ private TokenProccessor(){}; private static final TokenProccessor instance=new TokenProccessor(); public static TokenProccessor getInstance(){ return instance; } public String generatetoken(){ String token=System.currentTimeMillis()+new Random().nextInt()+""; try { MessageDigest md=MessageDigest.getInstance("md5"); byte[] md5=md.digest(token.getBytes()); //base64编码 BASE64Encoder encoder=new BASE64Encoder(); return encoder.encode(md5); } catch (NoSuchAlgorithmException e) { throw new RuntimeException(e); } } }
FormSession.java
package ser.david.useSessionFormRepeatDemo; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; public class FormSession extends HttpServlet { protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //产生随机数 TokenProccessor tp=TokenProccessor.getInstance(); String token=tp.generatetoken(); request.getSession().setAttribute("token",token); request.getRequestDispatcher("/form.jsp").forward(request,response); } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
Form.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Title</title> </head> <body> <form action="/doformSession" method="post"> <input type="hidden" name="token" value="${token}"> 用户名:<input type="text" name="username"><br/> <input type="submit" value="提交"> </form> </body> </html>
DoFormServlet.java
package ser.david.useSessionFormRepeatDemo; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; //使用session在服务端防止表单重复提交 public class DoFormServlet extends HttpServlet { protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { boolean b=isTokenValid(request); if (!b){ System.out.println("请不要重复提交"); return; } request.getSession().removeAttribute("token"); System.out.println("向数据库中注册数据。。。。。"); } private boolean isTokenValid(HttpServletRequest request){ String client_token =request.getParameter("token"); if (client_token==null){ return false; } String server_token=(String)request.getSession().getAttribute("token"); if (server_token==null){ return false; } if (!client_token.equals(server_token)){ return false; } return true; } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
效果图:
1、访问/session,跳转到form.jsp页面、填写并提交2、可以看到已经提交成功
3、刷新页面或者后退重新点击提交按钮,可以看到表单提交被拦截,后台输出提示信息
相关文章推荐
- JavaWeb学习总结(十三)——使用Session防止表单重复提交
- JavaWeb学习总结(十三)——使用Session防止表单重复提交
- JavaWeb学习总结(十三)——使用Session防止表单重复提交
- JavaWeb学习总结(十三)——使用Session防止表单重复提交
- 使用Session防止表单重复提交
- java web 学习十三(使用session防止表单重复提交)
- Java Web学习总结(12)——使用Session防止表单重复提交
- JavaWeb(十三)——使用Session防止表单重复提交
- [Java拾遗五]使用Session防止表单重复提交
- JavaWeb---总结(十三)使用Session防止表单重复提交
- 使用Session防止表单重复提交
- JavaWeb学习总结(十三)——使用Session防止表单重复提交
- 使用Session防止表单重复提交
- JavaWeb学习总结(十三)——使用Session防止表单重复提交
- JavaWeb学习总结(十三)——使用Session防止表单重复提交
- 使用Session防止表单重复提交
- 使用Session防止表单重复提交
- 登录和注销、基于Session的购物车案例、验证码的使用、防止表单重复提交
- JavaWeb学习总结(十三)——使用Session防止表单重复提交
- 使用Session防止表单重复提交