改造未获得所有 header 响应

Retrofit not getting all header response

当通过 Postman 发送请求时,我可以看到它正在发送所有 Set-Cookie 作为响应 header。示例:

Set-Cookie : wfwaf-authcookie-b52dd4381520%...... expires=Fri, 04-Dec-2020 23:32:21 GMT; Max-Age=43200; path=/; secure; HttpOnly
Set-Cookie : woocommerce_items_in_cart=1; path=/
Set-Cookie : woocommerce_cart_hash=92e2c.......; path=/
Set-Cookie : wp_cocart_session_a9339f....; expires=Fri, 11-Dec-2020 11:32:21 GMT; Max-Age=604800; path=/; secure; HttpOnly

但是在 Retrofit 中我只得到了其中的 2 个。不是全部 4。 请求 url 是:https://mywpwebsite.com/wp-json/wc/store/cart

我调用改造请求的代码:

public MutableLiveData<Resource<Cart> > getCartItems(HashMap<String,String> attribs, HashMap<String,String> headers) {

    Log.d(TAG, "get cart items: being called");

    final MutableLiveData cartitems = new MutableLiveData<>();

    WCService service = getRetrofitInstance().create(WCService.class);
    Call<Cart> call = service.getCartItems(attribs,headers);



    call.enqueue(new Callback<Cart>() {
        @Override
        public void onResponse(Call<Cart> call, Response<Cart> response) {
            Log.d(TAG,"fetched cartitems");
            Log.d(TAG,"responsecode:"+response.code());

            Log.d(TAG, "onResponse: headers:  "+response.headers().toString());

            Log.d(TAG, "onResponse: cookie : " + response.headers().toMultimap() .get("Set-Cookie").toString());

            if (response.code() == 200) {
                if (response.body() != null)
                    cartitems.setValue(WCRepository.Resource.success(response.body()));
                else
                    cartitems.setValue(WCRepository.Resource.error("Something went wrong, please refresh", null));
            } else {
                try {
                    errorResponse er = new Gson().fromJson(response.errorBody().string(), errorResponse.class);

                    cartitems.setValue(WCRepository.Resource.error(er.getMessage(), er.getMessage()));

                } catch (Exception e) {
                    cartitems.setValue(WCRepository.Resource.error("error: "+ e.getMessage(), null));

                }
            }
        }


        @Override
        public void onFailure(Call<Cart> call, Throwable t) {

            cartitems.setValue(null);
            Log.d(TAG, "onFailure: "+t.getMessage());
        }


    });

    return cartitems;
}

    @GET("store/cart?")
Call<Cart> getCartItems(@QueryMap() Map<String,String> params, @HeaderMap() Map<String,String> headers);

在尝试了我在互联网上找到的所有方法后,我终于注意到授权不记名令牌没有被发送,因为我将“Authentication”写为 header 名称而不是“Authorization”。我已经更正了它,它现在工作得很好。但是任何想要摆弄 headers 或 cookie 的人,这里有几种方法:

  • 将 CookieJar 用于 cookie
  • 对 header 或 cookie
  • 使用网络拦截器

Cookiejar 示例:

         final HashMap<String, List<Cookie>> cookieStore = new HashMap<>();

    CookieJar cookiejar = new CookieJar() {
        @Override
        public void saveFromResponse(@NotNull HttpUrl httpUrl, @NotNull List<Cookie> list) {

            Log.d(TAG, "saveFromResponse: "+ cookie.name() +":"+ cookie.value());

            cookieStore.put(httpUrl.host(), list);

        }

        @NotNull
        @Override
        public List<Cookie> loadForRequest(@NotNull HttpUrl httpUrl) {
            List<Cookie> cookies = cookieStore.get(httpUrl.host());
            return cookies != null ? cookies : new ArrayList<Cookie>();
        }
    };

OkHttpClient client ;
    OkHttpClient.Builder builder = new OkHttpClient.Builder();
    builder.cookieJar(cookiejar);
    client = builder.build();

HttpLoggingInterceptor 示例:

 HttpLoggingInterceptor logging = new HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger() {
        @Override
        public void log(@NotNull String s) {
            Log.d("logevent", s); // this will run in loop until finishes reading all headers
        }
    }).setLevel(HttpLoggingInterceptor.Level.HEADERS);

    
    OkHttpClient client ;
    OkHttpClient.Builder builder = new OkHttpClient.Builder();
    builder.addNetworkInterceptor(logging);
    client = builder.build();

读取 headers , ReceivedCookiesInterceptor 示例:

import android.content.Context;

import android.util.Log;

import java.io.IOException;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import okhttp3.Headers;
import okhttp3.Interceptor;
import okhttp3.Response;



public class ReceivedCookiesInterceptor implements Interceptor {
    private Context context;
    public ReceivedCookiesInterceptor(Context context) {
        this.context = context;
    } 

    @Override
    public Response intercept(Chain chain) throws IOException {
        Response originalResponse = chain.proceed(chain.request());

        //cookie headers only
        if (!originalResponse.headers("Set-Cookie").isEmpty()) {

            for (String header : originalResponse.headers("Set-Cookie")) {
                Log.d(TAG, "cookie: "+header);
            }


        }

         //for any other headers
         Map m = originalResponse.headers().toMultimap();

        Iterator it = m.entrySet().iterator();
        while (it.hasNext()) {
            Map.Entry pair = (Map.Entry)it.next();
            Log.d(TAG, "intercept: "+pair.getKey() + " = " + pair.getValue());
            it.remove(); 
        }


        return originalResponse;
    }
}

用于操作 headers,AddCookiesInterceptor :

import android.content.Context;
import android.util.Log;
import java.io.IOException;
import java.util.HashSet;
import okhttp3.Interceptor;
import okhttp3.Request;
import okhttp3.Response;

public class AddCookiesInterceptor implements Interceptor {


    public AddCookiesInterceptor(Context context) {
        this.context = context;
    }

    @Override
    public Response intercept(Interceptor.Chain chain) throws IOException {
        Request.Builder builder = chain.request().newBuilder();

        

//for adding headers:
builder.addHeader("key", "value");
       
//for replacing headers:
builder.header("key", "value"); 



        return chain.proceed(builder.build());
    }
}

然后像以前一样将它们添加为拦截器。您可能需要将这些添加到您的依赖项中:

implementation("com.squareup.okhttp3:logging-interceptor:4.9.0")
implementation "com.squareup.okhttp3:okhttp-urlconnection:3.6.0"