Okhttp Put 方法返回“不允许的方法”

Posted

技术标签:

【中文标题】Okhttp Put 方法返回“不允许的方法”【英文标题】:Okhttp Put method returning 'Method Not Allowed' 【发布时间】:2016-05-15 21:12:21 【问题描述】:

我正在尝试使用 android 应用程序中的 OkHttp 在我的服务器上调用 put 方法。

这是 api 方法签名:

public void Put(int userId, string regId)


这是调用上述方法的Android代码:

private boolean SendGCMRegIdToServer(String registrationId, Integer userId) throws IOException 
    HttpUrl url = new HttpUrl.Builder()
            .scheme("http")
            .host(serverApiHost)
            .addPathSegment("AppDashboard")
            .addPathSegment("api")
            .addPathSegment("GCM/")
            .build();

    MediaType JSON
            = MediaType.parse("application/json; charset=utf-8");

    String json = "'userId':" + userId + ","
            + "'regId':'" + registrationId + "'"
            + "";

    RequestBody requestBody = RequestBody.create(JSON, json);

    Request request = new Request.Builder()
            .url(url)
            .put(requestBody)
            .build();

    //this should post the data to my server
    Response response = client.newCall(request).execute();
    if(response.code() == 400)
        return false;

    return true;

现在的问题是我在响应中收到错误代码 405,说方法不允许,但我看不出问题出在哪里,因为我可以在服务器本身上使用 Postman 成功调用该方法,如下所示:

http://localhost/AppDashboard/api/GCM?userId=5&regId=123

我认为这可能与在 JSON 字符串中错误传递的整数或字符串有关,但不明白为什么这不起作用。

【问题讨论】:

你确定你也在邮递员中使用了 PUT 吗? 【参考方案1】:

我遇到了同样的问题,服务器返回 405 。经过一番搜索,我意识到这是 IIS 上的配置问题,它不允许 put 请求。所以android代码没有问题,你应该配置你的服务器来允许这种请求。 见this、this和this

【讨论】:

【参考方案2】:

好的,谢谢大家的回复,但我似乎对我用来将参数传递给我的 API 的两种方法感到有些困惑。

这是我所做的:

将方法的签名更改为使用参数 [FromBody] 作为模型发布(仅支持一个参数)...

public void Post([FromBody]UserGcmRegIdModel model)


然后我可以使用更好的 JSONBuilder 并在请求生成器中使用 .post 而不是 .put 将我的方法调用更改为以下内容

JSONObject jsonObject = new JSONObject();

    try 
        jsonObject.put("UserId", userId);
        jsonObject.put("RegId", registrationId);
     catch (JSONException e) 
        e.printStackTrace();
    

    String json = jsonObject.toString();

    RequestBody requestBody = RequestBody.create(JSON, json);

    Request request = new Request.Builder()
            .url(url)
            .post(requestBody)
            .build();

我仍然不知道 IIS 上的 put() 方法是否存在问题,但在我的情况下使用 post 绝对没问题,所以我将继续这样做......

【讨论】:

我已经更新了我的答案,因为您的问题也已更新。【参考方案3】:

我在您的 REST api 调用中看到了两种不同的方法。在 OkHttp 中,您发送一个带有序列化 JSON 对象的 PUT 方法,而在 POSTMAN 中,您使用 URL 中的参数发送一个 PUT(尽管我猜您是执行 GET)请求,我的意思不是在 JSON 正文结构中。

无论如何,HTTP 405 告诉您您的后端不支持 PUT 方法,并且可能是带有"X-HTTP-Method-Override:PUT" HTTP 标头的expecting a POST method,因为 POST 在 REST 中比 PUT 更标准。

我会做的是仔细检查您的 POSTMAN 请求,并将 Android 的一个调整为相同的方法、参数和标头,而不是更多。

答案更新(问题已更新)

当然,那个动词有问题,正如我在上面所说的,IIS 只处理标准方法,而 PUT 不是其中之一。你有三个选择:

    将 PUT 更改为 POST。 使用带有 X-HTTP-Method-Override 的 POST 来 PUT。 (reference) 修改 IIS 配置以支持非标准 REST 方法。一世 个人不会推荐第三个,因为它附在 后端配置(例如,假设您将 IIS 更改为 NancyFX)。

【讨论】:

那么有没有办法发送一个没有正文但带有 url 参数的 Okhttp put 请求...... 当然可以,但你为什么要这么做?我建议像所有人一样使用 JSON。但是,如果您想这样做并使用表单参数,请调整您的 MediaType 并执行以下操作:github.com/square/okhttp/wiki/Recipes#posting-form-parameters

以上是关于Okhttp Put 方法返回“不允许的方法”的主要内容,如果未能解决你的问题,请参考以下文章

错误 405:不允许的方法

Retrofit2 OkHttp3 响应正文空错误

GET Web API 方法返回不允许的方法

WCF 服务返回“方法不允许”

如何响应 Django 基于类的视图中不允许的方法

地理服务器返回 405:不允许的方法