如何获得网络响应,即使状态代码不是 200

How to get network response even status code not 200

我使用 API 登录,如果登录成功它 return 代码 200 和响应。如果不正确的电子邮件或密码将 return 代码 401 与 json 对象包含错误 问题是我想获得网络响应,即使请求代码不等于 200,如图像

但是凌空抛出异常BasicNetwork.performRequest: Unexpected response code 401

这是我的代码

public interface OnResponse{
    void onResponse(JSONObject response) throws Exception;
    void onErrorResponse(VolleyError volleyError);
}//OnResponse



public static void newRequest(Context context, String url, final Map<String, String>params, final OnResponse onResponse){
    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

    RequestQueue queue = Volley.newRequestQueue(context);
    //
    //onErrorResponse()
    //onResponse()
    StringRequest stringRequest = new StringRequest(Request.Method.POST, url, response -> {
        // - - - - - - - - - - - - - - - - - - - - -
        try {
            JSONObject object = new JSONObject(response);
            onResponse.onResponse(object);
        } catch (Exception e) {
            Log.e(TAG, "FLAG-1");
            e.printStackTrace();
        }
        // - - - - - - - - - - - - - - - - - - - - -
    }, error -> {
        Log.e(TAG, "FLAG-2");
        onResponse.onErrorResponse(error);
    }){
        @Override
        protected VolleyError parseNetworkError(VolleyError volleyError) {
            volleyError.printStackTrace();
            Log.e("zxc", volleyError.getMessage()+"");
            Log.e("zxc", volleyError.getLocalizedMessage()+"");
            return super.parseNetworkError(volleyError);
        }
    };
    //
    stringRequest.setParams(params);
    stringRequest.setShouldCache(false);
    queue.add(stringRequest);
    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
}//newRequest()`

只需在 newRequest() 方法中覆盖 parseNetworkResponse,如下所示

StringRequest request = new StringRequest(Method.GET,
            <your url>,
            new Response.Listener<String>() {
                @Override
                public void onResponse(String response) {
                    //handle response
                }
            },
            new Response.ErrorListener() {
                @Override
                public void onErrorResponse(VolleyError error) {
                    //handle error
                }
            }) {

        @Override
        protected Response<String> parseNetworkResponse(NetworkResponse response) {
            int mStatusCode = response.statusCode;
            return super.parseNetworkResponse(response);
        }
    };

VolleyError 具有 networkResponse 属性,它包含响应。

这是一个例子:String response = new String(error.networkResponse.data);

您可以从 VolleyError 中提取响应数据。

@Override
public void onErrorResponse(VolleyError error) {
   NetworkResponse networkResponse = error.networkResponse;
   if (networkResponse != null && networkResponse.data != null) {
   String jsonError = new String(networkResponse.data);
   // Print Error!
    }
 }

如果网络状态代码不是 4xx 或 5xx,Volley returns 在 onErrorResponse 中的响应为 VolleyError。响应以字节数组形式接收,因此您需要对其进行解析以读取错误和消息键。

以下是所需代码的精简版。

final String failAuthError = new String(volleyError.networkResponse.data, Charset.forName("UTF-8"));
ErrorResponse errorResponse = new Gson().fromJson(failAuthError, ErrorResponse.class);
Log.e(TAG, "Error Status: " + errorResponse.error);
Log.e(TAG, "Error Message: " + errorResponse.message);

ErrorResponse 是带有 errormessage 变量的自定义 class。

class ErrorResponse {
    @Expose
    @SerializedName("error")
    String error;

    @Expose
    @SerializedName("message")
    String message;
}