1

I've searched and tested for 2 days every code I have found, with absolutely no luck. I'm sending a json file to a servlet, and I'm pretty sure that data are correctly sent; for some reason I cannot get them from the input stream of the request.

Here the code from the data sender:

{
...
    HttpURLConnection con = (HttpURLConnection) obj.openConnection();
    con.setRequestMethod("POST");
    con.setRequestProperty("User-Agent", "Mozilla/5.0");
    con.setRequestProperty("Accept-Language", "en-US,en;q=0.5");
    con.setDoOutput(true);
    DataOutputStream wr = new DataOutputStream(con.getOutputStream());

    Gson gson = new Gson();
    String jsonString = gson.toJson(<POJO_to_send>).toString();
    wr.writeBytes(URLEncoder.encode(jsonString,"UTF-8"));

    wr.flush();
    wr.close();        

    String responseMessage = con.getResponseMessage();
...
}

The code from the servlet:

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

    String s = "";
    StringBuilder sb = new StringBuilder();
    BufferedReader br = new BufferedReader(new InputStreamReader(request.getInputStream()));

    while((s=br.readLine())!=null) {
         s = br.readLine();
         sb.append(s);
    }

    String jsonString = sb.toString();
    if (jsonString != null) {
        jsonString = br.readLine();
    }else{
        IOException ioex = new IOException("Error reading data.");
        throw(ioex);
    }   
}

For some reason that I have not found yet, sb.toString() result in null value, because the sb is an empty string. From debug I've found that the buf value of input stream of the request seems not empty (at least there are some byte data in it, and seems to me that they are the same of the data output writer of the sender).

Did you see some error that I have missed? Can I check data send before they reach the servlet (maybe the encoding fails somewhere)?

Any advise/idea?

Thank you

Marco Dalena
  • 23
  • 1
  • 5

3 Answers3

0

As stdunbar said, there is no writing to OutputStream. Thank you joop-eggen for all the suggestions.

Try the following for sending:

   {
    ...
        Gson gson = new Gson();
        DataOutputStream wr = new DataOutputStream(resp.getOutputStream());
        String jsonString = gson.toJson(<POJO_to_send>).toString();

        HttpURLConnection con = (HttpURLConnection) obj.openConnection();
        con.setRequestMethod("POST");
        con.setRequestProperty("Content-Type", "application/json; charset=UTF-8");
        conn.setRequestProperty( "Content-Length", String.valueOf(jsonString.length()));
        con.setDoOutput(true);

        wr.writeBytes(jsonString);
        wr.flush();
        wr.close();     

        String responseMessage = con.getResponseMessage();
    ...
    }

and for getting:

 protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

BufferedReader br = new BufferedReader(new InputStreamReader(request.getInputStream(), "utf-8"));
    String sb = new String(); 
          try {
            String line = "";
            while ((line = br.readLine()) != null)
             sb += line;
          } catch (Exception e) { 
            e.printStackTrace();
          }

      String jsonString = sb;
}
Fr333du
  • 191
  • 13
  • Edited. Do you use `doPost(...)` instead of `doGet(...)`? Also did you check what is the value of `jsonString` after `String jsonString = gson.toJson().toString();`? – Fr333du Sep 14 '16 at 08:16
  • @RealSkeptic actually this puzzled me a bit: since I set request method to use POST, I was expecting a doPost execution server side, but instead request goes through doGet. – Marco Dalena Sep 14 '16 at 08:21
  • There are still issues in this answer. Mainly, it won't compile.You can't assign an OutputStreamWriter to a DataOutputStream, and an OutputStreamWriter would not have a `writeBytes` method. And in the receiver, there is an undefined variable `line`. – RealSkeptic Sep 14 '16 at 08:22
  • @Fr333du I have checked jsonString and it is a string containing my POJO in a json format. – Marco Dalena Sep 14 '16 at 08:23
  • @MarcoDalena Are you sure the request is what you expect? It really *should* go through `doPost`, and if it goes to `doGet`, there won't be an input stream - unless you have a `doPost` that calls `doGet`, or something funny in your `service` method. – RealSkeptic Sep 14 '16 at 08:23
  • @RealSkeptic just debugged: for some reason that I do not understand, the setRequestMethod does not work, and request is sent as GET. And I do not have doPost calling doGet, so I agree with you that request should go through doPost. – Marco Dalena Sep 14 '16 at 08:36
  • @MarcoDalena that would mean that your `con.getOutputStream` is not working, either, because that method sets the request to "POST" if it was "GET". I suggest you check your exception handler, go back and edit your question, and post an [mcve] as the code snippet is not sufficient for analyzing your problem. – RealSkeptic Sep 14 '16 at 08:48
  • Thank you for all suggestions, I improved the answer, but the problem with sending POST is still in there. @MarcoDalena: Here is my example of sending POST in jsp page using jQuery, maybe it will help: http://stackoverflow.com/a/39368450/5502924 Data is the string with your JSON data. – Fr333du Sep 14 '16 at 09:41
  • Added Content-Type and Content-Length. – Fr333du Sep 14 '16 at 09:52
  • @Fr333du thanks. I'm not sending json through ajax nor any kind of web form or whatsoever, it is just a dummy java application that send data to a servlet deployed on Hana Cloud Platform. My intent is to manage correctly the received json on this servlet, but at the moment I'm stucked with this problem of sending fake data of which I care nothing. I'm pretty sure (because I've printed the values) that http client request is correct: I really do not understand why my servlet process this requests as GET. As soon as possible I will try to post a ready-to-run example code. – Marco Dalena Sep 14 '16 at 15:33
  • Added minor changes to the proposed solution. Please also check the solutions proposed here: http://stackoverflow.com/questions/21404252/post-request-send-json-data-java-httpurlconnection – Fr333du Sep 15 '16 at 06:28
0

A DataOutputStream is contraproductive. Without passing content type and charset the code becomes:

For POST one would have expected an HTML form parameter, say json=.... Unfortunately posting form data needs more formating, so let's try it as such.

HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("POST");
con.setRequestProperty("User-Agent", "Mozilla/5.0");
con.setRequestProperty("Accept-Language", "en-US,en;q=0.5");
con.setDoOutput(true);
con.connect(); // .............
OutputStream out = con.getOutputStream();

Gson gson = new Gson();
String jsonString = gson.toJson(<POJO_to_send>).toString() + "\r\n";
out.write(jsonString.getBytes(StandardCharsets.UTF_8));
out.close();

String responseMessage = con.getResponseMessage();

In every case for request method POST one must use doPost in the servlet.

protected void doPost(HttpServletRequest request, HttpServletResponse response)
        throws ServletException, IOException {

    BufferedReader br = new BufferedReader(
        new InputStreamReader(request.getInputStream(), StandardCharsets.UTF_8));

    StringBuilder sb = new StringBuilder();
    String s;
    while ((s = br.readLine()) != null) {
         sb.append(s).append("\n");
    }

    String jsonString = sb.toString();
}
Joop Eggen
  • 107,315
  • 7
  • 83
  • 138
  • I agree with you, but it seems that con.setRequestMethod("POST") does not work, and request is sent as GET; also every following setters calling seem not working and I really do not understand why. – Marco Dalena Sep 14 '16 at 08:41
  • 1
    Thanks to your comment. What was forgotten, was the `connect()`. I have added it. That does send the parameters, headers and starts the real connection. `openConnection ... connect` is something one normally will not forget. – Joop Eggen Sep 14 '16 at 08:54
0

You have to update properties maxpostSize="" in server.xml if you are using tomcat or relevant properties for other server

abhinavsinghvirsen
  • 1,853
  • 16
  • 25