项目开发中有个需求,将所有接口的值都通过RSA加密传输,服务端返回的所有内容也都需要通过RSA解密后再使用。

参考这篇文章可以实现功能:https://blog.csdn.net/yuzhiqiang_1993/article/details/90168515

但是在实现功能之后,替换原有response的body之后,接口从onError返回,没有正确的解析成实体类,返回错误信息就如标题中所写。

因为retrofit在数据返回的时候,可能会对数据包进行压缩传输,到客户端在解密:

//读取服务器返回的结果
ResponseBody responseBody = response.newBuilder().build().body();
BufferedSource source = responseBody.source();
source.request(Long.MAX_VALUE); // Buffer the entire body.
Buffer buffer = source.buffer();
//获取content的压缩类型
String encoding = response.headers().get("Content-Encoding");
Charset charset = Charset.forName("UTF-8");
MediaType contentType = responseBody.contentType();
if (contentType != null) {
    charset = contentType.charset(charset);
}
Buffer clone = buffer.clone();
if (encoding != null && encoding.equalsIgnoreCase("gzip")) {//content 使用 gzip 压缩
  return ZipHelper.decompressForGzip(clone.readByteArray(), convertCharset(charset));//解压
} else if (encoding != null && encoding.equalsIgnoreCase("zlib")) {//content 使用 zlib 压缩
  return ZipHelper.decompressToStringForZlib(clone.readByteArray(),convertCharset(charset));//解压
 } else {//content 没有被压缩, 或者使用其他未知压缩方式
  return clone.readString(charset);
 }

而我们通过responseBody.creat()方法进行body创建的时候并没有做压缩操作(跟进去看看源码就知道),所以按照替换原有body的编码格式,就可能会出现格式与内容对应不上的情况

那么找到问题解决就简单了,只需要将格式重置一下就可以了

response.newBuilder().body(responseBody).addHeader("Content-Encoding","").build();

还有可能遇到一个问题,就是Json可以解析了,但是解析出来之后,汉字都变成???,其实原理也是一样的,我们直接修改response,原有的编码格式还在,但可能和我们设置的格式可能不同。

因为按照上篇博客所写的内容,我们在创建新的responseBody的时候,使用的和服务器返回一致的contentType,所以在创建responseBody的时候,不传contentType就行了,这样的编码格式就是默认的(UTF-8)

// newData 为解密后的字串
ResponseBody responseBody = ResponseBody.create(null, newData);

以上就是我遇到的问题以及解决办法。

--------

又遇到一个问题,我这边上传的所有中文在服务器那边乱码了,乱码格式为:URLEncode

原因是啥呢,retrofit在进行接口请求的时候,我们在接口注解上加了:@FormUrlEncoded

这个注解的意思是会将所有参数进行URLEncode编码,利于传输。

本来服务器也有配套的解码的,但在服务器框架对数据进行URLDecode的时候,由于我们对数据进行了RSA编码,URLDecode解码的过程虽然走了,但是没有生效(RSA格式和URLDecode不一样)。

所以服务器同事应该在解码之后再手动的进行一次URLDecode

写这个就是想说,问题并不在android这边,方便排查问题。

Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