【问题标题】:Retrofit not getting all header response改造未获得所有标头响应
【发布时间】:2021-03-17 04:58:06
【问题描述】:

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

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。 请求地址为: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);

【问题讨论】:

  • 贴一些相关代码
  • 编辑了问题。请让我知道这是否足够
  • 设置cookie:woocommerce_items_in_cart=0; expires=星期六,2020 年 12 月 5 日 08:47:09 GMT;最大年龄=0;路径=/设置cookie:woocommerce_cart_hash=0; expires=星期六,2020 年 12 月 5 日 08:47:09 GMT;最大年龄=0; path=/ 作为回应,我只将两个标题作为 "Set-Cookie" 。但是,如果我通过 POSTMAN 发出请求,我可以看到另外两个“Set-Cookie”标头
  • github.com/square/okhttp/tree/master/okhttp-logging-interceptor 你可以使用okhttp登录拦截器记录响应
  • 看起来这些标头可能与会话身份验证相关联,适用于浏览器登录交互,但不适用于应用请求。

标签: android wordpress retrofit okhttp woocommerce-rest-api


【解决方案1】:

在尝试了我在互联网上找到的所有内容后,最后我注意到没有发送授权承载令牌,因为我将 "Authentication" 作为标题名称而不是 "Authorization" 。我已经纠正了这一点,现在它工作得很好。但是任何想弄乱标题或cookie的人,这里有几种方法:

  • 为 cookie 使用 CookieJar
  • 对标头或 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;
    }
}

用于操作标头,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"

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-01-21
    • 2020-06-17
    • 1970-01-01
    • 1970-01-01
    • 2015-08-26
    • 1970-01-01
    • 1970-01-01
    • 2017-01-28
    相关资源
    最近更新 更多