带有键值参数的 Volley Post

Volley Post with key value params

我在 Tomcat 服务器上部署了一个 REST 服务。此服务有一个带有端点 createUser 的 POST 方法,以及以下方法:

@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()
    }

通过使用 SoapUI 调用此方法,一切正常。我部署我的服务器并向此 (http://my_IP:8080/myApplication/myService/createUser) 发送一个 post。

现在我正尝试从我的 Android 应用中调用它。我正在尝试为此使用 Volley 库。第一个测试使用 GET 请求(使用来自我的 tomcat 的其他端点)并且没有问题。但是,当我尝试调用此端点并创建用户时,该方法在 Tomcat 中被触发,但未检索到任何参数(这意味着用户和密码为空)。这是我的 Android 代码:

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);
}

我做错了什么?我还尝试使用 JSONObjects 更改 Android 调用(保持 REST 服务器完好无损),代码如下:

    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);
    }

非常感谢您的帮助。谢谢!

更新:感谢@dev.bmax 的提示,已解决。我必须修改我的 REST 服务器并获取整个请求(不仅是 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()
    }
}

您的后端示例代码使用UriInfo 的getQueryParameters() 方法提取参数。这对 GET 方法来说很好。 但是,如果您使用相同的代码尝试提取 POST 请求的参数,那么它就不会工作,因为它们不包含在 URL 中。 而不是你应该使用类似的东西:

String userName = request.getParameter("name");
String password = request.getParameter("password");