Okhttp共通パラメータを設定し、jsonオブジェクトを@Body要求共通パラメータに入れる構成


ネットワーク要求が1つのURLに基づいている場合、すべてのインタフェースは同じアドレスであり、異なるインタフェースデータを要求する場合はcommandフィールドで構成され、すべての要求パラメータは自分でbeanクラスを書く必要があり、jsonフォーマットに変換してフォームform-bodyではなく要求bodyにバックグラウンドに送る必要があるため、sessionId、timestampなどの共通パラメータを構成するのは少し面倒である.各beanクラスにこれらのパラメータを追加するか、ベースクラスBaseRequestBeanを書いて、ベースクラスに共通パラメータを構成するのは解決策ですが、私はそうしたくないので、okhttp構成ブロッカーで共通パラメータを設定するしかありません.次のトピックに進みます.
ブロッキング構成ステップ1、ブロッキングCommonSignParamsInterceptorクラスはokhttp 3に継承する.Interceptorクラスは、親メソッドintercept 2を書き換え、private HashMap getCommanParams()メソッドをカスタマイズします.このメソッドでは、HashMapオブジェクトを介して共通パラメータ3をキー値ペアで設定し、interceptメソッドでリクエストボディを取得し、getCommanParamsメソッドを呼び出し、リクエストボディを再構成して送信します
共通パラメータがリクエストヘッダヘッダまたはform-bodyに配置されている場合、以下のように構成される可能性があります.
    @Override
    public Response intercept(@NonNull Chain chain) throws IOException {

        Response response;
        Request originRequest = chain.request();
        Request.Builder newRequest = originRequest.newBuilder();
        RequestBody body = originRequest.body();
        
        // , addHeader(key,value) 
        newRequest.addHeader("header-key",
               new JSONObject(getCommonParams()).toString());

        if (body == null) {
            body = EMPTY_BODY;
            newRequest.post(body);
        } else if(body instanceof FormBody){
            // form-body
            FormBody oldBody = (FormBody) body;
            FormBody.Builder newFormBodyBuilder = new FormBody.Builder();
            for (int i = 0; i < oldBody.size(); i++) {
                newFormBodyBuilder.add(oldBody.name(i), oldBody.value(i));
            }
            // 
            for (Map.Entry entry : getCommonParams().entrySet()) {
                newFormBodyBuilder.add(entry.getKey(), entry.getValue());
            }
            FormBody newFormBody = newFormBodyBuilder.build();
            newRequest.post(newFormBody);
        }
        response = chain.proceed(newRequest.build());

        return response;
    }

以上のコードから、要求ヘッダを共通パラメータとして追加するのが最も簡単で、newRequestを直接呼び出すことが分かった.addHeaderでいいし、フォームパラメータを追加するのも難しくないし、元の要求パラメータを簡単に取り出して新しいFormBodyに入れるだけです.Builderオブジェクトでいいです.もう1つのケースは,本稿のトピックで,要求体bodyのjsonオブジェクトに共通パラメータをどのように入れるかということである.
ソースを読むことで、okhttp 3.logging.HttpLoggingInterceptorは、headerなどの要求情報を含む要求内容をこのように印刷することを発見した.
      if (!logBody || !hasRequestBody) {
        logger.log("--> END " + request.method());
      } else if (bodyHasUnknownEncoding(request.headers())) {
        logger.log("--> END " + request.method() + " (encoded body omitted)");
      } else {
        Buffer buffer = new Buffer();
        requestBody.writeTo(buffer);

        Charset charset = UTF8;
        MediaType contentType = requestBody.contentType();
        if (contentType != null) {
          charset = contentType.charset(UTF8);
        }

        logger.log("");
        if (isPlaintext(buffer)) {
          logger.log(buffer.readString(charset));
          logger.log("--> END " + request.method()
              + " (" + requestBody.contentLength() + "-byte body)");
        } else {
          logger.log("--> END " + request.method() + " (binary "
              + requestBody.contentLength() + "-byte body omitted)");
        }
      }

以上のソースコードから、elseでは、requestBodyをwriteToメソッドでbufferに書き込み、bufferコンテンツを読み出します.これにより、元のリクエスト体とコンテンツを取り出してから、共通パラメータを修正して追加することができます.具体的な実装コードはソースコード方式と大同小異であり、コードは以下の通りである.
    @Override
    public Response intercept(@NonNull Chain chain) throws IOException {

        Response response;
        Request originRequest = chain.request();
        Request.Builder newRequest = originRequest.newBuilder();
        RequestBody body = originRequest.body();
        
        // , addHeader(key,value) 
        //newRequest.addHeader("header-key",
        //       new JSONObject(getCommonParams()).toString());

        if (body == null) {
            //------------
        } else if(body instanceof FormBody){
            // form-body
        } else if(body instanceof MultipartBody){
            //.......... 
        } else {
            Buffer buffer = new Buffer();
            body.writeTo(buffer);
            Charset charset = Charset.forName("UTF-8");
            MediaType contentType = body.contentType();
            if (contentType != null) {
               charset = contentType.charset(charset);
               if (charset != null) {
               // 
               String requestParams = buffer.readString(charset);
               try {
                   // 
                   JSONObject jsonObject = new JSONObject(requestParams);
                   for (Map.Entry entry : getCommonParams().entrySet()) {
                       jsonObject.put(entry.getKey(), entry.getValue());
                   }
                   RequestBody newBody = RequestBody.create(body.contentType(), jsonObject.toString());
                   newRequest.post(newBody);
                   } catch (JSONException e) {
                       e.printStackTrace();
                   }
               }
             }
        }
        response = chain.proceed(newRequest.build());

        return response;
    }

文が終わったら、よく勉強して、毎日向上します.