1

I need to make a HTTPS POST with urlencoded parameters like this :

https://logintest.moveon.pro/?rest_route=/simple-jwt-login/v1/auth&email=Email&password=Password

And get in return a JSON like this :

{"success":false,"data":{"message":"Wrong user credentials.","errorCode":48}}

I am using Volley library on Android Studio.

What I have done :

  1. I have tried the complete process on PostMan. Here are the conclusion :
  • POST works, GET does not.
  • Parameters are needed
  • There is NOTHING in header (on request, except the "auto-generated" ones)Postman of Header
  • There is NOTHING in body (on request)Postman of Body
  • Checked that even with incorrect credentials, a JSON answer is sent. Just the content of the answer will change if the parameters are correct.
  • I tried with both, HTTP & HTTPS, both work the same here.HTTPS working just as fine
  1. Installed Volley in the APP build.gradle build.gradle Volley dependenciy

  2. Authorized the Internet & Network State in my Manifest.xml manifest.xml INTERNET & NETWROK STATE

  3. Did a very basic login Screen as main activity

  4. When clicking, direct me on my TESTs I've done.

Here are my 3 tests performed :

a. With StringRequest (Yes, I want a POST, but don't need anything in the request body, I thought it could be an idea to go simple). I did a great deal of testing here, same as with the next subject, the JsonObjectRequest.

b. With a JsonObjectRequest (Did soooooo many tries with this one ! I think I really tried all I could find on StackOverflow... and others...). Among other things trying to override BodyContent, Headers, Body, etc...

c. With a new "helping" class which extends the Request. as I read here.

What is my problem :

I can't find a way to pass my parameters to the POST url... When debugging I get the "mUrl" of Volley as the basic URL (https://logintest.moveon.pro/) and not the one with added parameters (https://logintest.moveon.pro/?rest_route=/simple-jwt-login/v1/auth&email=Email&password=Password).

Here is my code... I used a stupid "if" in order to test the different approaches, don't blame me too hard on this ;-)... And there is a LOT of redundancy in the parameters wanting to be sent.

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ProgressBar;

import com.android.volley.AuthFailureError;
import com.android.volley.Request;
import com.android.volley.RequestQueue;
import com.android.volley.Response;
import com.android.volley.Response.Listener;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.JsonObjectRequest;
import com.android.volley.toolbox.StringRequest;
import com.android.volley.toolbox.Volley;

import org.json.JSONException;
import org.json.JSONObject;

import java.util.HashMap;
import java.util.Map;

public class MainActivity extends AppCompatActivity {

    /**
     * Logcat tag
     */
    private static final String TAG = MainActivity.class.getSimpleName();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        final EditText usernameEditText = findViewById(R.id.username);
        final EditText passwordEditText = findViewById(R.id.password);
        final Button loginButton = findViewById(R.id.login);
        final ProgressBar loadingProgressBar = findViewById(R.id.loading);

        loginButton.setOnClickListener(new View.OnClickListener() {

            private static final String URL_LOGIN = "http://logintest.moveon.pro";
            //private static final String URL_LOGIN = "http://logintest.moveon.pro/?rest_route=/simple-jwt-login/v1/auth&email=Email&password=Password";
            private static final String route = "/simple-jwt-login/v1/auth";

            @Override
            public void onClick(View v) {

                // Build the request payload -- tried not working better
                final JSONObject jsonObject = new JSONObject();
                try {
                    jsonObject.put("rest_route", "/simple-jwt-login/v1/auth");
                    jsonObject.put("email", "john@domain.com");
                    jsonObject.put("password", "ghjghjk");
                 } catch (JSONException e) {
                    e.printStackTrace();
                }

                // Instantiate the RequestQueue.
                RequestQueue queue = Volley.newRequestQueue(getApplicationContext());

                //Tried different ways of sending the request :
                //String url = "http://logintest.moveon.pro/?rest_route=/simple-jwt-login/v1/auth&email=Email&password=Password";
                //String url = "http://logintest.moveon.pro/wp-json/?rest_route=/simple-jwt-login/v1/auth&email=Email&password=Password";
                String url = "http://logintest.moveon.pro/";

                int test = 3;
                if (test == 0) {
                    // Request a string response from the provided URL.
                    StringRequest sr = new StringRequest(Request.Method.POST, url,
                            new Response.Listener<String>() {
                                @Override
                                public void onResponse(String response) {
                                    Log.e("HttpClient", "success! response: " + response.toString());
                                    // Display the first 500 characters of the response string.
                                    usernameEditText.setText("Response is: " + response.toString().substring(0, 500));
                                }
                            },
                            new Response.ErrorListener() {
                                @Override
                                public void onErrorResponse(VolleyError error) {
                                    usernameEditText.setText("That didn't work!");
                                    Log.e("HttpClient", "error: " + error.toString());
                                }
                            }) {
                        @Override
                        protected Map<String, String> getParams() {
                            Map<String, String> params = new HashMap<String, String>();
                            params.put("rest_route", "/simple-jwt-login/v1/auth");
                            params.put("email", "asdasd");
                            params.put("password", "ghjghjk");
                            return params;
                        }

                        //Tried with adding params in Body... but not working better
                        @Override
                        public byte[] getBody() throws AuthFailureError {
                            HashMap<String, String> params2 = new HashMap<String, String>();
                            params2.put("rest_route", "/simple-jwt-login/v1/auth");
                            params2.put("email", "john@domain.com");
                            params2.put("password", "ghjghjk");
                            return new JSONObject(params2).toString().getBytes();
                        }

                        //Tried defining the Body content in different ways... but not working better
                        @Override
                        public String getBodyContentType() {
                            return "application/json; charset=UTF-8";
                        }
                        @Override
                        public Map<String, String> getHeaders() throws AuthFailureError {
                            HashMap<String, String> headers = new HashMap<String, String>();
                            //headers.put("Content-Type", "application/x-www-form-urlencoded;  charset=UTF-8");
                            //headers.put("Content-Type","application/x-www-form-urlencoded");
                            headers.put("Content-Type", "application/json;  charset=UTF-8");
                            return headers;

                        }

                    };
                    // Add the request to the RequestQueue.
                    queue.add(sr);

                } else if (test == 1) {


                    Map<String, String> params = new HashMap<String, String>();
                    params.put("rest_route", "/simple-jwt-login/v1/auth");
                    params.put("email", "asdasd");
                    params.put("password", "ghjghjk");
                    JSONObject parameters = new JSONObject(params);


                    // Request a string response from the provided URL.
                    JsonObjectRequest stringRequest1 = new JsonObjectRequest(Request.Method.POST, url, parameters,
                            new Listener<JSONObject>() {
                                @Override
                                public void onResponse(JSONObject response) {
                                    // Display the first 500 characters of the response string.
                                    usernameEditText.setText("Response is: " + response.toString().substring(0, 500));

                                }
                            }, new Response.ErrorListener() {
                        @Override
                        public void onErrorResponse(VolleyError error) {
                            usernameEditText.setText("That didn't work!");
                        }
                    }) {
                        @Override
                        protected Map<String, String> getParams() {
                            Map<String, String> params = new HashMap<String, String>();
                            params.put("rest_route", "/simple-jwt-login/v1/auth");
                            params.put("email", "asdasd");
                            params.put("password", "ghjghjk");
                            return params;
                        }

                        @Override
                        public Map<String, String> getHeaders() throws AuthFailureError {
                            HashMap<String, String> headers = new HashMap<String, String>();
                            headers.put("Content-Type", "application/x-www-form-urlencoded;  charset=UTF-8");
                            //headers.put("Content-Type", "application/json");
                            return headers;

                        }
                    };
                    // Add the request to the RequestQueue.
                    queue.add(stringRequest1);

                } else if (test == 3) {

                    Map<String, String> params = new HashMap();
                    params.put("rest_route", "/simple-jwt-login/v1/auth");
                    params.put("email", "john@domain.com");
                    params.put("password", "ghjghjk");

                    CustomVolleyRequest strReq = new CustomVolleyRequest(Request.Method.POST, url, params, new Response.Listener<JSONObject>() {
                        @Override
                        public void onResponse(JSONObject response) {
                            Log.e("HttpClient", "success! response: " + response.toString());
                            // Display the first 500 characters of the response string.
                            usernameEditText.setText("Response is: " + response.toString().substring(0, 500));
                        }
                    },
                            new Response.ErrorListener() {
                                @Override
                                public void onErrorResponse(VolleyError error) {
                                    usernameEditText.setText("That didn't work!");
                                    Log.e("HttpClient", "error: " + error.toString());
                                }
                            }) ;
                }
            }
        });

    }

}

