0

I can't figure out what is up with this code. First of all, as it is here, it works. But I'm afraid I have missed an important concept and I don't want it to come back and bite me later. My code below will write a blank line to a text log that I have created for testing purposes if I don't add the line "connection.getResponseMessage.' It will also work with 'getResponseCode.' Why?

Why does it write an empty buffer to the OutputStream without these codes?

public class AdminActivity extends AppCompatActivity {

    Context mContext;
    private static final String TAG = "AdminActivity";

    EditText mSystemID, mSystemPassword;
    RecyclerView mRecyclerView;
    Button mUpdateButton, mDownloadButton;
    FileItemAdapter mAdapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_admin);

        mContext = this;

        mSystemID = findViewById(R.id.et_system_id);
        mSystemPassword = findViewById(R.id.et_system_password);
        mRecyclerView = findViewById(R.id.rv_file_names);
        mUpdateButton = findViewById(R.id.bt_update_files_list);
        mDownloadButton = findViewById(R.id.bt_download_file);

        LinearLayoutManager layoutManager = new LinearLayoutManager(this);
        mRecyclerView.setLayoutManager(layoutManager);

        DividerItemDecoration divider = new DividerItemDecoration(mContext, layoutManager.getOrientation());
        divider.setDrawable(ContextCompat.getDrawable(mContext, R.drawable.divider_dark));


        // TESTING TESTING TESTING TESTING TESTING //
        mUpdateButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                new SendInfoToServer().execute("A new Test");
            }
        });
    }

    private static class SendInfoToServer extends AsyncTask<String, String, String> {

        HttpURLConnection connection = null;  //***** Should eventually change to https instead of http
        OutputStream out = null;

        @Override
        protected String doInBackground(String... params) {


            String parameters = params[0];

            try {
                URL url = new URL("http://www.example.com/login/webhook.php");

                connection = (HttpURLConnection) url.openConnection();
                connection.setRequestMethod("POST");
                connection.setDoOutput(true);
                connection.connect();


                out = new DataOutputStream(connection.getOutputStream());
                BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(out, "UTF-8"));
                writer.write(parameters);
                writer.flush();
                writer.close();

                Log.d(TAG, "response message: " + connection.getResponseMessage());

            } catch (IOException e) {
                Log.d(TAG, "an error occured");
                e.printStackTrace();
            } finally {
                if (connection != null) {
                    connection.disconnect();
                }
            }
            return null;
        }

    }

}

I've tried to ask this question multiple different ways and nobody has given me any useful input. This, I guess, is my last attempt to simplify the question. Above is the entire Activity. It has already been suggested to remove 'writer.close()' but that didn't work.

Thanks in advance

  • I told you before that you should not just send a text string. But parameters with their value. You ars still messing around with just text. No wonder that it does nit work. – greenapps Nov 17 '17 at 22:13
  • `My code below will write a blank line to a text log`. My god.. Where is that text log? On your server? Why are you not writing a better post?! Should all be repeated again? – greenapps Nov 17 '17 at 22:15
  • But it does work! As long as I add the code I mentioned. You should still be able to send regular Strings to a server, even if there is a better way. I'm simply looking for an explanation as to why adding the code after connection.close works and why omitting it causes the write to fail. –  Nov 17 '17 at 22:16
  • maybe you just don't know –  Nov 17 '17 at 22:17

1 Answers1

0

HttpURLConnection has a terrible API and is very confusing to use. I would strongly recommend using OkHttp in its place. With OkHttp, you would make the request with the following code:

String parameters = params[0];
Response response;
try {
    MediaType contentType = MediaType.parse("text/plain; charset=utf-8");
    RequestBody body = RequestBody.create(contentType, parameters);
    Request request = new Request.Builder()
        .url("http://www.example.com/login/webhook.php")
        .post(body)
        .build();

    response = client.newCall(request).execute();
    if (response.isSuccessful()) {
        return response.body().string();
    }
} catch (IOException e) {
    Log.d(TAG, "an error occured");
    e.printStackTrace();
} finally {
    if(response != null) {
        response.close();
    }
}
return null;

If you want to stick with HttpURLConnection, this answer explains the connection process pretty well.

James McCracken
  • 15,488
  • 5
  • 54
  • 62