Retrofit 2 之自定义Converter实现加密解密

原创 2016年05月31日 21:29:47

版权声明:本文为博主原创文章,未经博主允许不得转载。

如果你还不知道,Retrofit2是什么,请你移步到hangyang的博客,认真看他写的 Retrofit2 完全解析 探索与okhttp之间的关系的这篇文章,他是现在我认为最全,也是最好的一篇,有关Retrofit2和OKhttp3的使用文档。

等你认真,领悟了,实践了,可能你就会产生下列的需求,Retrofit 2 之如何自定义Converter来实现数据的加密解密。

以下是我的个人实践,对Retrofit2我是才接触,不是很深,我只是记录我自己的工作笔记,希望你们看见的时候不要见笑。

项目使用的依赖包:

  //retrofit2
    compile 'com.squareup.retrofit2:retrofit:2.0.1'
    compile 'com.squareup.retrofit2:adapter-rxjava:2.0.1'
    compile 'com.squareup.retrofit2:converter-gson:2.0.1'
    compile 'com.google.code.gson:gson:2.6.2'
    //okhttp
    compile 'com.squareup.okhttp3:okhttp:3.2.0'
    compile 'com.squareup.okhttp3:logging-interceptor:3.2.0'
    //rxjava
    compile 'io.reactivex:rxjava:1.1.5'
    compile 'io.reactivex:rxandroid:1.2.0'     
                在build.gradle(Module.app)    dependencies {***}  中添加

1.构建Retrofit和okhttp客户端

   //配置okhttp3客户端
  OkHttpClient okHttpClient = new OkHttpClient.Builder()
                .addNetworkInterceptor(new HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BODY)).build();

//构建Retrofit
        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl("http://192.168.10.225:8080")  //.baseUrl  是设置连接的地址
                .client(okHttpClient)
                .addConverterFactory(GsonConverterFactory.create()) //添加Gson转换器
                .addCallAdapterFactory(RxJavaCallAdapterFactory.create()) // 添加Rxjava适配器 
                .build();

2.自定义转换器 JsonConverterFactory,新建响应与请求

/**
 * Created by zhang on 2016/5/31.
 * <p>
 * 自定义 json转换器
 */
public class JsonConverterFactory extends Converter.Factory {

                ………………
    @Override
    public Converter<ResponseBody, ?> responseBodyConverter(Type type, Annotation[] annotations,
                                                            Retrofit retrofit) {

        TypeAdapter<?> adapter = gson.getAdapter(TypeToken.get(type));
        return new JsonResponseBodyConverter<>(gson, adapter);  //响应
    }

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

        TypeAdapter<?> adapter = gson.getAdapter(TypeToken.get(type));
        return new JsonRequestBodyConverter<>(gson, adapter); //请求
    }


---------------------------------------------------------------------------------------

/**
 * Created by zhang on 2016/5/31.
 * <p>
 * 自定义请求RequestBody
 */
public class JsonRequestBodyConverter<T> implements Converter<T, RequestBody> {
                    ……………………
    @Override
    public RequestBody convert(T value) throws IOException {
        //加密
        APIBodyData data = new APIBodyData();   
        Log.i("xiaozhang", "request中传递的json数据:" + value.toString());
        data.setData(XXTEA.Encrypt(value.toString(), HttpConstant.KEY));
        String postBody = gson.toJson(data); //对象转化成json
        Log.i("xiaozhang", "转化后的数据:" + postBody);
        return RequestBody.create(MEDIA_TYPE, postBody);
        ###这里需要,特别注意的是,request是将T转换成json数据。你要在T转换成json之后再做加密。再将数据post给服务器,同时要注意,你的T到底指的那个对象
    }

}


-----------------------------------------------------------------------------------
/**
 * Created by zhang on 2016/5/31.
 * 自定义响应ResponseBody
 */
public class JsonResponseBodyConverter<T> implements Converter<ResponseBody, T> {
                      ……………………
    @Override
    public T convert(ResponseBody responseBody) throws IOException {

        String response=responseBody.string();

            String strResult = response.substring(1, response.length() - 1);
            String result = XXTEA.Decrypt(strResult, HttpConstant.KEY);//解密
            Log.i("xiaozhang", "解密的服务器数据:" + result);
            PageBean pageBean=mGson.fromJson(result,PageBean.class);
        return (T) pageBean;
   ###需要注意的是,response是将string转换成T,string需要先解密成json再转换成T,同样要注意你的T指代的谁。

    }

}

3.改GsonConverterFactory.create()为自定义的Converter:

     // .addConverterFactory(JsonConverterFactory.create())  自定义

