16

I can not see what is wrong with this code:

JSONObject msg;  //passed in as a parameter to this method

HttpURLConnection httpCon = (HttpURLConnection) url.openConnection();
httpCon.setDoOutput(true);
httpCon.setDoInput(true);
httpCon.setUseCaches(false);
httpCon.setRequestProperty( "Content-Type", "application/json" );
httpCon.setRequestProperty("Accept", "application/json");
httpCon.setRequestMethod("POST");
OutputStream os = httpCon.getOutputStream();
OutputStreamWriter osw = new OutputStreamWriter(os, "UTF-8");
msg.write(osw);
osw.flush();
osw.close();    
os.close();     //probably overkill

On the server, I am getting no post content at all, a zero length string.

AgilePro
  • 5,588
  • 4
  • 33
  • 56
  • I know it looks strange, but the JSONObject class has a write method which you pass a Writer object to, and the class writes itself to the stream. This is far more efficient than converting to a string and then writing the string. That does not really make a difference in this situation, we could steam anything to the Writer and the test is the same. The error is about getting the connection. – AgilePro Jun 09 '17 at 22:15

5 Answers5

26

Try

...
httpCon.setRequestMethod("POST");
httpCon.connect(); // Note the connect() here
...
OutputStream os = httpCon.getOutputStream();
OutputStreamWriter osw = new OutputStreamWriter(os, "UTF-8");
...    
osw.write(msg.toString());
osw.flush();
osw.close();

to send data.

to retrieve data try:

BufferedReader br = new BufferedReader(new InputStreamReader( httpCon.getInputStream(),"utf-8"));
String line = null;
while ((line = br.readLine()) != null) {
    sb.append(line + "\n");
}
br.close();
System.out.println(""+sb.toString());
ingh.am
  • 25,981
  • 43
  • 130
  • 177
