なぜリクエストパラメータをインターセプトするのでしょうか?
Retrofit は、最も人気のあるネットワーク リクエスト ライブラリとして、弊社でもよく使用されています。これを使用する場合、リクエスト パラメーターをインターセプトして署名計算を実行し、統一ヘッダーを設定するなど、リクエスト パラメーターをインターセプトして統一処理を行う必要がある場合があります。この状況にどう対処すればよいでしょうか? もちろん、カスタム インターセプターを使用するのが最善です。
ただし、インターセプトするときは、get リクエストと post リクエストを区別する必要があります。投稿リクエストにはさまざまなリクエスト方法があります。
1. Retrofit が取得リクエストを行う
@GET("message/getUnReadMessageList")
fun getUnReadMessageList(@Query("userId") userId: String): Observable<BaseResponse<ArrayList<MsgInfoBean>>>
パラメータを結合する場合。
userId=xxxなど
2. Retrofit は 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 はフォーム データを送信するためのポスト リクエストを作成します
@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())
...