改造未获得所有 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"
当通过 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"