Two steps to let Retrofit use FastJson analysis: Solve the return String error: Expected a string but was BEGIN_OBJECT at line 1 column 2 path

The blogger recently encountered a project requirement and needed to judge a JSONString data and parse it into different Objects according to the type field.

    @POST("v1/recharge/new")
    Call<String> payNewPhone(@Body PayNewPhoneReq payNewPhoneReq);

However, after I confidently completed the modification of the return type, Retrofit gave me an exception relentlessly.

In fact, this error does not come from Retrofit, but from Gson, which will only parse data such as "anything" into String. The bloggers also tried to replace the return type with JSONObject, add Scalars Converter, etc... all ended in failure.

So the blogger decided to replace the imperfect Gson library and replace it with FastJson.

I believe that when using Retrofit, many friends use Gson parsing for the convenience of illustration, because Retrofit does not officially provide FastJson parsing library. But it doesn’t matter, the great Ali father wrote it for us long ago, and he is here:

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<ResponseBody, ?> responseBodyConverter(Type type, //
                                                            Annotation[] annotations, //
                                                            Retrofit retrofit) {
        return new ResponseBodyConverter<ResponseBody>(type);
    }

    @Override
    public Converter<?, RequestBody> requestBodyConverter(Type type, //
                                                          Annotation[] parameterAnnotations, //
                                                          Annotation[] methodAnnotations, //
                                                          Retrofit retrofit) {
        return new RequestBodyConverter<RequestBody>();
    }

    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<T> implements Converter<ResponseBody, T> {
        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<T> implements Converter<T, RequestBody> {
        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);
        }
    }
}

Just copy it down, create a new Retrofit2ConverterFactory.java, paste it, the official converter is there, ready-made~

Then you can drastically delete Gson's ProGuard-Rule and implementation and import FastJsonForAndroid:


implementation 'com.alibaba:fastjson:1.1.70.android'

In the place where Retrofit is initialized, replace ConvertFactory:

Retrofit retrofit = new Retrofit.Builder().baseUrl(HttpArgs.BASE_URL)

                //更换ConvertFactory

                .addConverterFactory(new Retrofit2ConverterFactory())

Run the APP again, OK the problem is solved~

You see, the moon in foreign countries is no more rounder than in China.

Finally, it is international practice. If you find it helpful, give the blogger a red envelope~

Guess you like

Origin blog.csdn.net/u014653815/article/details/84141027