Yser
  • 2,086
  • 22
  • 28
  • 1
    The reason that I don't use "msg.toString()" is that I don't want to make a second copy of the data. I use the msg.write() to write to file writers all the time, so I know this writes to a stream properly. The only other difference is the call to "connect" I will try that. – AgilePro Feb 23 '14 at 21:21
  • Yes, the "connect" seemed to fix it (which is strange because the server GOT a request, so a connection was made, but apparently "connect" actually sends the body? Are there constraints on where connect has to be done? After headers and before getOutputStream? – AgilePro Feb 23 '14 at 21:26
  • JavaDoc says "URLConnection objects go through two phases: first they are created, then they are connected. After being created, and before being connected, various options can be specified (e.g., doInput and UseCaches). After connecting, it is an error to try to set them. Operations that depend on being connected, like getContentLength, will implicitly perform the connection, if necessary.". Maybe close() forces a connect() but the flush() is way to early? In addition even close() on the OSW is already triggered. – Yser Feb 23 '14 at 21:36
5
 public String sendHTTPData(String urlpath, JSONObject json) {
        HttpURLConnection connection = null;
        try {
            URL url=new URL(urlpath);
            connection = (HttpURLConnection) url.openConnection();
            connection.setDoOutput(true);
            connection.setDoInput(true);
            connection.setRequestMethod("POST");
            connection.setRequestProperty("Content-Type", "application/json");
            connection.setRequestProperty("Accept", "application/json");
            OutputStreamWriter streamWriter = new OutputStreamWriter(connection.getOutputStream());
            streamWriter.write(json.toString());
            streamWriter.flush();
            StringBuilder stringBuilder = new StringBuilder();
            if (connection.getResponseCode() == HttpURLConnection.HTTP_OK){
                InputStreamReader streamReader = new InputStreamReader(connection.getInputStream());
                BufferedReader bufferedReader = new BufferedReader(streamReader);
                String response = null;
                while ((response = bufferedReader.readLine()) != null) {
                    stringBuilder.append(response + "\n");
                }
                bufferedReader.close();

                Log.d("test", stringBuilder.toString());
                return stringBuilder.toString();
            } else {
                Log.e("test", connection.getResponseMessage());
                return null;
            }
        } catch (Exception exception){
            Log.e("test", exception.toString());
            return null;
        } finally {
            if (connection != null){
                connection.disconnect();
            }
        }
    }`

call this methopd in doitbackground in asynctask

Mahadev Dalavi
  • 173
  • 1
  • 7
4

HttpURLConnection is cumbersome to use. With DavidWebb, a tiny wrapper around HttpURLConnection, you can write it like this:

JSONObject msg;  //passed in as a parameter to this method

Webb webb = Webb.create();
JSONObject result = webb.post("http://my-url/path/to/res")
    .useCaches(false)
    .body(msg)
    .ensureSuccess()
    .asJsonObject()
    .getBody();

If you don't like it, there is a list of alternative libraries on the link provided.

Why should we all write the same boilerplate code every day? BTW the code above is more readable and less error-prone. HttpURLConnection has an awful interface. This has to be wrapped!

hgoebl
  • 12,637
  • 9
  • 49
  • 72
  • Does this .body handle streaming JSON instead the DOM-like JsonObject way of serializing JSON? I mean, if I want to use GSON streaming as per https://sites.google.com/site/gson/streaming does this Webb handle that? – diegosasw Sep 29 '14 at 21:53
  • It looks very interesting though and I think I'll give it a try because of the easy GZIP compression. But I cannot find anything about support of streaming JSON – diegosasw Sep 29 '14 at 21:55
  • Have a look at the [issue](https://github.com/hgoebl/DavidWebb/issues/5). Thank you @realavaloro. If we can find a solution, I'll update the answer. – hgoebl Sep 30 '14 at 06:12
  • wow, looks very nice and simple. How do I get the HTTP(s) respond code? like 200, 401..? – CularBytes May 17 '15 at 17:36
  • 1
    @RageCompex you can access status code and other things [like in this example/test-case](https://github.com/hgoebl/DavidWebb/blob/master/src/test/java/com/goebl/david/TestWebb.java#L53-L64) – hgoebl May 18 '15 at 08:33
  • thanks for the reply, but I'm running into problems with the dependencies, the app crashes when executing this command, turns out I have problems with the apache packages. Trying to repackage with jarjar without any luck atm :( Really annoying, something THAT simple and still a pain in the ass to implement. – CularBytes May 18 '15 at 08:46
1

Follow this example:

public static PricesResponse getResponse(EventRequestRaw request) {

    // String urlParameters  = "param1=a&param2=b&param3=c";
    String urlParameters = Piping.serialize(request);

    HttpURLConnection conn = RestClient.getPOSTConnection(endPoint, urlParameters);

    PricesResponse response = null;

    try {
        // POST
        OutputStreamWriter writer = new OutputStreamWriter(conn.getOutputStream());
        writer.write(urlParameters);
        writer.flush();

        // RESPONSE
        BufferedReader reader = new BufferedReader(new InputStreamReader((conn.getInputStream()), StandardCharsets.UTF_8));
        String json = Buffering.getString(reader);
        response = (PricesResponse) Piping.deserialize(json, PricesResponse.class);

        writer.close();
        reader.close();

    } catch (Exception e) {
        e.printStackTrace();
    }

    conn.disconnect();

    System.out.println("PricesClient: " + response.toString());

    return response;
}


public static HttpURLConnection getPOSTConnection(String endPoint, String urlParameters) {

    return RestClient.getConnection(endPoint, "POST", urlParameters);

}


public static HttpURLConnection getConnection(String endPoint, String method, String urlParameters) {

    System.out.println("ENDPOINT " + endPoint + " METHOD " + method);
    HttpURLConnection conn = null;

    try {
        URL url = new URL(endPoint);
        conn = (HttpURLConnection) url.openConnection();
        conn.setRequestMethod(method);
        conn.setDoOutput(true);
        conn.setRequestProperty("Content-Type", "text/plain");

    } catch (IOException e) {
        e.printStackTrace();
    }

    return conn;
}
1

this without json String post data to server

 class PostLogin extends AsyncTask<Void, Void, String> {
        @Override
        protected String doInBackground(Void... params) {
            String response = null;

            Uri.Builder builder= new Uri.Builder().appendQueryParameter("username","amit").appendQueryParameter("password", "amit");
            String parm=builder.build().getEncodedQuery();
      try
           {

               response = postData("your url here/",parm);
           }catch (Exception e)
           {
               e.printStackTrace();
           }
            Log.d("test", "response string is:" + response);
            return response;
        }
    }


private String postData(String path, String param)throws IOException {
        StringBuffer response = null;

        URL  url = new URL(path);
        HttpURLConnection  connection = (HttpURLConnection) url.openConnection();
        connection.setRequestMethod("POST");
        connection.setDoOutput(true);
//        connection.setRequestProperty("Content-Type", "application/json");
//        connection.setRequestProperty("Accept", "application/json");
            OutputStream out = connection.getOutputStream();
            out.write(param.getBytes());
            out.flush();
            out.close();
            int responseCode = connection.getResponseCode();
            if (responseCode == HttpURLConnection.HTTP_OK) {
                BufferedReader br = new BufferedReader(new InputStreamReader(connection.getInputStream()));
                String line;
                response = new StringBuffer();
                while ((line = br.readLine()) != null) {
                    response.append(line);
                }
                br.close();
            }

        return response.toString();
    }
Mahadev Dalavi
  • 173
  • 1
  • 7