gpt4 book ai didi

android - 无法解析 Retrofit 2 中的错误

转载 作者:塔克拉玛干 更新时间:2023-11-02 20:49:46 25 4
gpt4 key购买 nike

我正在使用 Retrofit 2,但在这一行出现空指针异常:

 RetrofitClient.APIError error = RetrofitClient.ErrorUtils.parseError(response, retrofit);

错误为空。更多详情:

这是 API 返回错误的格式:

{
"error": {
"message": "Incorrect credentials",
"statusCode": 401
}
}

这是我的登录回调代码:

new Callback<LoginResponse>() {

@Override
public void onResponse(Response<LoginResponse> response, Retrofit retrofit) {
if (listener != null) {
if (response.isSuccess() && response.body() != null) {

User user = RetrofitUserToUserMapper.fromRetrofitUser(response.body().getLoginUser());

} else {

RetrofitClient.APIError error = RetrofitClient.ErrorUtils.parseError(response, retrofit);
listener.onUserLoginFailure(error.getErrorMessage()); // NPE - error is null
}
}
}

@Override
public void onFailure(Throwable t) {

if (listener != null) {
listener.onUserLoginFailure("");
}
}
}

这是我的 Retrofit 2 类:

public class RetrofitClient {

public static final String API_ROOT = "http://example.com/api/v1/";
private static final String HEADER_OS_VERSION = "X-OS-Type";
private static final String HEADER_APP_VERSION = "X-App-Version";
private static final String HEADER_OS_VERSION_VALUE_ANDROID = "android";


private RetrofitClient() {
}

private static Retrofit INSTANCE;

public static Retrofit getInstance() {
if (INSTANCE == null) {
setupRestClient();
}
return INSTANCE;
}

public static void setupRestClient() {

OkHttpClient httpClient = new OkHttpClient();
addHeadersRequiredForAllRequests(httpClient, BuildConfig.VERSION_NAME);

INSTANCE = new Retrofit.Builder()
.baseUrl(API_ROOT)
.addConverterFactory(GsonConverterFactory.create())
.client(httpClient)
.build();
}

private static void addHeadersRequiredForAllRequests(OkHttpClient httpClient, final String appVersion) {

class RequestInterceptor implements Interceptor {

@Override
public com.squareup.okhttp.Response intercept(Chain chain) throws IOException {
Request request = chain.request().newBuilder()
.addHeader(HEADER_OS_VERSION, HEADER_OS_VERSION_VALUE_ANDROID)
.addHeader(HEADER_APP_VERSION, appVersion)
.build();
return chain.proceed(request);
}
}

httpClient.networkInterceptors().add(new RequestInterceptor());
}

public static class ErrorUtils {

public static APIError parseError(Response<?> response, Retrofit retrofit) {
Converter<ResponseBody, APIError> converter =
retrofit.responseConverter(APIError.class, new Annotation[0]);

APIError error;

try {
error = converter.convert(response.errorBody());
} catch (IOException e) {
e.printStackTrace();
return new APIError();
} catch (Exception e) {
e.printStackTrace();
return new APIError();
}

return error;
}
}

public static class APIError {
@SerializedName("error")
public
ErrorResponse loginError;

public ErrorResponse getLoginError() {
return loginError;
}

public String getErrorMessage() {
return loginError.message;
}

private class ErrorResponse {
@SerializedName("message")
private String message;
@SerializedName("statusCode")
public int statusCode;

public String getMessage() {
return message;
}

public int getStatusCode() {
return statusCode;
}

@Override
public String toString() {
return "LoginErrorResponseBody{" +
"message='" + getMessage() + '\'' +
", statusCode=" + statusCode +
'}';
}

public void setMessage(String message) {
this.message = message;
}
}
}


}

我从本教程中得到了错误 utils 类,但由于他们示例中的错误格式不同而对其进行了轻微更改:

编辑:这是 Converter 类:

/**
* Convert objects to and from their representation as HTTP bodies. Register a converter with
* Retrofit using {@link Retrofit.Builder#addConverterFactory(Factory)}.
*/
public interface Converter<F, T> {
T convert(F value) throws IOException;

abstract class Factory {
/**
* Create a {@link Converter} for converting an HTTP response body to {@code type} or null if it
* cannot be handled by this factory.
*/
public Converter<ResponseBody, ?> fromResponseBody(Type type, Annotation[] annotations) {
return null;
}

/**
* Create a {@link Converter} for converting {@code type} to an HTTP request body or null if it
* cannot be handled by this factory.
*/
public Converter<?, RequestBody> toRequestBody(Type type, Annotation[] annotations) {
return null;
}
}
}

最佳答案

更新:

如果你想使用自定义类而不是下面的JSONObject,你可以引用以下内容:

自定义类:

public class ResponseError {

Error error;

class Error {
int statusCode;
String message;
}
}

WebAPIService接口(interface)中添加如下内容:

@GET("/api/geterror")
Call<ResponseError> getError2();

然后,在 MainActivity.java 中:

Call<ResponseError> responseErrorCall = service.getError2();
responseErrorCall.enqueue(new Callback<ResponseError>() {
@Override
public void onResponse(Response<ResponseError> response, Retrofit retrofit) {
if (response.isSuccess() && response.body() != null){
Log.i(LOG_TAG, response.body().toString());
} else {
if (response.errorBody() != null){
RetrofitClient.APIError error = RetrofitClient.ErrorUtils.parseError(response, retrofit);
Log.e(LOG_TAG, error.getErrorMessage());
}
}
}

@Override
public void onFailure(Throwable t) {
Log.e(LOG_TAG, t.toString());
}
});

我刚刚用我的 Web 服务测试了您的 RetrofitClient 类。我对您的 APIError 类做了如下小更新(添加 2 个构造函数,实际上它们没有被调用):

public APIError(){
this.loginError = new ErrorResponse();
}

public APIError(int statusCode, String message) {
this.loginError = new ErrorResponse();
this.loginError.statusCode = statusCode;
this.loginError.message = message;
}

接口(interface):

public interface WebAPIService {
@GET("/api/geterror")
Call<JSONObject> getError();
}

主要 Activity :

// Retrofit 2.0-beta2
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(API_URL_BASE)
.addConverterFactory(GsonConverterFactory.create())
.build();

WebAPIService service = retrofit.create(WebAPIService.class);

Call<JSONObject> jsonObjectCall = service.getError();
jsonObjectCall.enqueue(new Callback<JSONObject>() {
@Override
public void onResponse(Response<JSONObject> response, Retrofit retrofit) {
if (response.isSuccess() && response.body() != null){
Log.i(LOG_TAG, response.body().toString());
} else {
if (response.errorBody() != null){
RetrofitClient.APIError error = RetrofitClient.ErrorUtils.parseError(response, retrofit);
Log.e(LOG_TAG, error.getErrorMessage());
}
}
}

@Override
public void onFailure(Throwable t) {
Log.e(LOG_TAG, t.toString());
}
});

我的网络服务(Asp.Net Web API):

根据你的JSON响应数据,我使用了如下代码:

[Route("api/geterror")]
public HttpResponseMessage GetError()
{
var detailError = new
{
message = "Incorrect credentials",
statusCode = 401
};

var myError = new
{
error = detailError
};

return Request.CreateResponse(HttpStatusCode.Unauthorized, myError);
}

它的工作!希望对您有所帮助!

关于android - 无法解析 Retrofit 2 中的错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34462019/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com