Question

I have an index.jsp page where I have a form where the user enters some data that gets stored in the database using a Controller servlet.

I want to display the same page (index.jsp) with that form after entering the data in the database. Also, I want to display all the entries that the user entered in the database.

I tried using the forward() method of RequestDispatcher. It works fine (meaning I am able to display that same form again and also display all the data entered by that user below the form using JSTL).

But the problem is whenever the user presses the Refresh or F5 button, all the previous data also gets entered in the database and as I am displaying all the data, and that duplicate entries also come up.

I thought of using the POST-REDIRECT-GET pattern, but the problem is when I redirect I don't get those data to be displayed using JSTL.

How do I do it?

Was it helpful?

Solution

I thought of using POST-REDIRECT-GET pattern but the problem is when I redirect I don't get those data to be displayed using JSTL.

Just send a request parameter along identifying the information you'd like to display in the new GET request.

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

and then in the servlet which is mapped on an URL pattern of /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);
}

OTHER TIPS

I would add an invisible ID to the page. If the data is new to the database (ID = unknown), insert and create an ID and update the page with the ID. That way you know if it is a ID != unknown, and you don't have to do an insert. And if the data hasn't changed, you don't even have to do an update...

Here is the simplest solution

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

The trick lies with the response.sendRedirect("index.jsp");. This makes null all request parameters. If an f5 or refresh is hit, then the if is never executed. If a normal submit is the case, then the if is executed and you call the response.sendRedirect("index.jsp");.

In summary, all you really need to do is:

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

2) If above is true then do database inserts

3) If above is true then response.sendRedirect("index.jsp");

UPDATE

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

You just have to implement these 2 methods. The addNameToDb(String) will make the insert in your database. And the getAllNamesFromDb() will return an ArrayList<String> Object that will represent on the entries from your database. (And you no longer need the names list introduced before in my first answer)

I think PRGP (Post Redirect Get Pattern) is the way to go for this. If you're using Spring Web Flow it has a FlashScope where you can put the data that you want to be retained after the Post-get-redirection. You can retain more than just an edit Id using this approach.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top