这是我的效果图:

这里写图片描述

以下为全部代码:

api接口:

 @POST("api/SQBY/SQSJ/get_shequ_list")
    Observable<PageBean> getXiaoQuLiBiaoResulttwo(@QueryMap Map<String, String> urlPostFix, @Body String data);

Retrofit和okhttp客户端:

   //配置okhttp3客户端
  OkHttpClient okHttpClient = new OkHttpClient.Builder()
                .addNetworkInterceptor(new HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BODY)).build();

//构建Retrofit
        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl("http://192.168.10.225:8080")  //.baseUrl  是设置连接的地址
                .client(okHttpClient)
                .addConverterFactory(JsonConverterFactory.create())//添加自定义转换器
                .addCallAdapterFactory(RxJavaCallAdapterFactory.create()) // 添加Rxjava适配器 
                .build();

执行请求:

//传递的json数据
    JSONObject object = new JSONObject();
        try {
            object.put("opencode", "JNPKL3M438O");
            object.put("name", "");
            object.put("areaid", "");
            object.put("lng", 106.561581);
            object.put("lat", 29.564743);
            object.put("pageindex", "1");
            object.put("pagesize", "10");

        } catch (JSONException e) {
            e.printStackTrace();
        }
  //请求
    SelectPlotBizApi selectPlotBizApi= HttpHelper.createApi(SelectPlotBizApi.class);
     selectPlotBizApi.getXiaoQuLiBiaoResulttwo(HttpHelper.getUrlPostFix(), object.toString()) //后缀,json
      .subscribeOn(Schedulers.io())//执行在io线程
                .observeOn(AndroidSchedulers.mainThread())//主线程显示
                .subscribe(new Subscriber<PageBean>() {
                    @Override
                    public void onCompleted() {
                        Log.i("xiaozhang", "执行完成:");
                    }

            @Override
           public void onError(Throwable e) {
              Log.i("xiaozhang", "for执行失败:" + e);
           }

           @Override
           public void onNext(PageBean pageBean) {
              Log.i("xiaozhang", "线程中执行的,数据为" + pageBean.ResultJson);
            }
         });

自定义的Converter:


**
 * Created by zhang on 2016/5/31.
 * <p>
 * 自定义 json转换器
 */
public class JsonConverterFactory extends Converter.Factory {

    public static JsonConverterFactory create() {
        return create(new Gson());
    }

    public static JsonConverterFactory create(Gson gson) {
        return new JsonConverterFactory(gson);

    }

    private final Gson gson;

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


    @Override
    public Converter<ResponseBody, ?> responseBodyConverter(Type type, Annotation[] annotations,
                                                            Retrofit retrofit) {

        TypeAdapter<?> adapter = gson.getAdapter(TypeToken.get(type));
        return new JsonResponseBodyConverter<>(gson, adapter); //响应
    }

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

        TypeAdapter<?> adapter = gson.getAdapter(TypeToken.get(type));
        return new JsonRequestBodyConverter<>(gson, adapter); //请求
    }


}

_______________________________________________________________________________

/**
 * Created by zhang on 2016/5/31.
 * <p>
 * 自定义请求RequestBody
 */
public class JsonRequestBodyConverter<T> implements Converter<T, RequestBody> {
    private static final MediaType MEDIA_TYPE = MediaType.parse("application/json; charset=UTF-8");
    private final Gson gson;
    private final TypeAdapter<T> adapter;

    /**
     * 构造器
     */

    public JsonRequestBodyConverter(Gson gson, TypeAdapter<T> adapter) {
        this.gson = gson;
        this.adapter = adapter;
    }


    @Override
    public RequestBody convert(T value) throws IOException {
        //加密
        APIBodyData data = new APIBodyData();
        Log.i("xiaozhang", "request中传递的json数据:" + value.toString());
        data.setData(XXTEA.Encrypt(value.toString(), HttpConstant.KEY));
        String postBody = gson.toJson(data); //对象转化成json
        Log.i("xiaozhang", "转化后的数据:" + postBody);
        return RequestBody.create(MEDIA_TYPE, postBody);
    }

}

---------------------------------------------------------------------------------
**
 * Created by zhang on 2016/5/31.
 * 自定义响应ResponseBody
 */
public class JsonResponseBodyConverter<T> implements Converter<ResponseBody, T> {
    private final Gson mGson;//gson对象
    private final TypeAdapter<T> adapter;

