开发中有没有遇到类似的情况:
1,服务器大佬在数据请求成功的时候返回的数据和请求失败的时候返回的数据不一致,并且无法有效沟通,他甚至想打你,如下:
这是成功的数据
{
"code":200,
"msg":"OK",
"data":{}
}
这是失败的数据
{
"code":201,
"msg":"OK",
"data":[]
}
2,服务器大佬要求所有的参数进行md5加密,当然可以写个工具类对每个接口都进行加密,但是如果有一天不加密了呢,那就要该很多地方,写法很low啊.
....
还有很多用到的情况,就不多说,下面看着俩种情况怎们处理
一,处理数据结构不一致问题
首先就看上面的简单的数据结构,一般情况我们都会对接口请求返回的数据结构进行封装,如上的data我们请求成功的时候用拿到的是一个大括号(对象),而请求出错的时候我们拿到的是一个中括号(对象集合),这样我们封装的就冲突了,下面是处理办法:
@Override
public Response intercept(Chain chain) throws IOException {
Request request = chain.request();
Response response = chain.proceed(request);
if (response.code() == 200) {
ResponseBody body = response.body();
BufferedSource source = body.source();
source.request(Long.MAX_VALUE); // Buffer the entire body.
Buffer buffer = source.buffer();
String string = buffer.clone().readString(Charset.forName("UTF-8"));
try {
JSONObject jsonObject = new JSONObject(string);
int code = jsonObject.getInt("code");
if (code == ErroCode.OVERPAY) {
Response response2 = toOverpay(jsonObject, response);
return response2;
} else if (code == ErroCode.FAIL) {
---------------------------------------------------------------------------------------
jsonObject.put("data", new Object());
-------------------------------------------------------------------------------------------
String string1 = jsonObject.toString();
Buffer buffer1 = response.body().source().buffer();
buffer1.clear();
buffer1.writeString(string1, Charset.forName("UTF-8"));
}
return response;
} catch (JSONException e) {
e.printStackTrace();
}
return response;
}
return response;
}
其他的地方不用管了,那是一些其他的相关逻辑,如果只处理上面那俩个简单的数据结构,看虚线中间的哪一行就可以了,就是这么简单.
二,参数加密
加密有很多加密的算法,只拿我某个项目中的md5来举个例子吧,直接看代码
public class Md5Interceptor implements Interceptor {
@Override
public Response intercept(Chain chain) throws IOException {
Request request = chain.request();
Response response = null;
String method = request.method();
switch (method) {
case "POST":
response = postMd5(chain, request);
break;
case "GET":
response = getMd5(chain, request);
break;
}
return response;
}
/**
* get请求url参数加密
*
* @param chain
* @param request
* @return
*/
private Response getMd5(Chain chain, Request request) throws IOException {
Response response;//url
String actionUrl = null;
HttpUrl url = request.url();
Set<String> set = url.queryParameterNames();
Map<String, String> map = new HashMap<>();
for (String name : set) {
if (name.equals("service")) {
actionUrl =url.queryParameter(name);
}
else if (!name.equals("s")) {
map.put(name, url.queryParameter(name));
}
}
StringBuilder tempParams = new StringBuilder();
int pos = 0;
for (String key : map.keySet()) {
if (pos > 0) {
tempParams.append("&");
}
tempParams.append(String.format("%s=%s", key, URLEncoder.encode(map.get(key), "utf-8")));
pos++;
}
final String requestUrl = String.format("%s%s&%s", Api.baseUrl, actionUrl, tempParams.toString()) + Md5Utils.md5Encryption(actionUrl, map);
final Request request1 = new Request.Builder().url(requestUrl).build();
response = chain.proceed(request1);
return response;
}
/**
* post请求url参数加密
*
* @param chain
* @param request
* @return
* @throws IOException
*/
private Response postMd5(Chain chain, Request request) throws IOException {
Response response;//url
String actionUrl = null;
FormBody body = (FormBody) request.body();
FormBody.Builder builder = new FormBody.Builder();
Map<String, String> map = new HashMap<>();
for (int i = 0; i < body.size(); i++) {
if (body.name(i).equals("service")) {
actionUrl = body.value(i);
} else {
builder.add(body.name(i), body.value(i));
map.put(body.name(i), body.value(i));
}
}
RequestBody formBody = builder.build();
final String requestUrl = String.format("%s%s", Api.baseUrl, actionUrl) + Md5Utils.md5Encryption(actionUrl, map);
final Request request1 = new Request.Builder().url(requestUrl).post(formBody).build();
response = chain.proceed(request1);
return response;
}
}
这个是某个简单的拦截器,就是根据get 或者 post 把每个参数取出来进行加密,然后再重新放到response中,加密规则就不说了,每个项目都不一样.只需注意一下怎们取参数即可.
所以说拦截器是个很牛x的机制,凡是涉及到网络层面的东西,大部分可以用拦截器去解决,如果有道了什么接口请求方面的问题,不妨想想拦截器.