Retrofit 2.0转换器返回空值

4
我使用的是Retrofit 2.0.0-beta2
我找到了一个示例,能将同步的转换 .errorBody为对象。
我需要实现异步转换。
这是我的JSON:
{
  "error_msg": "This user name is already registered."
}

当运行异步示例时,我得到了 null。
package com.test.client;

import com.squareup.okhttp.ResponseBody;

import java.io.IOException;
import java.lang.annotation.Annotation;

import retrofit.Call;
import retrofit.Callback;
import retrofit.Converter;
import retrofit.GsonConverterFactory;
import retrofit.Response;
import retrofit.Retrofit;
import retrofit.http.GET;

public final class DeserializeErrorBody {

interface Service {
    @GET("account.signup")
    Call<User> getUser();
}

static class User {
    // normal fields...
}

static class Error {
    String error_msg;
}

public static void main(String... args) throws IOException {
    Retrofit retrofit = new Retrofit.Builder()
            .baseUrl("https://api.site.com/method/")
            .addConverterFactory(GsonConverterFactory.create())
            .build();

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


    // ASYNCHRONOUS

    Call<User> response = service.getUser();
    response.enqueue(new Callback<User>() {

        @Override
        public void onResponse(Response<User> response, Retrofit retrofit) {
            if(!responce.isSuccess()) {

                System.out.println(response.errorBody().string()); // returns { "error_msg": "This user name is already registered."}    :)))))

                Converter<ResponseBody, Error> errorConverter = retrofit.responseConverter(Error.class, new Annotation[0]);

                try {
                    Error error = errorConverter.convert(response.errorBody());

                    System.out.println(error); // returns null   :((((((

                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

        @Override
        public void onFailure(Throwable t) {
            // ...
        }
    });


    // SYNCHRONOUS

    /*
    Response<User> call = service.getUser().execute();
    Converter<ResponseBody, Error> errorConverter = retrofit.responseConverter(Error.class, new Annotation[0]);

    Error error = errorConverter.convert(call.errorBody());
    System.out.println(error); // returns Object     :))))))
    System.out.println(error.error_msg); // returns "This user name is already registered."    :))))))
    */

}
}

对不起我的英语不好 :)

在异步请求中,成功返回一个字符串。然而,转换为对象没有运行。

如何获得对象而不是 null?


你有什么问题? - Jason D
如何获取对象而不是 null? - Qulery
1
你的方法 Call<User> getUser(); 是同步的,如果需要异步请求,请查看此链接 - NullPointerException
@NullPointerException, 你的文章使用的是 retrofit 1.9 版本。 在 2.0 版本中,接口对于同步和异步请求的描述是相同的。 http://inthecheesefactory.com/blog/retrofit-2.0 - Qulery
1个回答

4

好的,你的问题出在以下代码行:

System.out.println(response.errorBody().string());

如果你查看com.squareapp.okhttp.ResponseBody源码,你会发现调用string()将消耗掉响应的流。因此,下次您尝试解析响应正文时:

Error error = errorConverter.convert(response.errorBody());

errorBody()的调用将不会提供任何字节流,Gson也不会解析任何数据。

那么你该怎么办呢?只需不要以你这样的方式消费errorBody()即可。只需删除此行:

System.out.println(response.errorBody().string());

如果需要高级日志记录,请单击此链接。这应该基本上是这样的:

OkHttpClient client = new OkHttpClient();
HttpLoggingInterceptor logging = new HttpLoggingInterceptor();
logging.setLevel(Level.BASIC);
client.interceptors().add(logging);

Retrofit retrofit = new Retrofit.Builder()
       .baseUrl("https://api.site.com/method/")
       .addConverterFactory(GsonConverterFactory.create())
       .client(client)
       .build();

非常感谢!一切都正常工作了!感谢您的帮助!! - Qulery
我遇到了类似的问题,有人可以给些建议吗?http://stackoverflow.com/questions/39261481/assigning-reference-when-accessing-json-response - tccpg288

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接