Getting Header from Response (Retrofit / OkHttp Client)
我正在使用OkHttp Client和Jackson进行Retrofit进行Json序列化,并想获取响应的标头。
我知道我可以扩展OkClient
并拦截它。但这是在反序列化过程开始之前。
我基本上需要的是将标头与反序列化的Json Object一起获得。
在Retrofit 1.9.0中,如果您使用接口的回调异步版本,
1 2 | @GET("/user") void getUser(Callback<User> callback) |
然后您的回调将收到一个
1 2 3 4 5 6 7 8 9 10 11 | Callback<User> user = new Callback<User>() { @Override public void success(User user, Response response) { } @Override public void failure(RetrofitError error) { } } |
哪个方法称为
1 2 3 4 5 6 7 8 | Callback<User> user = new Callback<User>() { @Override public void success(User user, Response response) { List<Header> headerList = response.getHeaders(); for(Header header : headerList) { Log.d(TAG, header.getName() +"" + header.getValue()); } } |
对于Retrofit 2.0的界面,您可以使用
要获得Retrofit 2.0的Rx支持,可以使用
在Retrofit 2.0.0中,您可以获取如下标题:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | public interface Api { @GET("user") Call<User> getUser(); } Call<User> call = api.getUser(); call.enqueue(new Callback<User>() { @Override public void onResponse(Call<User> call, Response<User> response) { // get headers Headers headers = response.headers(); // get header value String cookie = response.headers().get("Set-Cookie"); // TODO } @Override public void onFailure(Call<User> call, Throwable t) { // TODO } }); |
就像您一样,我希望将标题放置在有效负载的旁边。我需要访问Etag。它需要一些retro-foo,但是您可以做到。这就是我所做的。这是一个肮脏的示例,因此不要将此作为最佳实践示例。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 | public static RestAdapter.Builder getRestBuilder(Context context) { GsonBuilder gsonBuilder = GsonBuilderUtils.getBuilder(); Gson gson = gsonBuilder.create(); // ** // 1. create our own custom deserializer here // ** final MyGsonConverter gsonConverter = new MyGsonConverter(gson); OkHttpClient httpClient = MyPersonalOkHttpFactory.getInstance().getAuthHttpClient(context); httpClient.networkInterceptors().add(new Interceptor() { @Override public Response intercept(Chain chain) throws IOException { Request originalRequest = chain.request(); Response response = chain.proceed(originalRequest); // ** // 2. add the headers from the Interceptor to our deserializer instance // ** gsonConverter.headers = response.headers(); return response; } }); RestAdapter.Builder builder = new RestAdapter.Builder() .setClient(new OkClient(httpClient)) .setEndpoint(Common.getApiOriginUrl()) .setConverter(gsonConverter); return builder; } private static class MyGsonConverter extends GsonConverter { private Headers headers; public MyGsonConverter(Gson gson) { super(gson); } @Override public Object fromBody(TypedInput body, Type type) throws ConversionException { Object obj = super.fromBody(body, type); // ** // 3. at this point, gson is called and you have access to headers // do whatever you want here. I just set it on the return object. // ** if (obj instanceof HeadersArrayList) { ((HeadersArrayList)obj).setHeaders(headers); } return obj; } } public class HeadersArrayList<K> extends ArrayList<K>{ private Headers headers; public Headers getHeaders() { return headers; } public void setHeaders(Headers headers) { this.headers = headers; } } // the retrofit api for reference @GET("/api/of/my/backend/{stuff}") HeadersArrayList<String> getSomething(@Path("stuff") String stuff); |
首先打印整个响应,正文,代码,消息,标头(通过日志记录或其他方式),然后尝试从中查找线索。
我建议您阅读API文档,并查看请求的类型。
使用邮递员检查以下哪一项有效:
1.表格数据
2.x-www-form-Urlencoded
3.原始
4.binary
然后相应地在接口的方法声明中设置注释。
例如:在我的情况下,它采用x-www-form-Urlencoded,因此我不得不使用
提及它
@FormUrlEncoded
@Headers("内容类型:应用程序/ x-www-form-urlencoded")
在方法声明中。
然后将@Field注释用于我发送的单个值
像
Call <'ReturnObj'> Signup(@Field(" name")字符串名称,@Field(" phoneNumber")长phoneNumber,@Field(" password")字符串密码,@Field(" counter")int计数器);