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接口:
@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;}
接口:
public interface WebAPIService { @GET("/API/geterror") Call<JsONObject> getError();}
主要活动:
// Retrofit 2.0-beta2Retrofit 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,t.toString()); }});
我的Web服务(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中解析错误全部内容,希望文章能够帮你解决android – 无法在Retrofit 2中解析错误所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)