1

I'm very new to android programming and I have a problem with OutputStreamWriter. Now i'm working on simple test appication to send a POST requests to a server. There is a PHP application on the server side, which is designed to write data in a txt file. When i run my android app it goes through the code and the commands in the "finally" block are performed. The server really writes in the txt file, but it puts empty data.

I've tried also with GET method and tried to check REQUEST array. But no data are sent. If i delete from my code OutputStreamWriter I obtain the same picture, so it doesn't work at all. I also tried with using encoding, the same result.

I have done through similar questions: OutputStreamWriter not writing - writing to file and problem was with its creating;

Android, Java: HTTP POST Request - here and a few other questions is used httpClient which is depricated now.

HttpUrlConnection getOutputStream have plroblem, HttpUrlConnection getOutputStream have plroblem - here networking at main thread, but mine is run on the another one;

Android POST request not working, Java HttpURLConnection OutputStreamWriter is empty - is proposed to use reader to receive input stream. I've tried this solution, but the result was the same (no data sent)

My android version 6.0.1. What is the problem may be in?

package com.victoria.requester;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import java.io.*;
import java.net.*;
import android.widget.TextView;
import java.io.IOException;
import java.net.URL;
import java.net.HttpURLConnection;

public class MainActivity extends AppCompatActivity {

    public final static String EXTRA_MESSAGE = "EXTRA_MESSAGE";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        thread.start();
    }

    Thread thread = new Thread(new Runnable() {

        @Override
        public void run() {
            String url = "http://192.168.56.226:90/wfile.php";
            String f_name = "123";
            HttpURLConnection httpCon = null;
            TextView textView = findViewById(R.id.textView);
            textView.setText("OK1!");

            try {
                textView.setText("OK2!");
                URL urlObj = new URL(url);
                httpCon = (HttpURLConnection) urlObj.openConnection();

                httpCon.setDoInput(true);
                httpCon.setDoOutput(true);
                //httpCon.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
                httpCon.setRequestProperty("Content-Type", "text/html");
                httpCon.setRequestMethod("POST");

                String parameters = "f_name"+f_name;
                //String parameters = URLEncoder.encode("f_name", "UTF-8") + "=" + URLEncoder.encode("123", "UTF-8");

                httpCon.getResponseCode();


                OutputStreamWriter writer = new OutputStreamWriter(httpCon.getOutputStream());
                writer.write(parameters);
                writer.close();

            } catch (MalformedURLException e) {
                textView.setText("bad  URL!");
            } catch (IOException e) {
                textView.setText("network error!");
            } finally {
                httpCon.disconnect();
                textView.setText("All done");


            }
        }
    });

}

Victoria
  • 395
  • 3
  • 13

2 Answers2

1

So, I've finally solved my problem, which actually was complex. First of all, thank you, @Stephen C. When I moved getResponseCode AFTER getOutputStream() my server begun to receive requests. It's important that without calling getResponseCode the data weren't sent.

But the second trouble was with string: String parameters = "f_name" + f_name;

As I lost "=" the name of the element in the POST array was 'f_name123' and value was empty))) That's why i couldn't pick the data up from $_POST["f_name"].

Also I'd like to notice that textview doesn't work only if accessing within the connection. After disconnected you can use textview.

Thank to all for help.

The next code works for me now:


package com.victoria.requester;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import java.io.*;
import java.net.*;
import android.widget.TextView;
import java.io.IOException;
import java.net.URL;
import java.net.HttpURLConnection;




public class MainActivity extends AppCompatActivity {

    public final static String EXTRA_MESSAGE = "EXTRA_MESSAGE";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        thread.start();
    }




    Thread thread;

    {
        thread = new Thread(new Runnable() {

            @Override
            public void run() {
                String url = "http://192.168.56.226:90/wfile.php";
                String f_name = "123";
                HttpURLConnection httpCon = null;
                TextView textView = findViewById(R.id.textView);


                try {
                    URL urlObj = new URL(url);
                    httpCon = (HttpURLConnection) urlObj.openConnection();

                    httpCon.setDoOutput(true);
                    httpCon.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");

                    httpCon.setRequestMethod("POST");

                    String parameters = "f_name=" + f_name;





                    OutputStreamWriter writer = new 
 OutputStreamWriter(httpCon.getOutputStream());
                    writer.write(parameters);
                    writer.flush();


                    writer.close();

                    httpCon.getResponseCode(); 


                } catch (MalformedURLException e) {
                    textView.setText("bad  URL!");
                } catch (IOException e) {
                    textView.setText("network error!");
                } finally {
                    httpCon.disconnect();
                    textView.setText("All done");


                }
            }
        });
    }

}
Victoria
  • 395
  • 3
  • 13
  • Just to note that the `flush()` is redundant. The `close()` will do any flushing that is necessary. In general, and in this case. – Stephen C Apr 02 '19 at 02:38
0

The problem is that you are calling httpCon.getOutputStream() and writing the request data after you have called httpCon.getResponseCode().

The correct order is:

  1. Call getConnection() to get the connection object for the URL
  2. In any order:
    • Set the request method
    • Set any request properties
    • Call setDoOutput(true) since you intend to use the output stream.
  3. Call getOutputStream()
  4. Write the data.
  5. Close the stream.
  6. Get the response code.

What you are currently doing will throw an exception when you call getOutputStream. The remote server can only send you a response after it has read the request data. When you call getResponseCode() this tells the client-side stack to indicate to the server that there is no more request data.

In addition, you should not call setDoInput(true) if you don't intend to read data from the connection in some circumstances. At the very least it is redundant.

Stephen C
  • 698,415
  • 94
  • 811
  • 1,216