3

I'm learning Java servlets and I wrote two separate servlets for "GET" and "POST". When a "GET" request is sent to the server, the servlet accesses the database and retrieves everything and converts the result to the format that can be recognized by Google Charts. And when a "POST" request is sent to the server, the servlet gets the parameters and adds them to a Java object and then the DAO adds the data to the database. However, when I hit the "add" button after the input, the web app cannot find the servlet at all. It simply just "skips" the ajax function and proceeds. So here's the servlet that does the insertion:

@WebServlet("/InsertServlet")
public class InsertServlet extends HttpServlet 
{
    private static final long serialVersionUID = 1L;
    private EmployeeDao dao;

    public InsertServlet() throws SQLException 
    {
        super();
        dao = new EmployeeDao();
    }

    public void doPost(HttpServletRequest request, HttpServletResponse response) 
            throws ServletException, IOException 
    {
        System.out.println("doPost");
        Employee e = new Employee();
        e.setName(request.getParameter("name"));
        e.setSSN(request.getParameter("ssn"));
        e.setDob(request.getParameter("birth"));
        e.setIncome(request.getParameter("xxxx"));

        dao.addEmployee(e);

        response.setContentType("text/html;charset=utf-8");
        PrintWriter out = response.getWriter();
        out.println("<h2>Data Entry Added</h2><br>");
        out.println("<h2>"+request.getParameter("name")+"</h2>");
        out.println("<h2>"+request.getParameter("ssn")+"</h2>");
        out.println("<h2>"+request.getParameter("birth")+"</h2>");
        out.println("<h2>"+request.getParameter("xxxx")+"</h2>");
        out.flush();
        out.close();


    }
}

And here's the index.html:

<form id="inputForm">
<table style="width:80%;border:3px;">
    <tr>
        <td align="center"><input type="text" name="name" id="name" placeholder="First Last"></td>
        <td align="center"><input type="text" name="ssn" id="ssn" placeholder="111111111"></td>
        <td align="center"><input type="text" name="birth" id="birth" placeholder="MM/DD/YYYY"></td>
        <td align="center"><input type="text" name="xxxx" id="xxxx" placeholder="12345"></td>
        <td align="center"><button type="button" name="add" id="add" >Add</button></td>
        <td align="center"><button type="button" name="delete" id="delete">Delete</button></td>
    </tr>
</table>
</form>
$("#add").click(function() {
            var nameIn = $('#name').val();
            var ssnIn = $('#ssn').val();
            var birthIn = $('#birth').val();
            var xxxxIn = $('#xxxx').val();
            if (validate(nameIn, ssnIn, birthIn, xxxxIn) === true) {
                xxxxIn = "\$" + xxxxIn;
                var ssn1 = ssnIn.substring(0, 3);
                var ssn2 = ssnIn.substring(3, 5);
                var ssn3 = ssnIn.substring(5);
                ssnIn = ssn1 + '-' + ssn2 + '-' + ssn3;

                $.post("InsertServlet", $("#inputForm").serialize(), function(responseHtml) {
                    $('#state').html(responseHtml);
                });
                window.setTimeout(redraw, 1000);
                redraw();
            }
        });

Edit 1: So the web app works all the way to the point where the $ajax of "add" sends the proper request. The JS functions worked fine. The request has the correct values corresponding to the attributes. However, when invoking the /InsertServlet URL, it seems that the web app just ignores the servlet and the getParameter methods all return null in the doPost method.

Edit 2: Tomcat version: 7.0.61. JDK version: 1.7.0_45. Servlet version: 3.0

Scott Wardlaw
  • 652
  • 1
  • 8
  • 13
