【问题标题】:Okhttp Put method returning 'Method Not Allowed'Okhttp Put 方法返回“不允许的方法”
【发布时间】: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 吗?

标签: android asp.net-web-api okhttp http-status-code-405


【解决方案1】:

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

【讨论】:

    【解决方案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 不是其中之一。你有三个选择:

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

    【讨论】:

    • 那么有没有办法发送一个没有正文但带有 url 参数的 Okhttp put 请求......
    • 当然可以,但你为什么要这么做?我建议像所有人一样使用 JSON。但是,如果您想这样做并使用表单参数,请调整您的 MediaType 并执行以下操作:github.com/square/okhttp/wiki/Recipes#posting-form-parameters
    猜你喜欢
    • 1970-01-01
    • 2023-03-23
    • 2018-07-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多