为什么要进行拦截请求参数?
retrofit作为最火的网络请求库,我们经常会用到它。在使用它时有时我们需要对请求参数进行拦截做一些统一的处理,如对请求参数进行拦截并进行签名计算,然后设置统一的header。这种情形怎么进行处理呢?当然最好是使用自定义拦截器了!
但是我们在拦截时,又需要区分get请求和post请求。post请求又有不同的请求方式。
1.retrofit进行get请求
@GET("message/getUnReadMessageList")
fun getUnReadMessageList(@Query("userId") userId: String): Observable<BaseResponse<ArrayList<MsgInfoBean>>>
如果拼接参数。如
userId=xxx
2.retrofit进行post请求发送json数据
@POST("user/ticket")
fun login1(
@Body body: RequestBody,
): Observable<BaseResponse<UserInfo>>
@POST("user/ticket")
fun login2(
@Body body: User,
): Observable<BaseResponse<UserInfo>>
这两种请求都会发送如下的数据格式到服务器:
{“username”: “xxx”, “password”:“xxx”}
3.retrofit进行post请求发送表单数据
@FormUrlEncoded
@POST("user/ticket")
fun login3(@Field("username") user: String, @Field("password") password: String) : Observable<BaseResponse<UserInfo>>
这种请求会发送如下的数据格式到服务器:
username=xxx&password=xxx
4.在拦截器里如何获取请求参数
都在代码里了:
public class HeaderInterceptor implements Interceptor {
@Override
public Response intercept(Chain chain) throws IOException {
Request request = chain.request();
Request.Builder requestBuilder = request.newBuilder();
//requestBuilder.addHeader("Content-Type", "application/json");
requestBuilder.addHeader("X-Co-Sign", signFn(request));
request = requestBuilder.build();
return chain.proceed(request);
}
/**
* 拦截请求参数并签名
*/
private String signFn(Request request) {
String signStr;
String type = request.method();
if (type.equals("GET") && request.url().encodedQuery() != null) {//获取get请求的参数
String encodedQuery = request.url().encodedQuery();
String[] querys = encodedQuery.split("&");
Map<String, String> queryMap = new HashMap<>();
for (String query : querys) {
String[] split = query.split("=");
queryMap.put(split[0], split[1]);
}
//获取get请求参数后可进行排序
List<Map.Entry<String, String>> entryList = new ArrayList<>(queryMap.entrySet());
Collections.sort(entryList, new Comparator<Map.Entry<String, String>>() {
@Override
public int compare(Map.Entry<String, String> o1, Map.Entry<String, String> o2) {
return o1.getKey().compareTo(o2.getKey());
}
});
/*省略签名计算*/
} else if (type.equals("POST")) {//获取POST请求的参数
String paramsStr = bodyToString(request);
/*省略签名计算*/
}
return signStr;
}
/**
* post 请求参数获取
*/
private String bodyToString(final Request request) {
final Request copy = request.newBuilder().build();
final Buffer buffer = new Buffer();
try {
copy.body().writeTo(buffer);
} catch (IOException e) {
return "something error,when show requestBody";
}
return buffer.readUtf8();
}
/**
* post 表单请求参数也可以这样获取
*/
private HashMap<String, String> bodyToString(final Request request) {
HashMap<String, String> map = new HashMap<>();
if (request.body() instanceof FormBody) {
FormBody body = (FormBody) request.body();
for (int i = 0; i < body.size(); i++) {
map.put(body.encodedName(i), body.encodedValue(i));
}
}
return map;
}
}
5.使用
OkHttpClient.Builder builder= new OkHttpClient.Builder();
...
builder.addInterceptor(new HeaderInterceptor())
...