Warthog0007
  • 71
  • 1
  • 1
  • 7
  • Please describe the problem based on technical observations based on developer's perspective instead of assumptions based on enduser's perspective. As first step, is the JavaScript code properly executed? Is the `$.ajax()` executed and did it send a proper XML HTTP request? (visible in HTTP traffic monitor in webbrowser's web developer toolset). And, it would be nice if you could provide the code in MCVE flavor. There's way too much irrelevant noise in the code posted so far. See also http://stackoverflow.com/help/mcve – BalusC May 10 '15 at 10:16
  • @BalusC So I've edited the question and the main confusion I had was that the InsertServlet was simply ignored but the other servlet which updates the Google Chart Table worked fine and they had similar configurations. – Warthog0007 May 10 '15 at 10:29
  • As per your edit, so the servlet is properly invoked (and thus actually not ignored), it are just the request parameters which are all `null`? – BalusC May 10 '15 at 10:31
  • @BalusC Yes all the parameters returned null in the response string – Warthog0007 May 10 '15 at 10:34
  • You didn't state that as such in the title and question. – BalusC May 10 '15 at 10:34
  • @BalusC I thought the servlet was "ignored" because when I tried to write "System.out.println("blah");" in the doPost method, nothing shows up on the console when I pressed the "add" button. But when I did the same thing on the other servlet, it actually printed "blah" on the console. – Warthog0007 May 10 '15 at 10:37

1 Answers1

10

Your mistake is in the dataType and data properties of $.ajax() option:

  $.ajax({
        type:"POST",
        url:"InsertServlet",
        dataType:"json",
        data: {
            name: nameIn, 
            ssn: ssnIn, 
            birth: birthIn, 
            xxxx: xxxxIn
        },
        // ...

As per the $.ajax() documentation, the dataType property instructs jQuery in what format the response will be returned (which is in your case by the way just HTML as indicated by text/html and definitely not JSON as indicated by application/json). It does not represent the format of request parameters as you incorrectly expected. And, the data property must represent the URL-encoded HTTP request query string conform the application/x-www-form-urlencoded content type, and thus not a JSON object.

That explains why the request parameters are null.

Remove the dataType attribute. You don't need it here and jQuery is smart enough to autodetect it based on response's Content-Type header.

Fix the data attribute to be a true URL-encoded HTTP request query string. You can do it either of the following ways:

  1. Use $.serialize() on the form. Given a <form id="yourFormId">:

    data: $("#yourFormId").serialize(),
    
  2. Use $.param() on the JSON object:

    data: $.param({
            name: nameIn, 
            ssn: ssnIn, 
            birth: birthIn, 
            xxxx: xxxxIn
        }),
    
  3. Manually compose the URL-encoded HTTP request query string.

    data: "name=" + encodeURIComponent(nameIn) 
       + "&ssn=" + encodeURIComponent(ssnIn)
       + "&birth=" + encodeURIComponent(birthIn)
       + "&xxxx=" + encodeURIComponent(xxxxIn),
    
  4. Use JSON.stringify() along with proper content type.

    contentType: "application/json",
    data: JSON.stringify({
            name: nameIn, 
            ssn: ssnIn, 
            birth: birthIn, 
            xxxx: xxxxIn
        }),
    

    This only requires a change in the servlet: it must parse the request body as JSON and not use getParameter() and such. As this is tedious, you'd better replace the servlet by a JAX-RS webservice which offers builtin facilities to handle this transparently.


Unrelated to the concrete problem, using $.post() instead of $.ajax() reduces the boilerplate code.

$.post("InsertServlet", $("#yourFormId").serialize(), function(responseHtml) {
    $('#state').html(responseHtml); 
});

See also:

Community
  • 1
  • 1
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • So I modified my code as you suggested and now use $.post() method but it still behaves the same way as before... – Warthog0007 May 10 '15 at 11:01
  • So, `request.getParameter()` still returns `null`? Which way have you used? – BalusC May 10 '15 at 11:06
  • Apparently you gave the input elements a different name than the ID they have (or even no names at all). Given a `` the request parameter name is `foo`. – BalusC May 10 '15 at 11:15
  • Actually I gave the same ids and names, as above. – Warthog0007 May 10 '15 at 11:17
  • What does `System.out.println(request.getParameterMap());` say? – BalusC May 10 '15 at 11:18
  • {name=[Ljava.lang.String;@5bb6e314, ssn=[Ljava.lang.String;@43f66516, birth=[Ljava.lang.String;@6566aa35, xxxx=[Ljava.lang.String;@3730b195} At least the console printed something this time... – Warthog0007 May 10 '15 at 11:20
  • Well, the parameters are clearly successfully sent and retrieved. So the jQuery part works fine. Those parameters are definitely not null. Perhaps you've a different and wrong definiton of "null" than what's being teached in the average sane Java tutorial? Perhaps those are actually just empty strings? What do you see when you do `System.out.println("[" + request.getParameter("name") + "]");` ? – BalusC May 10 '15 at 11:22
  • And by the way I used HTTP Client to send a POST request to the server and then the response returned "

    null

    " but not by calling System.out.println(request.getParameter("name")) in the servlet..
    – Warthog0007 May 10 '15 at 11:32
  • Well that's clearly a different problem, not related to jQuery+Servlet integration anymore. Feel free to ask a new question with a MCVE (without jQuery) if you still can't get that part solved. – BalusC May 10 '15 at 11:35
  • Oh just want to tell you that I've solved it. Turns out I forgot to put "executeUpdate()" after preparing the insert statement in the DAO class and the local server was also problematic...So I deployed everything to my remote server and everything began to be normal. Also turns out that the "data" part in $.post CAN be written as {name:nameIn, ssn:ssnIn...}. Thank you again for helping me. – Warthog0007 May 10 '15 at 19:44