retrofit 自定义请求参数加密 和自定义响应解密 带你走出那些坑
来源:互联网 发布:cimatrone11编程教程 编辑:程序博客网 时间:2024/06/07 10:36
首先,感谢一叶飘舟。给我灵感。
以及他分享的博文,从源码的角度来实现参数的加解密。
其次,也感谢这位这篇文章 :http://blog.csdn.net/zr940326/article/details/51549310
技术性人员就是不喜欢多啰嗦,直接来看代码吧。
首先要了解这个东西 -------- ConverterFactory。
这是retrofit 里面一个比较重要的类,他管理着request 和response ,要想实现自己需求的请求和参数,他是两者的桥梁。
(PS:retrofit 的封装是一门艺术,这里就不多讲了,基本的配置以及结合RX来实现 的文章已经很多了,自己去好好看看)
好的,接下来我们看下 Converter工厂的源码,直接从as 贴了
public interface Converter<F, T> { T convert(F var1) throws IOException; public abstract static class Factory { public Factory() { } public Converter<ResponseBody, ?> responseBodyConverter(Type type, Annotation[] annotations, Retrofit retrofit) { return null; } public Converter<?, RequestBody> requestBodyConverter(Type type, Annotation[] parameterAnnotations, Annotation[] methodAnnotations, Retrofit retrofit) { return null; } public Converter<?, String> stringConverter(Type type, Annotation[] annotations, Retrofit retrofit) { return null; } }}
三部分组成:请求 、响应、StringConverter
我们再来看看retrofit 给我提供的Converter
public final class GsonConverterFactory extends Factory { private final Gson gson; public static GsonConverterFactory create() { return create(new Gson()); } public static GsonConverterFactory create(Gson gson) { return new GsonConverterFactory(gson); } private GsonConverterFactory(Gson gson) { if(gson == null) { throw new NullPointerException("gson == null"); } else { this.gson = gson; } } public Converter<ResponseBody, ?> responseBodyConverter(Type type, Annotation[] annotations, Retrofit retrofit) { TypeAdapter adapter = this.gson.getAdapter(TypeToken.get(type)); return new GsonResponseBodyConverter(this.gson, adapter); } public Converter<?, RequestBody> requestBodyConverter(Type type, Annotation[] parameterAnnotations, Annotation[] methodAnnotations, Retrofit retrofit) { TypeAdapter adapter = this.gson.getAdapter(TypeToken.get(type)); return new GsonRequestBodyConverter(this.gson, adapter); }}好,就此我们了解到, 我们需要在request 和response 上来做文章了
这里要注意,看一下request和response 方法返回的是什么,是的返回了对应的converter。这两个的源码自己点进去看吧。
下面贴一下自己的requestconverter
public class MyRequestConverter<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 MyRequestConverter(Gson gson, TypeAdapter<T> adapter) { this.gson = gson; this.adapter = adapter; } @Override public RequestBody convert(T value) throws IOException { Log.e("数据", "转换前:" + value.toString()); Log.e("数据", "转化后:" + Base64_Utils.encryptBASE64(value.toString())); return RequestBody.create(MEDIA_TYPE, Base64_Utils.encryptBASE64(value.toString()).substring(0,Base64_Utils.encryptBASE64(value.toString()).length()-3)); }}
我这里简单的urlencode +base64加密。实际中根据需求来,注释已经写的很详细了。
下面贴一下封装的ServiceFactory
public class ServiceFactory { private final Gson gson; private ServiceFactory(){ gson = new GsonBuilder() .setDateFormat("yyyy-MM-dd hh:mm:ss") .create(); } private static class SingleHolder{ private static final ServiceFactory INSTANCE = new ServiceFactory(); } public static ServiceFactory getInstacne(){ return SingleHolder.INSTANCE; } //create a service public <S> S createService(Class<S> serviceClass) { String baseUrl = ""; try { Field field1 = serviceClass.getField("BASE_URL"); baseUrl = (String) field1.get(serviceClass); } catch (NoSuchFieldException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.getMessage(); e.printStackTrace(); } Retrofit retrofit = new Retrofit.Builder() .baseUrl(baseUrl) .client(getOkHttpClient()) .addConverterFactory(MyConverterFactory.create()) .addCallAdapterFactory(RxJavaCallAdapterFactory.create()) .build(); return retrofit.create(serviceClass); } private final static long DEFAULT_TIMEOUT = 10; private OkHttpClient getOkHttpClient() { //定制OkHttp OkHttpClient.Builder httpClientBuilder = new OkHttpClient.Builder(); //设置超时时间 httpClientBuilder.connectTimeout(DEFAULT_TIMEOUT, TimeUnit.SECONDS); httpClientBuilder.writeTimeout(DEFAULT_TIMEOUT, TimeUnit.SECONDS); httpClientBuilder.readTimeout(DEFAULT_TIMEOUT, TimeUnit.SECONDS); httpClientBuilder.addInterceptor(new Interceptor() { @Override public Response intercept(Chain chain) throws IOException { Request request = chain.request(); Request.Builder builder1 = request.newBuilder(); Request build = builder1.addHeader("USER-AGENT", clientType + "," + deviceId + "," + mobileBrand + "," + phoneModel + "," + systemName_versionNumber + "," + APP_versionNumber + "," + SDK_versionNumber + "," + pushNumber + "," + networkType + "," + APP_internalVersionNumber + "," + applicationMarketName + "," + screenResolution + "," + API_interfaceVersionNumber). build(); return chain.proceed(build); } }); //设置缓存// File httpCacheDirectory = new File(FileUtils.getCacheDir(SolidApplication.getInstance()), "OkHttpCache");// httpClientBuilder.cache(new Cache(httpCacheDirectory, 10 * 1024 * 1024)); return httpClientBuilder.build(); }
使用自定义的converter 要在retrofit 中添加自己的converter即可。
下面看一下接口API
@POST("/index/index/sms_code")Observable<BaseResopnse> sms_code(@Body String data);
接下来我们看实际的调用。
JSONObject jsonObject = new JSONObject();try { jsonObject.put("phone","15888810472"); jsonObject.put("check",1);} catch (JSONException e) { e.printStackTrace();}ServiceFactory.getInstacne() .createService(UserInfoService.class) .sms_code(jsonObject.toString()) .observeOn(AndroidSchedulers.mainThread()) .subscribeOn(Schedulers.io()) .subscribe(new ResultSubcriber() { @Override public void onSuccess(String str) { Toast.makeText(getActivity(),"成功"+str,Toast.LENGTH_LONG).show(); } @Override public void _onError(Throwable e) { Toast.makeText(getActivity(),"失败----"+e,Toast.LENGTH_LONG).show(); } });好了,这样就实现类请求数据响应数据的加解密。
注意这么几点:
1,参数要使用@Body这种形式,否则 request 方法会不执行。
2,请求和响应的操作在响应的Converter里做处理。
3,搭建request 和response 的桥梁。
4,添加桥梁依赖
阅读全文
0 0
- retrofit 自定义请求参数加密 和自定义响应解密 带你走出那些坑
- Retrofit 2 之自定义Converter实现加密解密
- Retrofit 2 之自定义Converter实现加密解密
- iOS framework制作 带你走出那些坑
- Retrofit添加公共请求参数以及添加自定义的ConverterFactory
- 安卓Retrofit post请求 带参数
- 字符串自定义加密解密 方法
- Tomcat自定义classLoader加密解密
- php 自定义加密、解密方法
- 加密代理和Retrofit解密Converter
- iOS 自定义加密解密——解密
- 自定义类加载器(实现加密和解密)
- UEditor自定义请求参数
- 自定义事件(自定义参数,带参数实现)
- Ajax中自定义发送请求和处理响应对象
- c# 加密 解密函数, 加密 解密 算法,自定义密钥
- Retrofit自定义Converter,获取原始请求数据,实现自定义解析
- 自定义Toolbar样式,带你出坑
- jquery二级联动下拉菜单
- 花生壳+IIS部署外网项目
- 面试题4:替换空格
- HTTP、FTP状态码 汇总
- iOS-手把手教你如何写block
- retrofit 自定义请求参数加密 和自定义响应解密 带你走出那些坑
- int和Integer的区别
- 02_核心概念--08_现代工具箱中的拖放
- PHP session 跨子域问题总结
- IOS内购验证
- Qwidget剪贴板的使用
- PuTTY (4) SSH
- CentOS下配置完全分布Hadoop-2.6.0-cdh5.6.0(2)
- UML设计9种设计图