我遇到一个问题,其中onResponse(JSONObject response)始终返回null。
我已经记录了在请求(POST)中作为正文传递的JSONObject.toString,并粘贴到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);
}
我在做什么错了?
答案 0 :(得分:0)
好吧,经过数小时的尝试来弄清楚我在做什么错之后,看来'JsonObjectRequest'不是我想要的。尽管,根据https://developer.android.com/training/volley/request,
JsonObjectRequest-在给定URL上检索JSONObject响应主体的请求,允许将可选的JSONObject作为请求主体的一部分传入。
我最初的想法:我在body()中发送(POST)一个JSONObject并从服务器接收一个JSONObject响应,所以,为什么不走这条路呢?错误。我尝试将JSONObject作为参数传递,并尝试覆盖body()方法,但在Postman正常工作的情况下,我在Android中始终收到“空”响应。
我的解决方案: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);
}
经过一些研究,似乎我并不是唯一遇到此问题的人。无论如何,我以为我会发布解决方案,以防万一将来有人遇到相同的问题。