我尝试使用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的情况下在我的应用程序上取得进展。
1条答案
按热度按时间oxalkeyp1#
我没有足够的代表添加评论,所以我会在这里回答。
OkHttp的默认字符编码是UTF-8,所以您可以直接这样做。
接下来,OkHttp的Headers类包含一个嵌套类Builder,您可以使用它在请求中添加头,add方法提供头名称和值的验证。下面我使用“内容类型”作为“内容类型”的代名词,因为我相信这是正确的方法。
最后将头添加到请求中。