0

I have a REST Service deployed over a Tomcat Server. This Service has a POST method with an endpoint createUser, and the following method:

@Path("/myService")
public class MyClass {
    @POST
    @Path("/createUser")
    public Response createUser(@Context UriInfo info) {
        String user = info.getQueryParameters().getFirst("name");
        String password = info.getQueryParameters().getFirst("password");

        if (user == null || password == null) {
             return Response.serverError().entity("Name and password cannot be null").build();
        }

    //do stuff...
    return Response.ok().build()
    }

By calling this method with SoapUI everything works smoothly. I deploy my server and send a post to this (http://my_IP:8080/myApplication/myService/createUser).

Now I am trying to call this from my Android app. I am trying to use the Volley library for it. The first tests were using a GET request (with other endpoint from my tomcat) and there were no problems. However, when I try to call this endpoint and create an user, the method is triggered in Tomcat, but no parameters are retrieved (that means, user and password are null). Here is my Android code:

private void sendPostRequest(final String user, final String password) {
    final Context context = getApplicationContext();

    RequestQueue mRequestQueue = Volley.newRequestQueue(this);

    final String URL = "http://my_IP:8080/myApplication/myService/createUser";

    StringRequest strRequest = new StringRequest(Request.Method.POST, URL,
            new Response.Listener<String>() {
                @Override
                public void onResponse(String response) {
                    Toast.makeText(getApplicationContext(), response, Toast.LENGTH_SHORT).show();
                }
            },
            new Response.ErrorListener() {
                @Override
                public void onErrorResponse(VolleyError error) {
                    Toast.makeText(getApplicationContext(), error.toString(), Toast.LENGTH_SHORT).show();
                }
            }) {
        @Override
        protected Map<String, String> getParams() {
            Map<String, String> params = new HashMap<String, String>();
            params.put("name", user);
            params.put("password", password);
            return params;
        }
    };
    mRequestQueue.add(strRequest);
}

What am I doing wrong? I also tried with JSONObjects changing the Android call (leaving the REST Server intact) with the following code:

    private void sendPostRequest (final String user, final String password) {
        final Context context = getApplicationContext();
        final String URL = "http://my_IP:8080/myApplication/myService/createUser";
        RequestQueue mRequestQueue = Volley.newRequestQueue(this);

        Map<String, String> postParam= new HashMap<String, String>();
        postParam.put("name", user);
        postParam.put("password", password);

        JsonObjectRequest jsonObjReq = new JsonObjectRequest(Request.Method.POST,
            URL, new JSONObject(postParam),
            new Response.Listener<JSONObject>() {

                    @Override
                    public void onResponse(JSONObject response) {
                        Toast.makeText(context, response.toString(), Toast.LENGTH_SHORT).show();
                    }
                }, new Response.ErrorListener() {

            @Override
            public void onErrorResponse(VolleyError error) {
                Toast.makeText(context, error.toString(), Toast.LENGTH_SHORT).show();
            }
        }) {

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

        };
        mRequestQueue.add(jsonObjReq);
    }

Any help is really appreciated. Thanks!

Update: Solved thanks to the tips from @dev.bmax. I had to modify my REST Server and get the whole Requests (not only the URIInfo):

@Path("/myService")
public class MyClass {
    @Context Request request;
    @Context UriInfo info;

    @POST
    @Path("/createUser")
    public Response createUser() {
        HttpRequestContext req = (HttpRequestContext) request;

        String params = req.getEntity(String.class);
        HashMap<String, String> props = Helper.unparseEntityParams(params);

        if (props.get("username") == null || props.get("password") == null) {
             return Response.serverError().entity("Name and password cannot be null").build();
        }

        //do stuff...
        return Response.ok().build()
    }
}

1 Answers1

0

The example code of your back-end extracts the params with the getQueryParameters() method of UriInfo. And that's fine for the GET method. But, if you are using the same code trying to extract the params of a POST request, then it won't work, because they are not included in the URL. Instead of that you are supposed to use something like:

String userName = request.getParameter("name");
String password = request.getParameter("password");
dev.bmax
  • 8,998
  • 3
  • 30
  • 41