【问题标题】:Volley POST request coming back null with headers and bodyVolley POST 请求返回空头和正文
【发布时间】:2018-11-01 17:19:24
【问题描述】:

我遇到了 onResponse(JSONObject response) 不断返回 null 的问题。

我已经记录了 JSONObject.toString 作为请求 (POST) 中的主体传递,粘贴到 Postman 中,它可以工作;我从服务器(JSON 对象)得到有效响应。我也尝试过 StringRequest 但我没有任何运气。

这是我的 PHP:

public function decryptTest2($param) {
        $key = sodium_hex2bin($param['key']);
        $nonce = sodium_hex2bin($param['nonce']);
        $chiper = sodium_hex2bin($param['chiper']);

        header('Content-Type: application/json; charset=utf-8');

        $plaintext = sodium_crypto_secretbox_open($chiper, $nonce, $key);
        if ($plaintext === false) {
            throw new Exception("Bad ciphertext");
            $json['error'] = "Not able to decrypt.";
            echo json_encode($json['error']);
        }

        $json['success'] = array("decryptedText" => $plaintext);
        echo json_encode($json['success']);

    }

Java:

public void encryptRequest(String input) throws JSONException{

    Encrypt e1 = new Encrypt();
    SodiumAndroid sodium = new SodiumAndroid();
    final LazySodiumAndroid lazySodium = new LazySodiumAndroid(sodium, StandardCharsets.UTF_8);
    SecretBox.Lazy secretBoxLazy = (SecretBox.Lazy) lazySodium;

    final byte[] nonce = lazySodium.randomBytesBuf(SecretBox.NONCEBYTES);
    final Key key = secretBoxLazy.cryptoSecretBoxKeygen();

    final String encryptedText = e1.encrypt(input, nonce, key);

    JSONObject postMethod = new JSONObject();
    postMethod.put("method", "decryptTest2");

    JSONObject postParams = new JSONObject();
    postParams.put("key", key.getAsHexString());
    postParams.put("nonce", lazySodium.sodiumBin2Hex(nonce));
    postParams.put("chiper", encryptedText);

    postMethod.put("params", postParams);

    final String requestBody = postMethod.toString();

    //{"method":"decryptTest2","params":{"key":"E9C0828178CEC39A8AD713F12E36203AA31C8F4885B6AE55B0C033D592CE9075","nonce":"94B683D94504D86D3FA654652545CAD3AA3F4863640ABD91","chiper":"8ED8B09269A0CABE6F8F4D5C851B4B35E987892956EF7E"}}
    //System.out.println("json: " + requestBody);

    String URL = "http://api.domain.com/index.php";

    JsonObjectRequest req = new JsonObjectRequest( Request.Method.POST, URL, postMethod,
            new Response.Listener<JSONObject>() {
                @Override
                public void onResponse(JSONObject response) {
                    System.out.println("json response: " + response);

                }
            },
            new Response.ErrorListener() {
                @Override
                public void onErrorResponse(VolleyError error) {
                    Toast.makeText(getApplicationContext(), error.getMessage(),
                            Toast.LENGTH_LONG).show();

                    System.out.println("json response: " + error.getMessage());
                }
            }) {

        @Override
        public String getBodyContentType() {
            return "application/json; charset=utf-8";
        }

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

        @Override
        public byte[] getBody() {
            try {
                return requestBody == null ? null : requestBody.getBytes("utf-8");
            } 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<JSONObject> parseNetworkResponse(NetworkResponse response) {
            String responseString;
            JSONObject jsonObject = null;

            if (response != null) {
                try {
                    responseString = new String(response.data, HttpHeaderParser.parseCharset(response.headers));

                    jsonObject = new JSONObject(responseString);

                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            return Response.success(jsonObject, HttpHeaderParser.parseCacheHeaders(response));
        }

    };

    req.setRetryPolicy(new DefaultRetryPolicy(5000,
            DefaultRetryPolicy.DEFAULT_MAX_RETRIES,
            DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));

    requestQueue.add(req);


}

我做错了什么?

【问题讨论】:

    标签: java android json android-volley jsonobjectrequest


    【解决方案1】:

    好的,经过数小时试图找出我做错了什么之后,似乎“JsonObjectRequest”不是我想要的。虽然,根据https://developer.android.com/training/volley/request

    JsonObjectRequest - 用于在给定 URL 检索 JSONObject 响应正文的请求,允许将可选 JSONObject 作为请求正文的一部分传入。

    我最初的想法:我在 body() 中发送(POST)一个 JSONObject 并从服务器接收 JSONObject 响应,所以,为什么不走这条路,对吧?错误的。我尝试将 JSONObject 作为参数传递,并尝试覆盖 body() 方法,但我在 Android 中一直收到“null”响应,而 Postman 工作时没有任何问题。

    我的解决方案:StringRequest。我还手动创建了正文字符串,而不是创建 JSONObject:

    public void encryptRequest(String input) {
    
        Encrypt sodium = new Encrypt();
    
        final byte[] nonce = sodium.randomNonce();
        final Key key = sodium.randomKey();
    
        final String encryptedText = sodium.encrypt(input, nonce, key);
    
        final String jSonString = "{\"method\":\"decryptTest2\", \"params\":{\"cipher\":\"" +
                encryptedText + "\", \"nonce\":\"" + sodium.convertNonce(nonce) +
                "\", \"key\":\"" + sodium.convertKey(key) + "\"}}";
    
        StringRequest stringRequest = new StringRequest(Request.Method.POST, sodium.getURL(),
                new Response.Listener<String>() {
            @Override
            public void onResponse(String response) {
    
                try {
    
                    JSONObject jsonObject = new JSONObject(response);
    
                    if (jsonObject.names().get(0).equals("success")) {
    
                        System.out.println("Decrypted Text: " + jsonObject.getJSONObject("success").getString("decryptedText"));
    
                    }
    
                    else {
    
                        System.out.println("Error decrypting: " + jsonObject.getJSONObject("error").getString("decryptedText"));
    
                    }
    
    
                } catch (JSONException e) {
                    e.printStackTrace();
                    Log.e("LOG_VOLLEY", e.getMessage());
                }
    
    
            }
        }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                Log.e("LOG_VOLLEY", error.getMessage());
            }
        }) {
            @Override
            public byte[] getBody() throws AuthFailureError {
    
                try {
                    return jSonString == null ? null : jSonString.getBytes("utf-8");
                } catch (UnsupportedEncodingException uee) {
                    VolleyLog.wtf("Unsupported Encoding while trying to get the bytes of %s using %s", jSonString, "utf-8");
                    return null;
                }
            }
    
            @Override
            public String getBodyContentType() {
                return "application/json";
            }
        };
    
        stringRequest.setRetryPolicy(new DefaultRetryPolicy(5000,
                DefaultRetryPolicy.DEFAULT_MAX_RETRIES,
                DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
    
        requestQueue.add(stringRequest);
    
    }
    

    在做了一些研究之后,似乎我不是唯一一个遇到这个问题的人。无论如何,我想我会发布我的解决方案,以防万一将来有人遇到同样的问题。

    【讨论】:

    • 伙计,我在 2020 年,经过数小时搜索您的答案是正确的,谢谢,我好累了
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-08-06
    • 2019-12-13
    • 2020-01-02
    • 2021-08-11
    • 1970-01-01
    • 1970-01-01
    • 2018-01-14
    相关资源
    最近更新 更多