Also here is the "helper" class I took form the post already mentioned :

package com.example.logintest;

import java.io.UnsupportedEncodingException;
import java.util.Map;

import org.json.JSONException;
import org.json.JSONObject;

import com.android.volley.NetworkResponse;
import com.android.volley.ParseError;
import com.android.volley.Request;
import com.android.volley.Response;
import com.android.volley.Response.ErrorListener;
import com.android.volley.Response.Listener;
import com.android.volley.toolbox.HttpHeaderParser;

public class CustomVolleyRequest extends Request<JSONObject> {

    private Listener<JSONObject> listener;
    private Map<String, String> params;

    public CustomVolleyRequest(String url, Map<String, String> params, Listener<JSONObject> responseListener, ErrorListener errorListener) {
        super(Method.GET, url, errorListener);
        this.listener = responseListener;
        this.params = params;
    }

    public CustomVolleyRequest(int method, String url, Map<String, String> params, Listener<JSONObject> responseListener, ErrorListener errorListener) {
        super(method, url, errorListener);
        this.listener = responseListener;
        this.params = params;
    }

    protected Map<String, String> getParams()
            throws com.android.volley.AuthFailureError {
        return params;
    }


    @Override
    protected Response<JSONObject> parseNetworkResponse(NetworkResponse response) {
        try {
            String jsonString = new String(response.data,
                    HttpHeaderParser.parseCharset(response.headers));
            return Response.success(new JSONObject(jsonString),
                    HttpHeaderParser.parseCacheHeaders(response));
        } catch (UnsupportedEncodingException e) {
            return Response.error(new ParseError(e));
        } catch (JSONException je) {
            return Response.error(new ParseError(je));
        }
    }

