Android 通过凌空发送 JSON 原始正文的 POST

Posted

技术标签:

【中文标题】Android 通过凌空发送 JSON 原始正文的 POST【英文标题】:Android Send POST of JSON raw body with volley 【发布时间】:2017-08-28 07:52:10 【问题描述】:

我必须使用 voley 发送帖子,但是当我尝试按要求发送原始正文时,收到此错误而不是响应

******com.android.volley.ServerError******: "message":"没有收到用于注册的用户帐户数据。"

我在邮递员中尝试过同样的方法,它运行良好,我该如何在我的代码中修复它?

在邮递员中工作的原始正文 ->

    
    "camp1": 
        "value": "value"
    ,
    "camp2": 
        "value": "value2"
    

这就是我的代码中的内容 ->

    public void requestRegistrationInfo(@NonNull final String camp1, @NonNull final String camp2,final Listener listener) 
            RequestQueue requestQueue = Volley.newRequestQueue(context);
            requestQueue.add(new JsonObjectRequest(
                    Request.Method.POST, URL,
                    new Response.Listener<JSONObject>() 
                        @Override
                        public void onResponse(JSONObject response) 
                            Log.v("IT WORK");
                            listener.onSuccess();
                        
                    ,
                    new Response.ErrorListener() 
                        @Override
                        public void onErrorResponse(VolleyError error) 
                            Log.e("******" + error.toString() + "******", getErrorMessage(error));
                            listener.onFailure();
                        
                    )


                @Override
                protected Map<String,String> getParams() 

                    Map<String, String> map = new HashMap<>();
                    map.put("camp1", "value");
                    map.put("camp2", "value");

                    return map;
                

                @Override
                public Map<String, String> getHeaders() throws AuthFailureError 
                    Map<String, String> map = new HashMap<>();
                    map.put("header1", "header1");
                    map.put("header2", "header2");
                    return map;
                
            );
        

如何正确发送原始 json 并且不显示错误?

【问题讨论】:

【参考方案1】:

在正常情况下 JSONObject 请求没有命中 getParams() 方法,该方法仅适用于字符串请求和传递键值对数据负载。如果要传递带有 JSON 数据的原始正文,首先必须将数据格式化为服务器接受的格式。 在您的情况下,这是您的数据


  "camp1":
   "value":"value1"
  ,
  "camp2":
    "value2":"value2"
  

您必须像这样将数据转换为服务器接受的 JSON 格式

                JSONObject jsonObject = new JSONObject();
                jsonObject.put("value", "value1");
                JSONObject jsonObject1 = new JSONObject();
                jsonObject1.put("value2", "value2");
                JSONObject jsonObject2 = new JSONObject();
                jsonObject2.put("camp1", jsonObject);
                jsonObject2.put("camp2",jsonObject1);

 //jsonObject2 is the payload to server here you can use JsonObjectRequest 

 String url="your custom url";

 JsonObjectRequest jsonObjectRequest = new JsonObjectRequest
                        (Request.Method.POST,url, jsonObject2, new com.android.volley.Response.Listener<JSONObject>() 

                            @Override
                            public void onResponse(JSONObject response) 

                                try 
                                   //TODO: Handle your response here
                                
                                catch (Exception e)
                                    e.printStackTrace();
                                
                                System.out.print(response);

                            
                        , new com.android.volley.Response.ErrorListener() 

                            @Override
                            public void onErrorResponse(VolleyError error) 
                                // TODO: Handle error
                                error.printStackTrace();

                            


                        );

JsonObjectRequest 将在我们将传递数据的 url 参数之后在其构造函数中以 json 形式接受有效负载

【讨论】:

【参考方案2】:

这是经过测试的代码试试这个:

 private void multipartRequestWithVolly() 
        String urll = "your_url";

        progressDialog.show();
        StringRequest request = new StringRequest(Request.Method.POST, urll, new Response.Listener<String>() 
            @Override
            public void onResponse(String response) 
                progressDialog.dismiss();
                if (!TextUtils.isEmpty(response)) 
                    Log.e(TAG, "onResponse: " + response);
                    textView.setText(response);
                 else 
                    Log.e(TAG, "Response is null");
                
            
        , new Response.ErrorListener() 
            @Override
            public void onErrorResponse(VolleyError error) 
                progressDialog.dismiss();
                Log.e(TAG, "onErrorResponse: " + error.toString());
            
        ) 

            @Override
            protected Map<String, String> getParams() throws AuthFailureError 
                hashMap = new HashMap<>();
                hashMap.put("OPERATIONNAME", "bplan");
                hashMap.put("mcode", "298225816992");
                hashMap.put("deviceid", "dfb462ac78317846");
                hashMap.put("loginip", "192.168.1.101");
                hashMap.put("operatorid", "AT");
                hashMap.put("circleid", "19");
                return hashMap;
            
        ;
        AppController.getInstance().addToRequestQueue(request);
    

【讨论】:

使用这个代码,会出现和下面代码一样的错误-> ******com.android.volley.ServerError******: "message":"Not可接受的格式:json"【参考方案3】:
try 
RequestQueue requestQueue = Volley.newRequestQueue(this);
String URL = "http://...";
JSONObject jsonBody = new JSONObject();
jsonBody.put("Title", "Android Volley Demo");
jsonBody.put("Author", "BNK");
final String requestBody = jsonBody.toString();

StringRequest stringRequest = new StringRequest(Request.Method.POST, URL, new Response.Listener<String>() 
    @Override
    public void onResponse(String response) 
        Log.i("VOLLEY", response);
    
, new Response.ErrorListener() 
    @Override
    public void onErrorResponse(VolleyError error) 
        Log.e("VOLLEY", error.toString());
    
) 
    @Override
    public String getBodyContentType() 
        return "application/json; charset=utf-8";
    

    @Override
    public byte[] getBody() throws AuthFailureError 
        try 
            return requestBody == null ? null : encodeParameters(requestBody , getParamsEncoding());
         catch (UnsupportedEncodingException uee) 
            VolleyLog.wtf("Unsupported Encoding while trying to get the bytes of %s using %s", requestBody, "utf-8");
            return null;
        
    

    @Override
    protected Response<String> parseNetworkResponse(NetworkResponse response) 
        String responseString = "";
        if (response != null) 
            responseString = String.valueOf(response.statusCode);
            // can get more details such as response.headers
        
        return Response.success(responseString, HttpHeaderParser.parseCacheHeaders(response));
    
;

requestQueue.add(stringRequest);
 catch (JSONException e) 
 e.printStackTrace();

请检查编辑后的 ​​getBody()

   @Override
    public byte[] getBody() throws AuthFailureError 
        try 
            return requestBody == null ? null : encodeParameters(requestBody , getParamsEncoding());
         catch (UnsupportedEncodingException uee) 
            VolleyLog.wtf("Unsupported Encoding while trying to get the bytes of %s using %s", requestBody, "utf-8");
            return null;
        
    

【讨论】:

使用此代码,出现此错误 -> ******com.android.volley.ServerError******: "message":"Not Acceptable format: json" 我正在尝试这个,encodeParameters是自定义函数【参考方案4】:

如果您调用任何 REST-API,请注意该有效负载始终为 JSON 格式。因此,您可以像这样使用对象体作为有效载荷。

HashMap<String, String> params = new HashMap<String, String>();
params.put("username", input_loginId.getText().toString());
params.put("password", input_password.getText().toString());

你可以像这样传递这个方法

JsonObjectRequest logInAPIRequest = new JsonObjectRequest(Request.Method.POST, YOUR-URL,
                         new JSONObject(params), new Response.Listener<JSONObject>() 
 @Override
                     public void onResponse(JSONObject response)     
                         input_errorText.setText(response.toString());
                     
                 , new Response.ErrorListener() 
                     @Override
                     public void onErrorResponse(VolleyError error) 
                         input_errorText.setText("Error: " + error.getMessage());
                     
                 );

【讨论】:

以上是关于Android 通过凌空发送 JSON 原始正文的 POST的主要内容,如果未能解决你的问题,请参考以下文章

带有标头和原始 json 正文的 Volley POST 请求

凌空中的 JSONRequest 和 StringRequest 有啥区别

使用凌空json数据的片段中的Recyclerview?

nodejs从POST请求中获取原始正文[重复]

在 Android 的 OKhttp 中通过 POST 请求发送 JSON 正文

Flutter:为 Http GET 请求发送 JSON 正文