Как предотвратить дублирование записей во время обновления?
у меня есть index.jsp
страница, где у меня есть форма, где пользователь вводит некоторые данные, которые хранятся в базе данных с помощью контроллера-сервлета.
Я хочу отобразить ту же страницу (index.jsp
) с этой формой после ввода данных в базу данных. Кроме того, я хочу, чтобы отобразить все записи, которые пользователь ввел в базу данных.
Я попытался с помощью forward()
метод RequestDispatcher
. Он отлично работает (это означает, что я могу снова отобразить ту же форму, а также отобразить все данные, введенные этим пользователем под формой с помощью JSTL).
но проблема в том, когда пользователь нажимает Refresh or F5
кнопка, все предыдущие данные также вводятся в базу данных, и поскольку я отображаю все данные, и эти дубликаты также появляются.
Я думал об использовании шаблона POST-REDIRECT-GET, но проблема в том, что при перенаправлении я не получаю эти данные для отображения с помощью JSTL.
как мне это сделать?
4 ответов
Я думал об использовании шаблона POST-REDIRECT-GET, но проблема в том, что когда я перенаправляю, я не получаю эти данные для отображения с помощью JSTL.
просто отправьте параметр запроса вместе с идентификацией информации, которую вы хотите отобразить в новом запросе GET.
// ...
Long id = dataService.save(data);
// ...
response.sendRedirect(request.getContextPath() + "/index?editId=" + id);
а потом в сервлет который отображается на шаблоне URL /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);
}
Я бы добавил невидимый идентификатор на страницу. Если данные являются новыми для базы данных (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>
фокус заключается в response.sendRedirect("index.jsp");
. Это делает null
параметры запроса. Если f5
или refresh
попадает, затем if
никогда не выполняется. Если обычный submit имеет место, то if
выполняется и вы вызываете response.sendRedirect("index.jsp");
.
в общем, все, что вам действительно нужно сделать, это:
1) Проверить if(request.getParameter("name")!=null )
2) Если выше верно, то сделайте вставки базы данных
3) Если выше верно тогда response.sendRedirect("index.jsp");
обновление
if(request.getParameter("name")!=null ){
DbUtility.addNameToDb(request.getParameter("name"));
ArrayList<String> currentList = DbUtility.getAllNamesFromDb();
session.setAttribute("nameList", currentList);
response.sendRedirect("index.jsp");
}
вам просто нужно реализовать эти 2 метода. The addNameToDb(String)
сделает insert
в вашей базе данных. И getAllNamesFromDb()
возвращает ArrayList<String>
объект, который будет представлять записи из вашей базы данных. (И вам больше не нужно names
список, представленный ранее в моем первом ответе)
Я думаю, что PRGP (Post Redirect Get Pattern) - это способ пойти на это. Если вы используете Spring Web Flow, у него есть FlashScope, где вы можете поместить данные, которые хотите сохранить после перенаправления Post-get. С помощью этого подхода можно сохранить не только идентификатор редактирования.