博主最近遇到一个项目需求,需要对一个JSONString数据进行判断,根据type字段解析成不同的Object。
@POST("v1/recharge/new")
Call payNewPhone(@Body PayNewPhoneReq payNewPhoneReq);
然而,就在我自信的完成了返回类型的修改后,Retrofit毫不留情的给了我一个异常。
其实这个报错并不是来自Retrofit,而是来自Gson,它只会将"anything"这样的数据解析成String。博主也尝试了将返回类型替换为JSONObject,添加Scalars Converter等等等等……最终全部以失败告终。
于是博主决定更换掉不完善的Gson库,换成FastJson。
相信很多朋友在使用Retrofit的时候,为了图方便,使用的都是Gson解析,因为Retrofit官方并没有提供FastJson的解析库。不过不要紧,伟大的阿里爸爸早就帮我们写好了,他就在这里:
https://github.com/alibaba/fastjson/blob/master/src/main/java/com/alibaba/fastjson/support/retrofit/Retrofit2ConverterFactory.java
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.parser.Feature;
import com.alibaba.fastjson.parser.ParserConfig;
import com.alibaba.fastjson.serializer.SerializeConfig;
import com.alibaba.fastjson.serializer.SerializerFeature;
import okhttp3.MediaType;
import okhttp3.RequestBody;
import okhttp3.ResponseBody;
import retrofit2.Converter;
import retrofit2.Retrofit;
import java.io.IOException;
import java.lang.annotation.Annotation;
import java.lang.reflect.Type;
/**
* @author ligboy, wenshao
*/
public class Retrofit2ConverterFactory extends Converter.Factory {
private static final MediaType MEDIA_TYPE = MediaType.parse("application/json; charset=UTF-8");
private static final Feature[] EMPTY_SERIALIZER_FEATURES = new Feature[0];
private ParserConfig parserConfig = ParserConfig.getGlobalInstance();
private int featureValues = JSON.DEFAULT_PARSER_FEATURE;
private Feature[] features;
private SerializeConfig serializeConfig;
private SerializerFeature[] serializerFeatures;
public Retrofit2ConverterFactory() {
}
@Override
public Converter responseBodyConverter(Type type, //
Annotation[] annotations, //
Retrofit retrofit) {
return new ResponseBodyConverter(type);
}
@Override
public Converter, RequestBody> requestBodyConverter(Type type, //
Annotation[] parameterAnnotations, //
Annotation[] methodAnnotations, //
Retrofit retrofit) {
return new RequestBodyConverter();
}
public ParserConfig getParserConfig() {
return parserConfig;
}
public Retrofit2ConverterFactory setParserConfig(ParserConfig config) {
this.parserConfig = config;
return this;
}
public int getParserFeatureValues() {
return featureValues;
}
public Retrofit2ConverterFactory setParserFeatureValues(int featureValues) {
this.featureValues = featureValues;
return this;
}
public Feature[] getParserFeatures() {
return features;
}
public Retrofit2ConverterFactory setParserFeatures(Feature[] features) {
this.features = features;
return this;
}
public SerializeConfig getSerializeConfig() {
return serializeConfig;
}
public Retrofit2ConverterFactory setSerializeConfig(SerializeConfig serializeConfig) {
this.serializeConfig = serializeConfig;
return this;
}
public SerializerFeature[] getSerializerFeatures() {
return serializerFeatures;
}
public Retrofit2ConverterFactory setSerializerFeatures(SerializerFeature[] features) {
this.serializerFeatures = features;
return this;
}
final class ResponseBodyConverter implements Converter {
private Type type;
ResponseBodyConverter(Type type) {
this.type = type;
}
public T convert(ResponseBody value) throws IOException {
try {
return JSON.parseObject(value.string()
, type
, parserConfig
, featureValues
, features != null
? features
: EMPTY_SERIALIZER_FEATURES
);
} finally {
value.close();
}
}
}
final class RequestBodyConverter implements Converter {
RequestBodyConverter() {
}
public RequestBody convert(T value) throws IOException {
byte[] content = JSON.toJSONBytes(value
, serializeConfig == null
? SerializeConfig.globalInstance
: serializeConfig
, serializerFeatures == null
? SerializerFeature.EMPTY
: serializerFeatures
);
return RequestBody.create(MEDIA_TYPE, content);
}
}
}
只需要将它拷贝下来,新建一个Retrofit2ConverterFactory.java,粘贴,官方提供的Converter就有了,现成的~
然后就可以大刀阔斧的删掉Gson的ProGuard-Rule和implementation,导入FastJsonForAndroid:
implementation 'com.alibaba:fastjson:1.1.70.android'
在初始化Retrofit的地方,更换ConvertFactory:
Retrofit retrofit = new Retrofit.Builder().baseUrl(HttpArgs.BASE_URL)
//更换ConvertFactory
.addConverterFactory(new Retrofit2ConverterFactory())
再次运行APP,OK问题解决~
你看,国外的月亮也不比中国的圆。
最后是国际惯例,如果觉得有帮助的话,就打赏博主一个红包吧~