android okhttp不在post请求上发送标题

fumotvh3  于 2022-12-21  发布在  Android
关注(0)|答案(1)|浏览(125)

我尝试使用okhttp向MongoDB发送一个简单的post请求。下面是我使用的代码:

try {
                String jsonStr = om.writeValueAsString(postRequest);
                RequestBody body = RequestBody.create(
                        jsonStr, MediaType.parse("application/json; charset=utf-8"));
                // also attempted with MediaType.parse("application/json")

                Request request = new Request.Builder()
                        .url(insertUrl)
                        .addHeader("api-key", mongoDbApiKey)
                        // I have tried following ways to add content-type
                        // .addHeader("Content-Type", "application/json")
                        .addHeader("content-type", "application/json")
                        .post(body)
                        .build();

                String req = request.toString();

                OkHttpClient.Builder builder = new OkHttpClient.Builder();
                builder.addInterceptor(new CurlInterceptor(
                        new Logger() {
                            @Override
                            public void log(@NonNull String s) {
                                Log.v("OK2Curl", s);
                                // I copied this curl request to postman and it works from postman but for some reason does not work when run from my Android App.
                            }
                        }
                ));
                
               OkHttpClient client = builder.build();

                client.newCall(request).enqueue(new Callback() {
                    @Override public void onFailure(Call call, IOException e) {
                        e.printStackTrace();
                        Toast.makeText(getActivity(), "Unable to save the data.",
                                Toast.LENGTH_SHORT).show();
                    }

                    @Override public void onResponse(Call call, Response response) throws IOException {
                        String respString = response.body().string();
                        // respString => "Header missing: please add content-type: application/json or application/ejson to specify payload data types"
                        if(response.isSuccessful()){
                            Toast.makeText(getActivity(), "Data is saved.",
                                    Toast.LENGTH_SHORT).show();
                        }
                        else {
                            Toast.makeText(getActivity(), "Unable to save the data.",
                                    Toast.LENGTH_SHORT).show();
                        }
                    }
                });
            } catch (IOException e) {
                e.printStackTrace();
            }

但是,当代码在我的Android应用程序中运行时,它会失败,并显示以下错误:
标题丢失:请添加内容类型:应用程序/JSON或应用程序/JSON来指定有效载荷数据类型
HTTP响应错误代码为400。
显然,我已经用多种方式添加了一个content-type的头,日志输出了一个curl请求,它在postman中工作。我遗漏了什么?这个头是被okhttp还是其他什么东西删除了?
版本:okhttp3版本4.10.0

    • 更新1**

我知道有三种方法可以在okhttp. addHeader,header和using headers builder中添加头。除了header和header方法覆盖了在创建时将MediaType. parse("application/json")传递给请求时添加的头之外,没有太大的区别。无论我如何向请求添加头,我仍然得到400响应。

    • 更新2**

为了测试我的网络和参数,比如api-key,我使用了postman和Java11HttpClient,两种方法都可以工作。

HttpRequest request = HttpRequest.newBuilder()
            .POST(HttpRequest.BodyPublishers.ofString(data))
            .uri(URI.create(MONGO_DB_URL))
            .setHeader("api-key", API_KEY)
            .setHeader("Content-Type", "application/json")
            .build();

所以这个问题似乎是okhttp客户端特有的。

    • 更新3**

我用Google的Volley HTTP库尝试了同样的场景,它也能用,所以现在我可以在没有okhttp的情况下在我的应用程序上取得进展。

oxalkeyp

oxalkeyp1#

我没有足够的代表添加评论,所以我会在这里回答。
OkHttp的默认字符编码是UTF-8,所以您可以直接这样做。

final RequestBody body = RequestBody.create(
        MediaType.parse("application/json"), json);

接下来,OkHttp的Headers类包含一个嵌套类Builder,您可以使用它在请求中添加头,add方法提供头名称和值的验证。下面我使用“内容类型”作为“内容类型”的代名词,因为我相信这是正确的方法。

Headers.Builder builder = new Headers.Builder();
// Add a header with the specified name and value.
// Does validation of header names and values.
builder.add("api-key", mongoDbApiKey);
builder.add("Content-Type", "application/json");

// Build headers.
Headers headers = builder.build();

最后将头添加到请求中。

Request request = new Request.Builder()
        .url(url)
        .headers(headers)   // Add headers to request.
        .post(body)
        .build();

相关问题