retrofit2 发送 PUT 请求方法对于 PHP 来说是错误的


retrofit2 sending a PUT request method is wrong for PHP

我正在尝试将PUT请求方法从我的Android应用程序发送到我的PHP端点,但在我的端点中,PUT请求未被识别为PUT请求,所以我返回请求方法错误! 消息来自我的端点。

安卓界面和请求执行

激活接口

@PUT("device/activate.php")
Call<DeviceRegistry> registryDevice();

执行请求

DeviceRegistryAPI registryAPI =
            RetrofitController.getRetrofit().create(DeviceRegistryAPI.class);
Call<DeviceRegistry> registryCallback = registryAPI.registryDevice();
response = registryCallback.execute();

有了这个,我期待得到回应,但我收到我的端点错误消息。


我的 PHP 端点

if($_SERVER['REQUEST_METHOD'] == "PUT"){
   //doing something with the data
} else {
    $data = array("result" => 0, "message" => "Request method is wrong!");
}

我不知道为什么$_SERVER['REQUEST_METHOD'] == "PUT"是错误的,但我想知道我是否在改造 2 上遗漏了一些东西。


更多信息。

我正在使用改装2。


更新 1:将 json 发送到正文中

我正在尝试使用正文发送 json。

这是我的json:

{
    "number": 1,
    "infoList": [
        {
            "id": 1,
            "info": "something"
        },
        {
            "id": 2,
            "info": "something"
        }   
    ]
}

有我的课程:

class DataInfo{
    public int number;  
    public List<Info> infoList;
    public DataInfo(int number, List<Info> list){
        this.number = number;
        this.infoList = list;
    }
}

class Info{
    public int id;
    public String info;
}

我将 PUT 接口更改为:

@PUT("device/activate.php")
Call<DeviceRegistry> registryDevice(@Body DataInfo info);

但是我遇到了同样的问题。


更新2:我需要标头吗

我的 REstfull 客户端中有这个标头:

Accept: application/json
Content-Type: application/x-www-form-urlencoded

我需要把它放在我的请求配置中吗?如果需要,我该怎么做?

更新3:检查我的发送帖子的请求类型。

现在我正在检查请求的类型。因为我在 PUT/POST 请求方面遇到了同样的问题。所以如果可以用看跌期权解决问题,也许所有的问题都会得到解决。

当我执行请求并询问并检查请求时,它正在发送类型(PUT/POST),但在服务器中 php 仅检测或 GET??(下面的示例使用 POST,行为相同)

Call<UpdateResponse> requestCall = client.updateMedia(downloadItemList);
Log.i("CCC", requestCall .request().toString());

输出是一个开机自检:

Request{method=POST, url=http://myserver/api/v1/media/updateMedia.php, tag=null}

所以我正在向服务器发送一个 POST(无论我是否发送 PUT)请求,但为什么在服务器中我收到 GET。我被锁定了!!我不知道问题出在哪里。

更新4:干爹托管。

我在 godaddy 上托管了我的 php 服务器。这有什么问题吗?我创建了一个本地主机,一切正常,但相同的代码在 godaddy 上不起作用。我做了一些研究,但我没有找到这个问题的任何好答案,所以 godaddy 托管可能是问题所在吗?

PHP 除了 GET 和 POST 之外,无法识别任何其他内容。 服务器应该向你抛出某种错误,比如空请求。

要访问 PUT 和其他请求,请使用

$putfp = fopen('php://input', 'r'); //will be a JSON string (provided everything got sent)
$putdata = '';
while($data = fread($putfp, filesize('php://input')))
    $putdata .= $data;
fclose($putfp);
//php-like variable, if you want
$_PUT = json_decode($putdata);

没有测试,但应该可以工作。

我想

问题是你没有随请求一起传递任何数据PUT这就是为什么 PHP 将请求识别为GET。所以我认为你只需要尝试使用@FormUrlEncoded@Multipart或可能@Body注释传递一些数据

要在 retrofit2 中添加标头,您应该创建一个拦截器:

        Interceptor interceptor = new Interceptor() {
            @Override
            public okhttp3.Response intercept(Interceptor.Chain chain) throws IOException
            {
                okhttp3.Request.Builder ongoing = chain.request().newBuilder();
                ongoing.addHeader("Content-Type", "application/x-www-form-urlencoded");
                ongoing.addHeader("Accept", "application/json");
                return chain.proceed(ongoing.build());
            }
        };

并将其添加到客户端构建器:

        OkHttpClient.Builder builder = new OkHttpClient.Builder();
        builder.interceptors().add(interceptor);
  1. PHP 识别"PUT"调用。摘自 PHP.net:

"REQUEST_METHOD"使用哪种请求方法访问页面; 即"获取"、"头"、"发布"、"放置"。

  1. 如果您的服务器不期望任何标头,则无需发送任何标头页眉。

在使用 Retrofit 或任何其他网络库之前,您应该使用请求 http 构建器(如 Postman 或 Advanced Rest Client)检查端点。若要在运行应用或单元测试时调试请求/响应,请使用 Charles 等代理,这将对你观察请求/响应的真实外观有很大帮助。