2012-10-04 81 views
6

Tengo una página index.jsp donde tengo un formulario donde el usuario ingresa algunos datos que se almacenan en la base de datos utilizando un servlet de controlador.¿Cómo prevenir las entradas duplicadas mientras se actualiza?

Quiero mostrar la misma página (index.jsp) con ese formulario después de ingresar los datos en la base de datos. Además, quiero mostrar todas las entradas que el usuario ingresó en la base de datos.

Intenté usar el método forward() de RequestDispatcher. Funciona bien (lo que significa que puedo volver a mostrar ese mismo formulario y también mostrar todos los datos ingresados ​​por ese usuario debajo del formulario usando JSTL).

Pero el problema es que cada vez que el usuario presiona el botón Refresh or F5, todos los datos anteriores también se ingresan en la base de datos y aparecen todos los datos, y también aparecen entradas duplicadas.

Pensé en usar el patrón POST-REDIRECT-GET, pero el problema es que cuando redirecciono no obtengo esos datos para mostrarlos usando JSTL.

¿Cómo lo hago?

Respuesta

9

pensé en utilizar el patrón de POST-REDIRECT-GET, pero el problema es cuando vuelvo a dirigir no consigo esos datos a visualizar usando JSTL.

Simplemente envíe un parámetro de solicitud junto con la identificación de la información que desea mostrar en la nueva solicitud GET.

// ... 
Long id = dataService.save(data); 
// ... 
response.sendRedirect(request.getContextPath() + "/index?editId=" + id); 

y luego en el servlet que es mapeado en un patrón de URL de /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); 
} 
+0

Gracias Balus Creo que esta es una buena solución. Definitivamente intentaré esto y te lo haré saber. – Abubakkar

+0

¡Funciona perfectamente! – Abubakkar

+0

De nada. – BalusC

5

Agregaría una identificación invisible a la página. Si los datos son nuevos en la base de datos (ID = desconocido), inserte y cree una ID y actualice la página con la ID. De esta forma, sabrá si es una identificación! = Desconocida, y no tiene que hacer una inserción. Y si los datos no han cambiado, que ni siquiera tiene que hacer una actualización ...

+0

puede señalar o sugerir a mejores maneras – Abubakkar

+0

Me temo que no tengo experiencia con servlets. Lo que escribí fue una situación típica a la que me enfrento usando antiguas bases de datos Java. Supongo que podrías adoptar ese enfoque. Lo que no puedo decir es si la tecnología de servlet tiene alguna característica incorporada que lo haga por usted. – Fildor

+1

La sugerencia de Fildor es la forma de hacerlo. Incluya el ID de la base de datos de su registro en la página en un campo oculto. Si el usuario aún no ha enviado los datos, esto debería ser -1 o 0. Cuando procese la solicitud para insertar los datos, obtenga la ID de la base de datos de la fila recién insertada e inclúyala en la página la próxima vez. Si el usuario envía nuevamente el formulario, use la ID para actualizar los detalles, que es lo que esperarían. Por cierto, use un POST no un GET en su formulario: se alertará al usuario de que los datos se volverán a enviar si se actualizan. –

0

Aquí es la solución más simple

<%@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> 

El truco recae en el response.sendRedirect("index.jsp");. Esto hace que null todos los parámetros de solicitud. Si se golpea un f5 o refresh, entonces el if nunca se ejecuta. Si es un caso normal, entonces se ejecuta el if y usted llama al response.sendRedirect("index.jsp");.

En resumen, todo lo que necesita hacer es:

1) Verificar if(request.getParameter("name")!=null)

2) Si anteriormente es cierto, entonces hacer la base de datos inserta

3) Si anteriormente es cierto, entonces response.sendRedirect("index.jsp");

ACTUALIZACIÓN

if(request.getParameter("name")!=null){ 
    DbUtility.addNameToDb(request.getParameter("name")); 
    ArrayList<String> currentList = DbUtility.getAllNamesFromDb(); 
    session.setAttribute("nameList", currentList); 
    response.sendRedirect("index.jsp"); 
} 

Solo tiene que implementar estos 2 métodos. El addNameToDb(String) hará que el insert en su base de datos. Y el getAllNamesFromDb() devolverá un objeto ArrayList<String> que representará en las entradas de su base de datos. (Y ya no necesita la lista names introducido antes en mi primera respuesta)

+0

Hola, gracias por su respuesta, pero también quiero agregar entradas a la base de datos. Lo que quiero hacer es suponer que hice 1 entrada usando el formulario en la base de datos, entonces todas mis entradas (se supone que el nombre es la clave principal) deberían ser se muestra debajo de la misma forma que yo usé Se muestra bien por ahora, pero cuando toco actualizar también encuentro las entradas duplicadas. – Abubakkar

+0

ver mi ACTUALIZACIÓN en la lógica – MaVRoSCy

+0

Lo intentaré, pero no quiero usar el alcance de 'sesión' para almacenar mis datos, debe estar en el alcance' request'. – Abubakkar

0

Creo PRGP (Agrega redirección Obtener Pattern) es el camino a seguir para ello. Si está utilizando Spring Web Flow, tiene un FlashScope donde puede guardar los datos que desea conservar después de la redirección de publicación posterior. Puede conservar más que solo una Id de edición usando este enfoque.

Cuestiones relacionadas