您的位置:首页 > 编程语言 > Java开发

Retrofit2源码解析(二)添加 JacksonConverterFactory转化器

2016-11-07 17:26 351 查看
1、获取实例时,我们添加个转化器

retrofit = new Retrofit.Builder().baseUrl("http://localhost:8080/campus/")
.addConverterFactory(JacksonConverterFactory.create())
.build();


这时候相当于就多了一个转化器。所以还是支持上篇中的请求方式(主要是返回类型和入参类型)

2、话不多话。直接看转化器源码,看它支持哪些类型

retrofit2.converter.jackson.JacksonConverterFactory.java

public final class JacksonConverterFactory extends Converter.Factory {

public static JacksonConverterFactory create() {
return create(new ObjectMapper());
}

public static JacksonConverterFactory create(ObjectMapper mapper) {
return new JacksonConverterFactory(mapper);
}

private final ObjectMapper mapper;

private JacksonConverterFactory(ObjectMapper mapper) {
if (mapper == null) throw new NullPointerException("mapper == null");
this.mapper = mapper;
}
//返回类型retrofit2.Call<T> T没有任何限制,什么都可以由jackson处理
@Override
public Converter<ResponseBody, ?> responseBodyConverter(Type type, Annotation[] annotations,
Retrofit retrofit) {
JavaType javaType = mapper.getTypeFactory().constructType(type);
ObjectReader reader = mapper.reader(javaType);
return new JacksonResponseBodyConverter<>(reader);
}

//接口的形参类型也没有任何限制,什么都可以由jackson处理
@Override
public Converter<?, RequestBody> requestBodyConverter(Type type,
Annotation[] parameterAnnotations, Annotation[] methodAnnotations, Retrofit retrofit) {
JavaType javaType = mapper.getTypeFactory().constructType(type);
ObjectWriter writer = mapper.writerWithType(javaType);
return new JacksonRequestBodyConverter<>(writer);
}
}


是不是很爽。我们试下,在第一篇的基础对请求接口做修改

public interface HttpLogin {
@POST("account/login")
//直接返回一个HashMap看看
retrofit2.Call<HashMap<String, Object>> login(@Body Account body);
}


@Test
public void testRetrofit() {
retrofit2.Call<HashMap<String, Object>> login = retrofit.create(HttpLogin.class)
.login(new Account("yincs", null));
login.enqueue(new retrofit2.Callback<HashMap<String, Object>>() {

public void onResponse(retrofit2.Call<HashMap<String, Object>> call,
retrofit2.Response<HashMap<String, Object>> response) {
System.out.println("onResponse " + response.body().get("des"));
}

public void onFailure(retrofit2.Call<HashMap<String, Object>> call, Throwable t) {

System.out.println("onFailure " + t.getMessage());
}
});

sleep(12000);
}

执行结果
onResponse 参数错误[密码不能为空]
Process finished with exit code 0

也是成功的


一般服务器返回的参数形式一样。那我们能不能用一个统一类加泛型处理呢?

答案是当然可以的

先创建一个统一类

public class AppRes<T> {
private int code;
private String des;
T data;

public int getCode() {
return code;
}

public void setCode(int code) {
this.code = code;
}

public String getDes() {
return des;
}

public void setDes(String des) {
this.des = des;
}

public T getData() {
return data;
}

public void setData(T data) {
this.data = data;
}
}


接口改下

public interface HttpLogin {
@POST("account/login")
retrofit2.Call<AppRes<User>> login(@Body Account body);
}


执行下

retrofit.create(HttpLogin.class)
.login(new Account("ycs",null))
.enqueue(new retrofit2.Callback<AppRes<User>>() {
@Override
public void onResponse(retrofit2.Call<AppRes<User>> call, retrofit2.Response<AppRes<User>> response) {
System.out.println("onResponse " + response.body().getDes());
}

@Override
public void onFailure(retrofit2.Call<AppRes<User>> call, Throwable t) {
System.out.println("onFailure " + t.getMessage());
}
});
返回结果
onResponse 参数错误[密码不能为空]

Process finished with exit code 0


一切ok!!!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  源码 Retrofit java