防止重复提交数据
重复提交的问题是:
1:用户在提交以后,通过post请求停在了结果页面。
2:如果用户进行刷新则是指将刚才的请求协议再次向服务器发送。
解决的方式:
1:在提交成功以后,重定向(新的请求过程)到其他的地方给用户一个显示。
2:页面上,隐藏一个hidden元素。通过session来验证。
package cn.meeting.utils; import java.io.IOException; import java.io.PrintWriter; import java.util.UUID; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; /** * 生成一个随机数<br> * 输出一个input元素 */ public class RepeatServlet extends HttpServlet { protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html;charset=UTF-8"); PrintWriter out = response.getWriter(); String uuid = UUID.randomUUID().toString().replace("-", ""); String html = "<script type='text/javascript'>" + "parent.document.getElementsByName('repeat')[0].value='"+uuid+"';</script>"; out.print(html); //放到Sssion中去,以便于在AddMeetingServlet中验证 HttpSession s = request.getSession(); s.setAttribute("isRepeat", uuid); } }
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>会议管理系统</title> <link rel="stylesheet" type="text/css" href="../css/pub.css"> </head> <body> <form action="/meeting/add" method="post" class="form"> <p>添加新的会议</p> <table class="tb"> <tr> <td>标题:</td> <td><input class="txt" type="text" name="title"></td> </tr> <tr> <td>内容:</td> <td><textarea rows="5" cols="20" name="content"></textarea></td> </tr> <tr> <td>地点:</td> <td><input class="txt" type="text" name="addr"></td> </tr> <tr> <td>时间:</td> <td><input class="txt" type="text" name="dt"></td> </tr> <tr> <td></td> <td><input type="hidden" name="repeat"></td> </tr> <tr> <td colspan="2"><input type="submit" value="保存"> <input type="reset" value="清空"></td> </tr> </table> </form> <iframe style="display: none;" src="../repeat"></iframe> </body> </html>
package cn.meeting.add; import java.io.IOException; import java.io.PrintWriter; import java.util.UUID; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.websocket.Session; import cn.meeting.doamin.Meeting; import cn.meeting.utils.BeanUtils; import cn.meeting.utils.DSUtils; import cn.meeting.utils.IsLogin; /** * 添加新的会议 */ public class AddMeetingServlet extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 1:设置编码类型 request.setCharacterEncoding("UTF-8"); response.setContentType("text/html"); response.setCharacterEncoding("UTF-8"); PrintWriter out = response.getWriter(); // 判断用户是否登录 if (!IsLogin.logined(request)) { out.print("你还没有登录,请先去<a href='index.html'>登录</a>"); return; } //验证是否是重复的提交 //1:先获取用户在页面上提交的隐藏的值-(隐藏表单) String repeat = request.getParameter("repeat"); //2:从Sessioin中获取值 String isRepeat = (String) request.getSession().getAttribute("isRepeat"); if(!repeat.equals(isRepeat)){ out.print("不能重复提交,去显示列表:<a href='list'>会议列表</a>"); return; } // 2:接收所有的参数,封装到Meeeing对象中去 // 可以使用工具类,BeanUtils直接一次性的进行数据的封装 Meeting meeting = new Meeting(); BeanUtils.populate(meeting, request.getParameterMap()); System.err.println("封装成功了:" + meeting); int rows = new AddMeetingDao().addMeeting(meeting); // 重向到到/list.获取项目的上下文根 String contextPath = request.getContextPath();// - > /meeting //response.sendRedirect(contextPath + "/list");//如果重定向浏览器就出了一个新的请求,如果再刷新页面,则是请求/list out.print("保存成功。"); //保存成功以后,删除放到session中验证是否重复提交的值 request.getSession().removeAttribute("isRepeat"); } }