【问题标题】:Volley - Sending a POST request using JSONArrayRequestVolley - 使用 JSONArrayRequest 发送 POST 请求
【发布时间】:2013-08-05 14:35:18
【问题描述】:

我正在使用 Volley 与 API 进行交互。我需要向返回 JSON 数组的服务发送一个发布请求(带参数)。

JsonObjectRequest 有一个构造函数,它接受一个方法和一组参数

JsonObjectRequest(int method, java.lang.String url, JSONObject jsonRequest, Response.Listener<JSONObject> listener, Response.ErrorListener errorListener) 

然而 JSONArrayRequest(我需要的那个)只有一个形式的构造函数

JsonArrayRequest(java.lang.String url, Response.Listener<JSONArray> listener, Response.ErrorListener errorListener) 

我怎样才能让它发送一个带有数据的 POST 请求?

【问题讨论】:

    标签: java android android-volley


    【解决方案1】:

    他们可能稍后会添加它,但同时您可以自己添加想要的构造函数:

    public JsonArrayRequest(int method, String url, JSONObject jsonRequest,
            Listener<JSONArray> listener, ErrorListener errorListener) {
        super(method, url, (jsonRequest == null) ? null : jsonRequest.toString(), 
            listener, errorListener);
    }
    

    这没有经过测试,尽管我认为没有理由这不应该工作,因为实现细节在超类中:JsonRequest

    试试看它是否有效。

    编辑:

    我打电话了!在我回答这个问题后,他们花了将近两年的时间,但 Volley 团队于 2015 年 3 月 19 日将这个构造函数添加到了回购中。你猜怎么了?这是确切的语法。

    【讨论】:

    • 实际上是我昨晚在代码中发现的。不过还是谢谢。像魅力一样工作。
    • 你好,这段代码实际上是在哪里写的?以及 super(...) 如何工作,因为默认构造函数是这样的: JsonArrayRequest(java.lang.String url,Response.Listener listener,ErrorListener errorListener)
    • 超级构造函数属于“父”类JsonRequest&lt;JSONArray&gt;JsonArrayRequest 继承自该类,这就是它起作用的原因。我认为您将它与使用this 调用构造函数混淆了。您需要在 JsonArrayRequest.java 中添加该代码(在工具箱包内)。
    • 这是一个接受的答案,有 8 票赞成。这可能意味着您的问题不在于此构造函数,而在于您的服务器响应。调试你的代码看看。
    • 注意:官方截击没有这个构造函数。这个可以在已弃用和非官方的截击中找到:github.com/mcxiaoke/android-volley
    【解决方案2】:

    我很懒,没有自己构建 Volley 库(只是使用了 .jar),因此没有源代码...所以在匿名新 JSONArrayRequest 中添加了这些函数:

                // NO CONSTRUCTOR AVAILABLE FOR POST AND PARAMS FOR JSONARRAY!
                // overridden the necessary functions for this
                @Override
                public byte[] getBody() {
                    try {
                        return paramsArray.toString().getBytes("utf-8");
                    } catch (UnsupportedEncodingException e) {
                        e.printStackTrace();
                    }
                    return null;
                }
    
                @Override
                public int getMethod() {
                    return Method.POST;
                }
    

    【讨论】:

    • 对于刚使用.jar 的初学者来说,您的答案更容易。 @Itai 回答让像我这样的初学者感到困惑。
    • 是的,您可以直接继承 JSONArrayRequest,而不是重新编写它。
    • 什么是参数数组?
    • @k2ibegin 不再确定 XD 但我想这只是服务器所需的数据列表。但我想它可以是你想要的任何东西
    【解决方案3】:

    这段代码可以实现你想要的

        Volley.newRequestQueue(context).add(
                new JsonRequest<JSONArray>(Request.Method.POST, "url/", null,
                        new Response.Listener<JSONArray>() {
                            @Override
                            public void onResponse(JSONArray response) {
    
                            }
                        }, new Response.ErrorListener() {
                            @Override
                            public void onErrorResponse(VolleyError error) {
    
                            }
                        }) {
                    @Override
                    protected Map<String, String> getParams() {
                        Map<String, String> params = new HashMap<String, String>();
                        params.put("param1", "one");
                        params.put("param2", "two");
                        return params;
                    }
    
                    @Override
                    protected Response<JSONArray> parseNetworkResponse(
                            NetworkResponse response) {
                        try {
                            String jsonString = new String(response.data,
                                    HttpHeaderParser
                                            .parseCharset(response.headers));
                            return Response.success(new JSONArray(jsonString),
                                    HttpHeaderParser
                                            .parseCacheHeaders(response));
                        } catch (UnsupportedEncodingException e) {
                            return Response.error(new ParseError(e));
                        } catch (JSONException je) {
                            return Response.error(new ParseError(je));
                        }
                    }
                });
    

    【讨论】:

    • 服务器没有收到使用getParam() 发送的奇怪数据,否则它工作正常。为什么?
    【解决方案4】:

    使用 JSONarray 请求发送参数请求并根据参数返回自定义响应的最佳且简单的方法是在 URL 本身中添加 get 参数值。

    String URL ="http://mentormentee.gear.host/android_api/Message.aspx?key="+keyvalue;
    

    其中keyvalue 参数值并在JsonArrayRequest URL 中添加这个URL 简单。

        JsonArrayRequest searchMsg= new JsonArrayRequest(URL, new Response.Listener<JSONArray>() {
    
            @Override
            public void onResponse(JSONArray response) {
                Log.d(TAG, response.toString());
    
    
                // Parsing json
                for (int i = 0; i < response.length(); i++) {
                    try {
    
                        JSONObject obj = response.getJSONObject(i);
                        Message msg = new Message();
                        msg.setMessageThread(obj.getString("msgThread"));
                        msg.setUserName(obj.getString("Username"));
                        msg.setDate(obj.getString("msgDate"));
    
                        // adding movie to movies array
                        MessageList.add(msg);
    
                    } catch (JSONException e) {
                        e.printStackTrace();
                    }
    
                }
    
                // notifying list adapter about data changes
                // so that it renders the list view with updated data
                adapter.notifyDataSetChanged();
            }
        }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                VolleyLog.d(TAG, "Error: " + error.getMessage());
               // hidePDialog();
    
            }
        });
        // Adding request to request queue
        AppController.getInstance().addToRequestQueue(searchMsg);
    }
    

    【讨论】:

    • 服务器端php是否需要添加额外的东西
    【解决方案5】:

    可能您的问题已解决,但我希望这对其他用户有所帮助。我所做的是,我通过扩展它创建了一个新的自定义类。这是代码。

    public class CustomJsonRequest extends Request {
    
    Map<String, String> params;       
    private Response.Listener listener; 
    
    public CustomJsonRequest(int requestMethod, String url, Map<String, String> params,
                          Response.Listener responseListener, Response.ErrorListener errorListener) {
    
        super(requestMethod, url, errorListener);
        this.params = params;
        this.listener = responseListener;
    }
    
    @Override
    protected void deliverResponse(Object response) {
        listener.onResponse(response); 
    
    }
    
    @Override
    public Map<String, String> getParams() throws AuthFailureError {
             return params;
    }
    
    @Override
    protected Response 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));
        }
    }
    
    }
    

    您可以使用这个类来代替 JsonArrayRequest 或 JsonObjectRequest。这也解决了php无法在$_POST中捕获post参数的问题

    【讨论】:

    • 实际上它可以工作,但我需要别的东西。在我的情况下,我的参数是一个 Json 对象,有时是一个 Json 数组。我如何根据需要使用您的代码??
    • @FlavienBert 您可以对 json 对象进行类型检查,以确定是否需要返回数组或对象。 Object json = new JSONTokener(jsonString).nextValue(); if (json instanceof JSONObject) { } else if (json instanceof JSONArray) { }
    • 哦,感谢上帝!我一直在努力解决这个问题,这很有效,只需要根据我的需要将return Response.success(new JSONArray(jsonString), 更改为 JSONArray。然而,我很好奇为什么我的日子不好过,如果你有时间并且不介意看看我在这里发了一个帖子 [链接] (stackoverflow.com/questions/29837859/…)
    【解决方案6】:
    You can use this 
    
    package HelperClass;
    /*
     * Copyright (C) 2011 The Android Open Source Project
     *
     * Licensed under the Apache License, Version 2.0 (the "License");
     * you may not use this file except in compliance with the License.
     * You may obtain a copy of the License at
     *
     *      http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     * See the License for the specific language governing permissions and
     * limitations under the License.
     */
    
    
    
    import com.android.volley.NetworkResponse;
    import com.android.volley.ParseError;
    import com.android.volley.Response;
    import com.android.volley.Response.ErrorListener;
    import com.android.volley.Response.Listener;
    import com.android.volley.toolbox.HttpHeaderParser;
    import com.android.volley.toolbox.JsonRequest;
    
    import org.json.JSONArray;
    import org.json.JSONException;
    import org.json.JSONObject;
    
    import java.io.UnsupportedEncodingException;
    import java.util.Map;
    
    /**
     * A request for retrieving a {@link JSONArray} response body at a given URL.enter code here
     */
    public class MyjsonPostRequest extends JsonRequest<JSONArray> {
    
        protected static final String PROTOCOL_CHARSET = "utf-8";
    
    
    
        /**
         * Creates a new request.
         * @param method the HTTP method to use
         * @param url URL to fetch the JSON from
         * @param requestBody A {@link String} to post with the request. Null is allowed and
         *   indicates no parameters will be posted along with request.
         * @param listener Listener to receive the JSON response
         * @param errorListener Error listener, or null to ignore errors.
         */
        public MyjsonPostRequest(int method, String url, String requestBody,
                                Listener<JSONArray> listener, ErrorListener errorListener) {
            super(method, url, requestBody, listener,
                    errorListener);
        }
    
        /**
         * Creates a new request.
         * @param url URL to fetch the JSON from
         * @param listener Listener to receive the JSON response
         * @param errorListener Error listener, or null to ignore errors.
         */
        public MyjsonPostRequest(String url, Listener<JSONArray> listener, ErrorListener errorListener) {
            super(Method.GET, url, null, listener, errorListener);
        }
    
        /**
         * Creates a new request.
         * @param method the HTTP method to use
         * @param url URL to fetch the JSON from
         * @param listener Listener to receive the JSON response
         * @param errorListener Error listener, or null to ignore errors.
         */
        public MyjsonPostRequest(int method, String url, Listener<JSONArray> listener, ErrorListener errorListener) {
            super(method, url, null, listener, errorListener);
        }
    
        /**
         * Creates a new request.
         * @param method the HTTP method to use
         * @param url URL to fetch the JSON from
         * @param jsonRequest A {@link JSONArray} to post with the request. Null is allowed and
         *   indicates no parameters will be posted along with request.
         * @param listener Listener to receive the JSON response
         * @param errorListener Error listener, or null to ignore errors.
         */
        public MyjsonPostRequest(int method, String url, JSONArray jsonRequest,
                                Listener<JSONArray> listener, ErrorListener errorListener) {
            super(method, url, (jsonRequest == null) ? null : jsonRequest.toString(), listener,
                    errorListener);
        }
    
        /**
         * Creates a new request.
         * @param method the HTTP method to use
         * @param url URL to fetch the JSON from
         * @param jsonRequest A {@link JSONObject} to post with the request. Null is allowed and
         *   indicates no parameters will be posted along with request.
         * @param listener Listener to receive the JSON response
         * @param errorListener Error listener, or null to ignore errors.
         */
        public MyjsonPostRequest(int method, String url, JSONObject jsonRequest,
                                Listener<JSONArray> listener, ErrorListener errorListener) {
            super(method, url, (jsonRequest == null) ? null : jsonRequest.toString(), listener,
                    errorListener);
        }
    
        /**
         * Constructor which defaults to <code>GET</code> if <code>jsonRequest</code> is
         * <code>null</code>, <code>POST</code> otherwise.
         *
         * @see #MyjsonPostRequest(int, String, JSONArray, Listener, ErrorListener)
         */
        public MyjsonPostRequest(String url, JSONArray jsonRequest, Listener<JSONArray> listener,
                                ErrorListener errorListener) {
            this(jsonRequest == null ? Method.GET : Method.POST, url, jsonRequest,
                    listener, errorListener);
        }
    
        /**
         * Constructor which defaults to <code>GET</code> if <code>jsonRequest</code> is
         * <code>null</code>, <code>POST</code> otherwise.
         *
         * @see #MyjsonPostRequest(int, String, JSONObject, Listener, ErrorListener)
         */
        public MyjsonPostRequest(String url, JSONObject jsonRequest, Listener<JSONArray> listener,
                                ErrorListener errorListener) {
            this(jsonRequest == null ? Method.GET : Method.POST, url, jsonRequest,
                    listener, errorListener);
        }
    
        @Override
        protected Response<JSONArray> parseNetworkResponse(NetworkResponse response) {
            try {
                String jsonString = new String(response.data,
                        HttpHeaderParser.parseCharset(response.headers));
                return Response.success(new JSONArray(jsonString),
                        HttpHeaderParser.parseCacheHeaders(response));
            } catch (UnsupportedEncodingException e) {
                return Response.error(new ParseError(e));
            } catch (JSONException je) {
                return Response.error(new ParseError(je));
            }
        }
    
    }
    

    【讨论】:

      【解决方案7】:

      只需添加一些有关 JsonArrayRequest 的详细信息。 在\src\com\android\volley\toolbox中,可以发现JsonArrayRequest的默认构造不支持Method参数,在构造中volley add method(GET), 所以如果你想使用其他方法,试着自己写吧

      public class JsonArrayRequest extends JsonRequest<JSONArray> {
      
          /**
           * Creates a new request.
           * @param url URL to fetch the JSON from
           * @param listener Listener to receive the JSON response
           * @param errorListener Error listener, or null to ignore errors.
           */
          public JsonArrayRequest(String url, Listener<JSONArray> listener, ErrorListener errorListener) {
              super(Method.GET, url, null, listener, errorListener);
          }
      

      【讨论】:

        【解决方案8】:
        List<Map<String,String>> listMap =  new ArrayList<Map<String, String>>();
                Map<String,String> map  = new HashMap<String,String>();
                try {
        
                    map.put("email", customer.getEmail());
                    map.put("password",customer.getPassword());
        
                } catch (Exception e) {
                    e.printStackTrace();
                }
                listMap.add(map);
        
                String url = PersonalConstants.BASE_URL+"/url";
                JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(
                        Request.Method.POST, url, String.valueOf(new JSONArray(listMap)),
                        new Response.Listener<JSONObject>() {
                            @Override
                            public void onResponse(JSONObject jsonObject) {
                                Log.d(App.TAG, jsonObject.toString());
                            }
                        }, new Response.ErrorListener (){
        
                    @Override
                    public void onErrorResponse(VolleyError volleyError) {
                        Log.d(App.TAG,volleyError.toString());
                    }
                }
                );
                App.getInstance().getmRequestQueue().add(jsonObjectRequest);
        

        【讨论】:

          【解决方案9】:
          JsonArrayRequest req = new JsonArrayRequest(urlJsonArry,
                          new Response.Listener<JSONArray>() {
                              @Override
                              public void onResponse(JSONArray response) {
                                  Log.d(TAG, response.toString());
          
                                  try {
                                      // Parsing json array response
                                      // loop through each json object
                                      jsonResponse = "";
                                      for (int i = 0; i < response.length(); i++) {
          
                                          JSONObject person = (JSONObject) response
                                                  .get(i);
          
                                          String name = person.getString("name");
                                          String email = person.getString("email");
                                          JSONObject phone = person
                                                  .getJSONObject("phone");
                                          String home = phone.getString("home");
                                          String mobile = phone.getString("mobile");
          
                                          jsonResponse += "Name: " + name + "\n\n";
                                          jsonResponse += "Email: " + email + "\n\n";
                                          jsonResponse += "Home: " + home + "\n\n";
                                          jsonResponse += "Mobile: " + mobile + "\n\n\n";
          
                                      }
          
                                      txtResponse.setText(jsonResponse);
          
                                  } catch (JSONException e) {
                                      e.printStackTrace();
                                      Toast.makeText(getApplicationContext(),
                                              "Error: " + e.getMessage(),
                                              Toast.LENGTH_LONG).show();
                                  }
          
                                  hidepDialog();
                              }
                          }, new Response.ErrorListener() {
                              @Override
                              public void onErrorResponse(VolleyError error) {
                                  VolleyLog.d(TAG, "Error: " + error.getMessage());
                                  Toast.makeText(getApplicationContext(),
                                          error.getMessage(), Toast.LENGTH_SHORT).show();
                                  hidepDialog();
                              }
                          });
          
                  // Adding request to request queue
                  AppController.getInstance().addToRequestQueue(req);
          

          }

          【讨论】:

            猜你喜欢
            • 2015-07-03
            • 1970-01-01
            • 1970-01-01
            • 2015-08-10
            • 1970-01-01
            • 2017-03-10
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多