2


I'm trying to create a page that register new products and show the results list in same page.
This is my product.jsp page.

<%@page contentType="text/html" pageEncoding="UTF-8"%>  
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!DOCTYPE html>
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title>JSP Page</title>
        <script src="//code.jquery.com/jquery-1.10.2.js" type="text/javascript"></script>
    </head>
    <body>
        <table>
            <tr>
                <th>ID</th>
                <th>Name</th>
                <th>Description</th>
                <th>Price</th>
            </tr>
            <div>
                <c:forEach items="${products}" var="product">
                    <tr>
                        <td>${product.id}</td>
                        <td><c:out value="${product.name}" /></td>
                        <td><c:out value="${product.description}" /></td>
                        <td><c:out  value="${product.price}" /></td>
                    </tr>
                </c:forEach>
            </div>
        </table>
        <br/><br/>
        <form  id="form1" action="${pageContext.request.contextPath}/" method="post">
            <table> 
                <tr> <td>Product Name : <input type="text" name="pname" id="pname" /></td></tr>
                <tr> <td>Product Description : <input type="text" name="pdesc" id="pdesc"/></td></tr>
                <tr><td>Product Price : <input type="text" name="price" id="price"/></td></tr>
                <tr><td> <input type="submit" value="save"/></td></tr>

            </table>
            <h4 style="color: red" id="result"><c:out value="${msg}"/></h4>
        </form> 
        <script>
            $(document).ready(function () {            
                $('#form1').submit(function () {       .
                    $form = $(this);                            
                    $.post($form.attr('action'),
                            $form.serialize(),
                            function (responseText) {      
                                $('#result').text(responseText); 
                                $('#pname').val('');
                                $('#pdesc').val('');
                                $('#price').val('');
                            });
                    return false;                                    
                });
            });
        </script>
    </body>
</html>

