Retrofit2+Rxjava json数据自定义的发送和解析

      在网络网通信传输json数据格式的时候,有时候Json的数据格式并不是标准的json数据格式。这个时候在使用Gson ,fastJson 等框架去解析的时候回出现异常,例如 Expected BEGIN_OBJECT but was STRING,造成这种异常的原因有

      第一:返回的json数据和要期望解析成的格式不对应,这个时候只要修改本地期望解析格式和json格式保持一致即可

      第二:返回的json格式不是标准的json格式,这个时候就要获取json的源数据,然后找到json数据格式错误的地方,将不标准的json转换成标准的json在去解析。这就用到自定义解析json。

正常使用Retrofit2+Rxjava+OKhttp3的格式为:

    封装Retrofit2:

        

package scj.jl.com.jlscjsockeserver.fujianinetworkbean.network.retrofit;
import android.util.Log;

import com.google.gson.Gson;

import org.apache.http.conn.ssl.AllowAllHostnameVerifier;

import java.util.concurrent.TimeUnit;

import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;

import okhttp3.OkHttpClient;
import okhttp3.logging.HttpLoggingInterceptor;
import retrofit2.Retrofit;
import retrofit2.adapter.rxjava.RxJavaCallAdapterFactory;
import retrofit2.converter.gson.GsonConverterFactory;

public class BaseRetrofit {
    private  String tag = BaseRetrofit.class.getSimpleName();
    private static final int DEFAULT_WRITE_TIME_OUT = 10;
    private static final int DEFAULT_READ_TIME_OUT = 10;
    private static final int DEFAULT_TIME_OUT = 20;//超时时间 10s
    private Retrofit mRetrofit;
    private static BaseRetrofit instance = null;
    /**
     * 获取BaseRetrofit
     * @return
     */
    public static BaseRetrofit getInstance(){
        if (instance == null){
            synchronized (BaseRetrofit.class){
                if (instance == null){
                    instance = new BaseRetrofit();
                }
            }
        }
        return  instance;
    }

    private BaseRetrofit(){
        HttpLoggingInterceptor logInterceptor = new HttpLoggingInterceptor(new HttpLogger());
        logInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
        try {
            SSLContext sslContext = SSLContext.getInstance("TLS");
            sslContext.init(null, trustAllCerts, new java.security.SecureRandom());

        OkHttpClient builder = new OkHttpClient().newBuilder()
                .addInterceptor(logInterceptor)
                .connectTimeout(DEFAULT_TIME_OUT, TimeUnit.SECONDS)
                .writeTimeout(DEFAULT_WRITE_TIME_OUT,TimeUnit.SECONDS)
                .readTimeout(DEFAULT_READ_TIME_OUT,TimeUnit.SECONDS)
                .sslSocketFactory(sslContext.getSocketFactory()) //过滤所有证书
                .hostnameVerifier(new AllowAllHostnameVerifier())
                .build();
        // 创建Retrofit
        if (mRetrofit == null){
            mRetrofit = new Retrofit.Builder()
//                    .addConverterFactory(CustomizeGsonConverterFactory.create()) 自定义ConverterFactory
                    .addConverterFactory(GsonConverterFactory.create(new Gson()))使用官方的ConverterFactory
                    .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
                    .client(builder)
                    .baseUrl(HttpUrlConfig.BaseServerUrl)
                    .build();
        }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    /**
     * 获取对应的Service
     * @param service Service 的 class
     * @param <T>
     * @return
     */
    public <T> T create(Class<T> service){
        return mRetrofit.create(service);
    }


    public class HttpLogger implements HttpLoggingInterceptor.Logger {
        @Override
        public void log(String message) {
            Log.d("HttpLogInfo", message);
        }
    }
    TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() {
        @Override
        public void checkClientTrusted(
                java.security.cert.X509Certificate[] x509Certificates,
                String s) throws java.security.cert.CertificateException {
        }

        @Override
        public void checkServerTrusted(
                java.security.cert.X509Certificate[] x509Certificates,
                String s) throws java.security.cert.CertificateException {
        }

        @Override
        public java.security.cert.X509Certificate[] getAcceptedIssuers() {
            return new java.security.cert.X509Certificate[] {};
        }
    } };

}

接口封装:

package scj.jl.com.jlscjsockeserver.fujianinetworkbean.network.retrofit;



import retrofit2.Call;
import retrofit2.http.Body;
import retrofit2.http.Headers;
import retrofit2.http.POST;
import rx.Observable;
import scj.jl.com.jlscjsockeserver.fujianinetworkbean.bean.BaseRequestBean;
import scj.jl.com.jlscjsockeserver.fujianinetworkbean.bean.BaseResponsBean;
import scj.jl.com.jlscjsockeserver.fujianinetworkbean.bean.LoginModel;


public interface NetInterface {

