我试图在实际下载内容之前检查来自通过Retrofit 2.0.2进行的API调用的响应标头。
我的API界面如下所示:
@Headers({"Accept: application/json", "Origin: http://www.example.com"})
@HEAD("profiles")
Call<Void> getProfileHeaders(@Field("puids") String puid);
请注意,API调用要求我在正文中指定一个名为puids=%{UUID}
UUID列表的字段,以便返回响应。
如果我想在不先检查标题的情况下下载数据,我只需要调用这样的界面:
@Headers({"Accept: application/json", "Origin: http://www.example.com"})
@FormUrlEncoded
@POST("profiles")
Call<String> getProfile(@Field("puids") String puid);
现在的问题是,当我尝试使用getProfileHeader()
端点时,我得到以下RuntimeException:
java.lang.IllegalArgumentException: @Field parameters can only be used with form encoding. (parameter #1)
为了使用@Field参数(因为我认为POST方法通常会在需要时执行),我必须明确指定我使用@FormUrlEncoded
,但我不能使用{{ 1}}跟那个打电话。
我有点困惑,我怎么能实现我想要的东西以及我缺少什么?
基本上我想知道如何在下载需要字段参数的API端点的实际主体之前检查改装调用的响应标头?
干杯!
答案 0 :(得分:1)
改造使用的Okhttp有拦截器,可以让你动态修改或检查请求。查看github documentation
答案 1 :(得分:1)
好吧,我刚才意识到我的困惑源于一些误解:
@HEAD
是一种HTTP方法,通常用于验证超链接的有效性以及服务器对GET
调用的响应。它不适用于POST
请求,理论上不正确。 取自HTTP / 1.1定义的RFC2616
:
HEAD方法与GET相同,只是服务器不能 在响应中返回一个消息体。元信息包含 在HTTP头中响应HEAD请求应该是相同的 响应GET请求发送的信息。这种方法可以 用于获取有关该隐含的实体的元信息 请求而不转移实体主体本身。这个方法是 经常用于测试超文本链接的有效性,可访问性, 和最近的修改。
对HEAD请求的响应可能是可缓存的 响应中包含的信息可用于更新a 以前从该资源缓存的实体。如果是新字段值 表示缓存的实体与当前实体不同(如 将通过内容长度,内容-MD5,ETag或更改来表示 Last-Modified),然后缓存必须将缓存条目视为陈旧。
POST
请求时,我们已经计算了响应服务器端并花时间下载了正文。 POST
中定义的RFC2616
方法的一个功能是:
- 向数据处理流程提供数据块,例如提交表单的结果;
因此,为了不下载身体而验证标题是为了达到这个目的。
如上面的@Radek所述,使用GET
请求上的拦截器来动态修改和/或检查请求可以完成工作,但此时我们也可以发起HEAD
方法请求
此问题的解决方案是通过在服务器端进行更改而不是将原始数据块作为POST响应更好地与RFC2616
中定义的标准定义保持一致,使其成为可能返回一个将在GET
/ HEAD
请求中调用的资源。所有这些只是重构服务调用以使用GET
而不是POST
。