之前写过一篇 浅谈Retrofit封装-让框架更加简洁易用 里面采用的是GsonConverterFactory,对于retrofit的返回类型要求只能是: 具体对象、jsonObject、jsonArray这三种。由于服务器返回的基础数据格式不固定,所以封装请求类的时候每个请求方式都要封装两个方法,而retrofit又必须添加一种解析器,本人对代码有洁癖,抽时间写了个StringConverterFactory将数据解析成最基本的String返回。
参考GsonConverterFactory源码,自定义解析器还是比较好写的,一共三个类,直接贴了
解析器 工厂
packagecom.sunshine.retrofit.converter;importjava.lang.annotation.Annotation;importjava.lang.reflect.Type;importokhttp3.RequestBody;importokhttp3.ResponseBody;importretrofit2.Converter;importretrofit2.Retrofit;
/**
* Created by 耿 on 2016/9/6.
*/
publicclassStringConverterFactoryextendsConverter.Factory{
publicstaticStringConverterFactorycreate() {
return newStringConverterFactory();
}privateStringConverterFactory() {
}
@OverridepublicConverterresponseBodyConverter(Type type, Annotation[] annotations, Retrofit retrofit) {
return newStringResponseBodyConverter();
}
@OverridepublicConverterrequestBodyConverter(Type type, Annotation[] parameterAnnotations, Annotation[] methodAnnotations, Retrofit retrofit) {
return newStringRequestBodyConverter();
}
}
Response响应体类
packagecom.sunshine.retrofit.converter;importjava.io.IOException;importokhttp3.ResponseBody;importretrofit2.Converter;
/**
* Created by 耿 on 2016/9/6.
*/
publicclassStringResponseBodyConverterimplementsConverter {
@Overridepublic String convert(ResponseBody value)throwsIOException {
try{
returnvalue.string();
}finally{
value.close();
}
}}
Request 请求体类
packagecom.sunshine.retrofit.converter;importjava.io.IOException;importjava.io.OutputStreamWriter;importjava.io.Writer;importjava.nio.charset.Charset;importokhttp3.MediaType;importokhttp3.RequestBody;importokio.Buffer;importretrofit2.Converter;
/**
* Created by 耿 on 2016/9/6.
*/
publicclassStringRequestBodyConverterimplementsConverter {
privatestaticfinalMediaType MEDIA_TYPE = MediaType.parse("application/json; charset=UTF-8");privatestaticfinalCharset UTF_8 = Charset.forName("UTF-8");
StringRequestBodyConverter() { }
@Overridepublic RequestBody convert(String value)throwsIOException {
Buffer buffer =newBuffer();
Writer writer =newOutputStreamWriter(buffer.outputStream(), UTF_8);
writer.write(value);
writer.close();
return RequestBody.create(MEDIA_TYPE, buffer.readByteString());
}
}
在构建retrofit时替换掉原来的GsonConverterFactory就可以了
Retrofit retrofit = new Retrofit.Builder().baseUrl(BASE_URL +"/").addConverterFactory(StringConverterFactory.create()).addCallAdapterFactory(RxJavaCallAdapterFactory.create()).client(OkhttpProvidede.okHttpClient(mAppliactionContext, BASE_URL, SERVERS)).build();
这里要注意,retrofit对于解析器是由添加的顺序分别试用的,解析成功就直接返回,失败则调用下一个解析器。如果你们的服务器一开始基本返回格式不固定,而后来在你的建议或者坚持下,大发善心的把后面新需求的API的返回格式都固定了的话,可以按如下代码的方式将GsonConverterFactory添加在StringConverterFactory前面。这样如果是固定格式的就可以直接解析返回了。
Retrofit retrofit = new Retrofit.Builder().baseUrl(BASE_URL +"/").addConverterFactory(GsonConverterFactory.create()).addConverterFactory(StringConverterFactory.create()).addCallAdapterFactory(RxJavaCallAdapterFactory.create()).client(OkhttpProvidede.okHttpClient(mAppliactionContext, BASE_URL, SERVERS)).build();
然后以后调用请求就可以直接
newHttpUtil.Builder("favorite_authorized/list?page=1") .Version() .CacheTime("3600*24") .Params("carId", sb.toString()) .Params(sortMap_) .Success((s) -> { ld_.dismiss(); BaseModel model =newBaseModel(s); }).Error((v) -> { ld_.dismiss(); handler_.obtainMessage(MSG, v[1]).sendToTarget(); }).get(); });
再也不用去管返回格式是jsonObject还是jsonArray了。