    @Headers({"Content-Type: application/json","Accept: application/json"})
    @POST("/")
    Observable<BaseResponsBean> request(@Body BaseRequestBean baseRequestBean);

    @Headers({"Content-Type: application/json","Accept: application/json"})
    @POST("/")
    Observable<BaseResponsBean> request2(@Body BaseRequestBean baseRequestBean);
}

 

接口调用封装:

package scj.jl.com.jlscjsockeserver.fujianinetworkbean.network.retrofit;

import com.google.gson.Gson;

import retrofit2.Callback;
import rx.Observable;
import rx.Observer;
import scj.jl.com.jlscjsockeserver.fujianinetworkbean.bean.BaseRequestBean;
import scj.jl.com.jlscjsockeserver.fujianinetworkbean.bean.BaseResponsBean;
import scj.jl.com.jlscjsockeserver.fujianinetworkbean.bean.LoginModel;
import scj.jl.com.jlscjsockeserver.fujianinetworkbean.bean.ToolsUtils;
import scj.jl.com.utillibrary.log.LogUtil;

/**
 * Created by jl on 2020/5/26.
 */

public class ApiNet  extends BaseNet{

    private String TAG = "ApiNet";
    private static NetInterface mNetInterface;
    private static ApiNet instance = null;
    public static ApiNet getInstance(){
        if (instance == null){
            instance = new ApiNet();
            mNetInterface = BaseRetrofit.getInstance().create(NetInterface.class);
        }
        return instance;
    }

    /**
     * 请求接口
     * @param baseRequestBean
     * @return
     */
    public Observable<BaseResponsBean> requests(BaseRequestBean baseRequestBean){
        return mNetInterface.request(baseRequestBean);
    }

}

 

引用

implementation 'com.squareup.retrofit2:retrofit:2.2.0'
implementation 'com.squareup.retrofit2:converter-gson:2.2.0'
implementation 'com.squareup.retrofit2:adapter-rxjava:2.2.0'
implementation 'com.squareup.okhttp3:logging-interceptor:3.5.0'
implementation 'com.squareup.okhttp3:okhttp:3.2.0'

当需要自定义的时候我们自己重写Converter.Factory

package scj.jl.com.jlscjsockeserver.fujianinetworkbean.network.retrofit;

import com.google.gson.Gson;
import com.google.gson.TypeAdapter;
import com.google.gson.reflect.TypeToken;

import java.lang.annotation.Annotation;
import java.lang.reflect.Type;

import okhttp3.RequestBody;
import okhttp3.ResponseBody;
import retrofit2.Converter;
import retrofit2.Retrofit;
import scj.jl.com.utillibrary.log.LogUtil;


/**
 * Created by jl on 2020/5/27.
 */

public class CustomizeGsonConverterFactory extends Converter.Factory {
    private static final String TAG  = CustomizeGsonConverterFactory.class.getSimpleName();
    public static CustomizeGsonConverterFactory create() {
        return create(new Gson());
    }

    public static CustomizeGsonConverterFactory create(Gson gson) {
        return new CustomizeGsonConverterFactory(gson);
    }

    private final Gson gson;

    private CustomizeGsonConverterFactory(Gson gson) {
        if (gson == null) {
            throw new NullPointerException("gson == null");
        }
        this.gson = gson;
    }