    /**
     * 构造器
     */
    public JsonResponseBodyConverter(Gson gson, TypeAdapter<T> adapter) {
        this.mGson = gson;
        this.adapter = adapter;
    }

    /**
     * 转换
     *
     * @param responseBody
     * @return
     * @throws IOException
     */
    @Override
    public T convert(ResponseBody responseBody) throws IOException {

        String response = responseBody.string();

        String strResult = response.substring(1, response.length() - 1);
        String result = XXTEA.Decrypt(strResult, HttpConstant.KEY);//解密
        Log.i("xiaozhang", "解密的服务器数据:" + result);
        PageBean pageBean = mGson.fromJson(result, PageBean.class);
        return (T) pageBean;


    }

}

传递APIBodyData数据类:

public class APIBodyData {



    private String data;

    public String getData() {return data;}

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


}

版权声明:本文为博主原创文章,未经博主允许不得转载。

rxjava+retrofit请求加解密过程中的坑

学习rxjava和retrofit搭建demo时,用到了公司接口,由于公司的所有网络请求数据都有进行加密,这给搭建demo的过程中增加了一些困难,这里将学习以及一些走弯路的过程记录下来。 1、rxj...
  • a3100293282
  • a3100293282
  • 2017年03月22日 17:06
  • 1373

Retrofit 2 之自定义Converter实现加密解密

如果你还不知道,Retrofit2是什么,请你移步到hangyang的博客,认真看他写的 Retrofit2 完全解析 探索与okhttp之间的关系的这篇文章,他是现在我认为最全,也是最好的一篇,有关...
  • xiechengfa
  • xiechengfa
  • 2016年08月03日 10:34
  • 1345

Retrofit2封装之路(请求参数加密解密)(二)

Retrofit2 用例 public interface GitHubService { @GET("users/{user}/repos") Call> listRepos(@Path("...
  • majunm
  • majunm
  • 2017年07月13日 09:31
  • 1309

Retrofit对接口加解密

前两天因为短信验证码接口被人恶意调用,狂刷验证码账户里的钱,所以做了一次数据加密。网络请求使用的是Retrofit,解析工厂用的是GsonConverterFactory,依赖的是 compile ...
  • u014674558
  • u014674558
  • 2017年08月13日 10:16
  • 402

加密代理和Retrofit解密Converter

最近在研究安卓的Retrofit框架,服务器的数据全部用加密算法加密了,发现无法使用“com.squareup.retrofit2:converter-gson:2.1.0”Jar包了,所以要自己写这...
  • chen413203144
  • chen413203144
  • 2016年12月29日 00:41
  • 1754

Android网络请求使用Retrofit+OKHTTP,如何实现参数加密

项目中网络请求框架使用Retrofit+OKHTTP,如果需要进行参数加密呢?第一想法就是通过拦截器实现,Retrofit及OKHTTP都支持拦截器,但是拦截器却没有提供获取请求参数内容的方法,实现起...
  • lml0710
  • lml0710
  • 2015年12月17日 21:10
  • 4333

使用Retrofit搭建自己的网络请求框架

使用Retrofit搭建自己的网络请求框架本文是利用Android Studio,基于Retrofit2.0.0-beta2来搭建的网络请求框架。 尊重原创,转载请注明出处...
  • Jin_HeZai
  • Jin_HeZai
  • 2016年01月05日 15:20
  • 1482

retrofit 自定义请求参数加密 和自定义响应解密 带你走出那些坑

首先,感谢一叶飘舟。给我灵感。 以及他分享的博文,从源码的角度来实现参数的加解密。 其次,也感谢这位这篇文章 :http://blog.csdn.net/zr940326/article/deta...
  • baidu_35255405
  • baidu_35255405
  • 2017年06月15日 11:36
  • 1579

【腾讯Bugly干货】深入浅出 Retrofit,这么牛逼的框架你们还不来看看?

Android 开发中,从原生的 HttpUrlConnection 到经典的 Apache 的 HttpClient,再到对前面这些网络基础框架的封装,比如 Volley、Async Http Cl...
  • Tencent_Bugly
  • Tencent_Bugly
  • 2016年06月03日 17:33
  • 12704

Retrofit2.0的Converter使用

在Retrofit中, 不管是发送数据或是接收数据, 最基本都是通过OKHttp的RequestBody和ResponseBody来实现,但是通常为了方便,我们在定制协议的时候,不会直接使用原始的Re...
  • zoudifei
  • zoudifei
  • 2016年02月29日 19:33
  • 2975
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Retrofit 2 之自定义Converter实现加密解密
举报原因:
原因补充:

(最多只允许输入30个字)