Java 如何在刷新时防止重复条目?
我有一个Java 如何在刷新时防止重复条目?,java,html,jsp,servlets,post-redirect-get,Java,Html,Jsp,Servlets,Post Redirect Get,我有一个index.jsp页面,其中有一个表单,用户使用控制器servlet输入一些存储在数据库中的数据 在数据库中输入数据后,我希望显示与该表单相同的页面(index.jsp)。另外,我想显示用户在数据库中输入的所有条目 我尝试使用RequestDispatcher的forward()方法。它工作得很好(这意味着我可以再次显示同一个表单,还可以使用JSTL在表单下方显示该用户输入的所有数据) 但问题是,每当用户按下刷新或F5按钮时,所有以前的数据也会被输入数据库,当我显示所有数据时,重复的条目
index.jsp
页面,其中有一个表单,用户使用控制器servlet输入一些存储在数据库中的数据
在数据库中输入数据后,我希望显示与该表单相同的页面(index.jsp
)。另外,我想显示用户在数据库中输入的所有条目
我尝试使用RequestDispatcher
的forward()
方法。它工作得很好(这意味着我可以再次显示同一个表单,还可以使用JSTL在表单下方显示该用户输入的所有数据)
但问题是,每当用户按下刷新或F5按钮时,所有以前的数据也会被输入数据库,当我显示所有数据时,重复的条目也会出现
我曾想过使用POST-REDIRECT-GET模式,但问题是当我重定向时,我无法使用JSTL显示这些数据
怎么做?我会在页面上添加一个不可见的ID。如果数据是数据库的新数据(ID=未知),请插入并创建一个ID,然后用该ID更新页面。这样,您就知道它是否是ID!=未知,您不必进行插入。如果数据没有改变,你甚至不需要做更新…这里是最简单的解决方案
<%@page import="java.util.*"%>
<%@page contentType="text/html" pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%!
//This List is just for demonstration purposes
List<String> names = new ArrayList<String>();
%>
<%
if(request.getParameter("name")!=null ){
names.add(request.getParameter("name"));
session.setAttribute("nameList", names);
//Here you put your database insert code
//Whenever the code execution reaches this line ,
//then it means that you have a new page submission
//and not a refresh or f5 case
response.sendRedirect("index.jsp");
}
%>
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<form action="index.jsp" method="post">
<input type="text" id="name" name="name"/>
</form>
<p>
<table>
<c:forEach items="${nameList}" var="element">
<tr>
<td>Name: <c:out value="${element}"/> </td>
</tr>
</c:forEach>
</table>
</p>
</body>
</html>
您只需要实现这两种方法。addNameToDb(字符串)
将插入数据库中。而getAllNamesFromDb()
将返回一个ArrayList
对象,该对象将代表数据库中的条目。(您不再需要我在第一次回答中介绍的姓名
列表)
我曾想过使用POST-REDIRECT-GET模式,但问题是当我重定向时,我无法使用JSTL显示这些数据
只需发送一个请求参数,标识您希望在新GET请求中显示的信息
// ...
Long id = dataService.save(data);
// ...
response.sendRedirect(request.getContextPath() + "/index?editId=" + id);
然后在中,它被映射到/index
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
Long editId = Long.valueOf(request.getParameter("editId")); // Handle nullcheck yourself.
Data editData = dataService.find(editId);
request.setAttribute("editData", editData); // For the edit form.
List<Data> allData = dataService.list();
request.setAttribute("allData", allData); // For the table/list of all data.
request.getRequestDispatcher("/index.jsp").forward(request, response);
}
@覆盖
受保护的void doGet(HttpServletRequest请求,HttpServletResponse响应)抛出ServletException,IOException{
Long editId=Long.valueOf(request.getParameter(“editId”);//自己处理nullcheck。
Data editData=dataService.find(editId);
setAttribute(“editData”,editData);//用于编辑表单。
List allData=dataService.List();
request.setAttribute(“allData”,allData);//用于所有数据的表/列表。
request.getRequestDispatcher(“/index.jsp”).forward(请求,响应);
}
我认为PRGP(后重定向获取模式)是实现这一点的方法。如果您使用的是SpringWebFlow,那么它有一个FlashScope,您可以在其中放置希望在Post get重定向后保留的数据。使用这种方法,您可以保留的不仅仅是编辑Id。恐怕我对servlet没有经验。我写的是一个典型的场景,我正在使用普通的旧Java和数据库。我想你可以采用那种方法。我不知道servlet技术是否有一些内置功能可以为您实现这一点。Fildor的建议就是实现这一点的方法。在页面中的隐藏字段中包含记录的数据库ID。如果用户尚未提交数据,则应为-1或0。在处理插入数据的请求时,请获取新插入行的数据库ID,并在下次页面中包含该ID。如果用户再次提交表单,请使用ID更新详细信息,这是他们所期望的。顺便说一句,在表单中使用POST而不是GET-然后会提醒用户,如果刷新,数据将重新提交。您好,谢谢您的回复,但我也想向数据库中添加条目。我想做的是假设我使用数据库中的表单创建了一个条目,然后是我的所有条目(假设名称是主键)应该显示在我使用的同一表单下面。它现在显示的很好,但当我点击刷新时,我也发现了重复的条目。我会尝试,但我不想使用会话
范围来存储我的数据,它需要在请求
范围内。谢谢你,巴卢斯,我认为这是一个很好的解决方案,我一定会尝试并让你知道。
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
Long editId = Long.valueOf(request.getParameter("editId")); // Handle nullcheck yourself.
Data editData = dataService.find(editId);
request.setAttribute("editData", editData); // For the edit form.
List<Data> allData = dataService.list();
request.setAttribute("allData", allData); // For the table/list of all data.
request.getRequestDispatcher("/index.jsp").forward(request, response);
}