Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/html/85.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/visual-studio/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何在刷新时防止重复条目?_Java_Html_Jsp_Servlets_Post Redirect Get - Fatal编程技术网

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);
}