    @Override
    protected void deliverResponse(JSONObject response) {
        // TODO Auto-generated method stub
        listener.onResponse(response);
    }
}
netskink
  • 4,033
  • 2
  • 34
  • 46
Daric
  • 83
  • 9
  • Daric, I'm wondering if showing the guide you are using for reference would be helpful. Do you have a URL for the guide or reference api you are using? If so, it would be great if you added it. – netskink Jul 30 '20 at 13:28

2 Answers2

0

you can send a x-www-form-urlencoded request in this way:

  • request header: Content-Type: application/x-www-form-urlencoded
  • request body: rest_route=/simple-jwt-login/v1/auth&password=<YOUR_PASSWORD>&email=<YOUR_EMAIL>. (replace the placeholder by the correct credentials).

you can check this for reference: https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/POST

let me know your update =)

jaop
  • 268
  • 2
  • 8
  • Hello jaop... Thank you for your answer ! As you can see in my code, this has already been tried in many different ways. And in Volley this is suppose to be the default of what I could understand. I have not yet come to a correct way of doing it, but had success without overriding getParams, thus just setting the URL with directly the encoded parameters in it. Have a nice day, and thanks again for your suggestion. – Daric Aug 11 '20 at 09:27
0

so here is my working code.

The problem was lying into the API which was returning 400 code even though the syntax was correct.

When I found this out thanks to POSTMAN, I looked for a way to still get the body answer from my POST, using Volley Error return.

I found this post here which I added to my solution '0', simplified it at maximum, and here is the result : package com.example.logintest;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ProgressBar;

import com.android.volley.NetworkResponse;
import com.android.volley.Request;
import com.android.volley.RequestQueue;
import com.android.volley.Response;
import com.android.volley.ServerError;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.HttpHeaderParser;
import com.android.volley.toolbox.StringRequest;
import com.android.volley.toolbox.Volley;

import org.json.JSONException;
import org.json.JSONObject;

import java.io.UnsupportedEncodingException;
import java.util.HashMap;
import java.util.Map;

public class MainActivity extends AppCompatActivity {

    /**
     * Logcat tag
     */
    private static final String TAG = MainActivity.class.getSimpleName();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        final EditText usernameEditText = findViewById(R.id.username);
        final EditText passwordEditText = findViewById(R.id.password);
        final Button loginButton = findViewById(R.id.login);
        final ProgressBar loadingProgressBar = findViewById(R.id.loading);

        loginButton.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {

                // Instantiate the RequestQueue.
                RequestQueue queue = Volley.newRequestQueue(getApplicationContext());

                String url = "https://logintest.moveon.pro/";

                    // Request a string response from the provided URL.
                    StringRequest sr = new StringRequest(Request.Method.POST, url,
                            new Response.Listener<String>() {
                                @Override
                                public void onResponse(String response) {
                                    Log.e("HttpClient", "success! response: " + response.toString());
                                    // Display the first 500 characters of the response string.
                                    usernameEditText.setText("Response is: " + response.toString().substring(0, 500));
                                }
                            },
                            new Response.ErrorListener() {
                                @Override
                                public void onErrorResponse(VolleyError error) {
                                    usernameEditText.setText("That didn't work!");
                                    // As of f605da3 the following should work
                                    NetworkResponse response = error.networkResponse;
                                    if (error instanceof ServerError && response != null) {
                                        try {
                                            String res = new String(response.data,
                                                    HttpHeaderParser.parseCharset(response.headers, "utf-8"));
                                            // Now you can use any deserializer to make sense of data
                                            JSONObject obj = new JSONObject(res);
                                            usernameEditText.setText(usernameEditText.getText() + res);
                                        } catch (UnsupportedEncodingException e1) {
                                            // Couldn't properly decode data to string
                                            e1.printStackTrace();
                                        } catch (JSONException e2) {
                                            // returned data is not JSONObject?
                                            e2.printStackTrace();
                                        }
                                    }
                                    Log.e("HttpClient", "error: " + error.toString());
                                }
                            }) {

                        @Override
                        protected Map<String, String> getParams() {
                            Map<String, String> params = new HashMap<String, String>();
                            params.put("rest_route", "/simple-jwt-login/v1/auth");
                            params.put("email", "dummy@gmail.com");
                            params.put("password", "935jIDan^4S@$rAFLw4w@!$Z");
                            return params;
                        }
                    };
                    // Add the request to the RequestQueue.
                    queue.add(sr);
                }
        });
    }
}

Hope this will help someone...

Best regards, and happy coding !!!

Daric
  • 83
  • 9