And here is my products.java servlet.
doGet() method usually calls when the page is loaded and it returns the registered item list.
doPost() method on the other hand save the records and returns the results back to the product.jsp page.

   @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        try {
            List<Product> products = productDAO.list();
            request.setAttribute("products", products); 
            request.getRequestDispatcher("/products.jsp").forward(request, response);
        } catch (SQLException e) {
            throw new ServletException("Cannot obtain products from DB", e);
        }
    }

    @Override
    protected void doPost(HttpServletRequest requset, HttpServletResponse response) throws ServletException, IOException {
        response.setContentType("text/plain");
        response.setCharacterEncoding("UTF-8");
        try {
            Product p = new Product();
            p.setName(requset.getParameter("pname"));
            p.setDescription(requset.getParameter("pdesc"));
            p.setPrice(new BigDecimal(requset.getParameter("price")));
            if (productDAO.Save(p) > 0) {
               response.getWriter().write(String.valueOf("sucess"));
            } else {
                response.getWriter().write(String.valueOf("saved fail"));
            }
        } catch (Exception e) {
            e.printStackTrace();
            response.getWriter().write(String.valueOf(e));
        }

Also this is my web.xml file that indicate products.java servlet file load in the startup of the application.

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.1" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd">
    <servlet>
        <servlet-name>products</servlet-name>
        <servlet-class>com.shop.controller.products</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>products</servlet-name>
        <url-pattern/>
    </servlet-mapping>
    <session-config>
        <session-timeout>
            30
        </session-timeout>
    </session-config>
    <resource-ref>
        <description>DB Connection</description>
        <res-ref-name>jdbc/MyDatasource</res-ref-name>
        <res-type>javax.sql.DataSource</res-type>
        <res-auth>Container</res-auth>
    </resource-ref>
</web-app>

This web page is working finely, but the problem that I have is I want to update the given list after registration of the item.
Currently I only send a successful or error message only. I got an suggestion saying that I should use json. But to my knowledge it won't update the same given table.
Please help. Thank you.

Dil.
  • 1,996
  • 7
  • 41
  • 68

2 Answers2

2

Check out BalusC's answer here, it's a godsend. As you can see from it there are many different ways to handle your response data. Below i'll give you an example using your code.

For example, you could do something like this:

product.jsp

<%@page contentType="text/html" pageEncoding="UTF-8"%>  
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!DOCTYPE html>
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title>JSP Page</title>
        <script src="//code.jquery.com/jquery-1.10.2.js" type="text/javascript"></script>
    </head>
    <body>
        <table>
            <tr>
                <th>ID</th>
                <th>Name</th>
                <th>Description</th>
                <th>Price</th>
            </tr>
            <div>
                <c:forEach items="${products}" var="product">
                    <tr>
                        <td>${product.id}</td>
                        <td><c:out value="${product.name}" /></td>
                        <td><c:out value="${product.description}" /></td>
                        <td><c:out  value="${product.price}" /></td>
                    </tr>
                </c:forEach>
            </div>
        </table>
        <br/><br/>
        <form  id="form1" action="YourProductsServlet" method="post">
            <table> 
                <tr> <td>Product Name : <input type="text" name="pname" id="pname" /></td></tr>
                <tr> <td>Product Description : <input type="text" name="pdesc" id="pdesc"/></td></tr>
                <tr><td>Product Price : <input type="text" name="price" id="price"/></td></tr>
                <tr><td> <input type="submit" value="save"/></td></tr>

            </table>
            <div style="color: red" id="result"></div>
        </form> 
        <script>
    //ajaxifying an existing form
    $(document).on("submit", "#form1", function(event) {
       var $form = $(this);
       $.post($form.attr("action"), $form.serialize(), function(responseJson) {
        // handle response data 

   var $table = $("<table>").appendTo($("#result")); // Create HTML <table> element and append it to HTML DOM element with ID "result".
        $.each(responseJson, function(index, product) {    // Iterate over the JSON array.
            $("<tr>").appendTo($table)                     // Create HTML <tr> element, set its text content with currently iterated item and append it to the <table>.
                .append($("<td>").text(product.id))        // Create HTML <td> element, set its text content with id of currently iterated product and append it to the <tr>.
                .append($("<td>").text(product.name))      // Create HTML <td> element, set its text content with name of currently iterated product and append it to the <tr>.
                .append($("<td>").text(product.price));    // Create HTML <td> element, set its text content with price of currently iterated product and append it to the <tr>.
        });

       });    
       event.preventDefault(); // Important! Prevents submitting the form.
    });
        </script>
    </body>
</html>

products.java

Note: Servlets by convention start with a capital letter. Also in your web.xml there is no url mapping set.. So as shown in the form above i'm going to assume it's set as "YourProductsServlet"

 @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
      //in this case we are going to use this doGet method to handle your ajax response and when you initially load your data so we need to check if it's ajax or not, we can do that with this:
   boolean ajax = "XMLHttpRequest".equals(request.getHeader("X-Requested-With"));

        try {

            List<Product> products = productDAO.list();
            request.setAttribute("products", products); 



     if (ajax) {
    //where the magic happens
   //Returning List<Entity> as JSON
    String json = new Gson().toJson(products);
    response.setContentType("application/json");
    response.setCharacterEncoding("UTF-8");
    response.getWriter().write(json);
    }else{
    //not an ajax request so process normally
    request.getRequestDispatcher("/products.jsp").forward(request, response);
    }

        } catch (SQLException e) {
            throw new ServletException("Cannot obtain products from DB", e);
        }
    }

    @Override
    protected void doPost(HttpServletRequest requset, HttpServletResponse response) throws ServletException, IOException {
  //your form submits your new product to here, where you will save in your database
        try {
            Product p = new Product();
            p.setName(requset.getParameter("pname"));
            p.setDescription(requset.getParameter("pdesc"));
            p.setPrice(new BigDecimal(requset.getParameter("price")));

            productDAO.Save(p);
            //if (productDAO.Save(p) > 0) {
               //response.getWriter().write(String.valueOf("sucess"));
            //} else {
                //response.getWriter().write(String.valueOf("saved fail"));
            //}
        } catch (Exception e) {
            e.printStackTrace();
            //response.getWriter().write(String.valueOf(e));
        }

    doGet(request,response); //forward request and response to doGet method
}

Let me know if that works/helps or if you have questions.

Jonathan Laliberte
  • 2,672
  • 4
  • 19
  • 44
  • 1
    OMG. It's works like a charm. Thank you. The reason that I didn't use a URL pattern because I wanted it to become startup servlet with the project, Thanks again. – Dil. May 17 '18 at 03:40
0

Your code is indeed working correctly and as intended.

What you need to do, is to either trigger a reload of the page on the success callback (not very user-friendly) or update your table using JavaScript to modify the DOM of the page (how most modern systems work).

Such tasks are easier to accomplish using a JavaScript framework to dynamically render and keep the page updated based on changes in the server. There are very simple and easy-to-use libraries like Backbone.js, and more advanced ones like AngularJS and React.

Guilherme Mussi
  • 956
  • 7
  • 14