    @Override
    public Converter<ResponseBody, ?> responseBodyConverter(Type type, Annotation[] annotations, Retrofit retrofit) {
//        return super.responseBodyConverter(type, annotations, retrofit);
        LogUtil.d(TAG,"type"+type);

    //自定义的请求响应处理
        TypeAdapter<?> adapter = gson.getAdapter(TypeToken.get(type));
        return new CustomizeGsonResponseBodyConverter<>(gson, adapter);
    }

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

// 自定义的请求处理
        TypeAdapter<?> adapter = gson.getAdapter(TypeToken.get(type));
        return new CustomizeGsonRequestBodyConverter<>(gson, adapter);
    }
}
 

 

自定义的请求

package scj.jl.com.jlscjsockeserver.fujianinetworkbean.network.retrofit;

import com.google.gson.Gson;
import com.google.gson.TypeAdapter;
import com.google.gson.stream.JsonWriter;

import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.nio.charset.Charset;

import okhttp3.MediaType;
import okhttp3.RequestBody;
import okio.Buffer;
import retrofit2.Converter;

/**

这里没有任何改变
 * Created by jl on 2020/5/27.
 */

public class CustomizeGsonRequestBodyConverter<T> implements Converter<T, RequestBody>{

    private static final MediaType MEDIA_TYPE = MediaType.parse("application/json; charset=UTF-8");
    private static final Charset UTF_8 = Charset.forName("UTF-8");

    private final Gson gson;
    private final TypeAdapter<T> adapter;

    CustomizeGsonRequestBodyConverter(Gson gson, TypeAdapter<T> adapter) {
        this.gson = gson;
        this.adapter = adapter;
    }
    @Override
    public RequestBody convert(T value) throws IOException {
        Buffer buffer = new Buffer();
        Writer writer = new OutputStreamWriter(buffer.outputStream(), UTF_8);
        JsonWriter jsonWriter = gson.newJsonWriter(writer);
        adapter.write(jsonWriter, value);
        jsonWriter.close();
        return RequestBody.create(MEDIA_TYPE, buffer.readByteString());
    }
}
 

自定义的响应

package scj.jl.com.jlscjsockeserver.fujianinetworkbean.network.retrofit;

import android.util.Log;

import com.google.gson.Gson;
import com.google.gson.TypeAdapter;

import org.json.JSONException;
import org.json.JSONObject;

import java.io.IOException;

import okhttp3.ResponseBody;
import retrofit2.Converter;
import scj.jl.com.jlscjsockeserver.fujianinetworkbean.bean.BaseResponsBean;
import scj.jl.com.utillibrary.log.LogUtil;

/**
 * Created by jl on 2020/5/27.
 */

public class CustomizeGsonResponseBodyConverter<T> implements Converter<ResponseBody,T>{
   private static final  String TAG = CustomizeGsonResponseBodyConverter.class.getSimpleName();
    private final Gson gson;
    private final TypeAdapter<T> adapter;
    private BaseResponsBean baseResponsBean = null;
    CustomizeGsonResponseBodyConverter(Gson gson, TypeAdapter<T> adapter) {
        this.gson = gson;
        this.adapter = adapter;
    }
    @Override
    public T convert(ResponseBody value) throws IOException {
        String respones = value.string();//将json数据转化成字符串

//在这里处理需要处理的json数据
      //  BaseResponsBean bastR = gson.fromJson(respones,BaseResponsBean.class);

 

//        if (bastR.getCmdType().equals("07")){
//            String tempStr =  respones.replace("\\\"{","\"{");
//            String afterTempStr = tempStr.replace("}\\\"","}\"");
//            String strs = afterTempStr.replace("\\","");
//            String strs1 = strs.replace("\"{","{");
//            String strs2 = strs1.replace("}\"","}");
//            LogUtil.d(TAG,"strs2 = "+strs2);
//            baseResponsBean = gson.fromJson(strs2,BaseResponsBean.class);
//            return adapter.fromJson(respones);
//        }else {
            return adapter.fromJson(respones);
//        }

    }
}
最后修改我们封装的Retrofit,添加ConverterFactory的时候添加我们自定一个ConverterFactory。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

甜美冰景

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值