简体   繁体   English

带有键值参数的Volley Post

[英]Volley Post with key value params

I have a REST Service deployed over a Tomcat Server. 我在Tomcat服务器上部署了REST服务。 This Service has a POST method with an endpoint createUser, and the following method: 该服务具有一个带有端点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()
    }

By calling this method with SoapUI everything works smoothly. 通过使用SoapUI调用此方法,一切都可以顺利进行。 I deploy my server and send a post to this ( http://my_IP:8080/myApplication/myService/createUser ). 我部署了服务器,并为此发送了一个帖子( http:// my_IP:8080 / myApplication / myService / createUser )。

Now I am trying to call this from my Android app. 现在,我试图通过我的Android应用程序调用它。 I am trying to use the Volley library for it. 我正在尝试使用Volley库。 The first tests were using a GET request (with other endpoint from my tomcat) and there were no problems. 最初的测试使用的是GET请求(与我的tomcat的其他终结点一起使用),并且没有问题。 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). 但是,当我尝试调用此端点并创建用户时,该方法在Tomcat中触发,但是未检索到任何参数(这意味着用户名和密码为null)。 Here is my Android code: 这是我的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);
}

What am I doing wrong? 我究竟做错了什么? I also tried with JSONObjects changing the Android call (leaving the REST Server intact) with the following code: 我还尝试使用JSONObjects通过以下代码更改Android调用(使REST Server保持完整):

    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. 更新:由于@ dev.bmax的提示而得以解决。 I had to modify my REST Server and get the whole Requests (not only the URIInfo): 我必须修改我的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()
    }
}

The example code of your back-end extracts the params with the getQueryParameters() method of UriInfo. 后端的示例代码使用UriInfo的getQueryParameters()方法提取参数。 And that's fine for the GET method. 这对于GET方法很好。 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. 但是,如果您使用相同的代码尝试提取POST请求的参数,则它将不起作用,因为它们未包含在URL中。 Instead of that you are supposed to use something like: 取而代之的是,您应该使用类似:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM