我正在尝试将OkHttp 3.6.0与Elasticsearch一起使用,而且我一直坚持向Elasticsearch Multi GET API发送请求。
它需要使用请求正文发送HTTP GET请求。不幸的是,如果我自己尝试构建请求,OkHttp并不支持开箱即用并抛出异常。
RequestBody body = RequestBody.create("text/plain", "test");
// No RequestBody supported
Request request = new Request.Builder()
.url("http://example.com")
.get()
.build();
// Throws: java.lang.IllegalArgumentException: method GET must not have a request body.
Request request = new Request.Builder()
.url("http://example.com")
.method("GET", requestBody)
.build();
是否有机会在OkHttp中使用请求正文构建GET请求?
相关问题:
答案 0 :(得分:2)
经过几次尝试,我找到了解决该问题的方法。也许有人觉得它有用。
我使用了“ Httpurl.Builder”。
HttpUrl mySearchUrl = new HttpUrl.Builder()
.scheme("https")
.host("www.google.com")
.addPathSegment("search")
.addQueryParameter("q", "polar bears")
.build();
您的获取请求网址将完全按照这种方式发生:
https://www.google.com/search?q=polar%20bears
在构建了网址之后,您必须像这样构建请求:
Request request = new Request.Builder()
.url(mySearchUrl)
.addHeader("Accept", "application/json")
.method("GET", null)
.build();
以下是来源:https://square.github.io/okhttp/3.x/okhttp/okhttp3/HttpUrl.html
答案 1 :(得分:0)
我试图实现相同的目标,但不幸的是,如果没有我个人喜欢的肮脏技巧,这是不可能完成的,但是我不想在我的生产代码中看到。
基本上,您可以使用构建器创建POST方法,并在以后使用反射将其方法字段设置为“ GET”。这可以解决问题。
类似这样的东西:
Builder builder = new Request.Builder().url(mySearchUrl).method("POST", body).build();
Field field = Builder.class.getField("method");
field.setAccessible(true);
field.setValue(builder, "GET");
答案 2 :(得分:0)
技术上的 RFC https://tools.ietf.org/html/rfc2616#section-9.3 说你可以在 get 请求中使用正文。
在切换到另一个客户端库之前我尝试了什么
我尝试使用网络拦截器重写请求
我尝试了反射来改变方法
Field field = originalRequest.getClass().getDeclaredField("method");
field.setAccessible(true);
field.set(originalRequest, "GET");
结论: 您将需要更改库,OKHttp 不支持带有请求正文的 GET 请求,需要使用 apache 客户端或任何其他支持此功能的客户端。
答案 3 :(得分:0)
基于@nilesh-salpe 的回答:
static class GetBodyBuilder extends Request.Builder {
public Request.Builder get(RequestBody body) {
this.post(body);
try {
Field field = Request.Builder.class.getDeclaredField("method");
field.setAccessible(true);
field.set(this, "GET");
} catch (IllegalAccessException | NoSuchFieldException e) {
throw new SliceException("Couldn't set dirty reflection", e);
}
return this;
}
}
然后,而不是做
new Request.Builder().get(getBody(input))
我们可以做到
new GetBodyBuilder().get(getBody(input))
它不漂亮,但很管用
答案 4 :(得分:-1)
如果基本API允许查询参数,则将所有正文参数作为queryparams发送。它像一种魅力。虽然OKHttp允许查询参数,但不允许带有Get调用的正文以避免缓存不一致。
答案 5 :(得分:-1)
两者都做。 (按顺序)
Request request = new Request.Builder()
.url("http://example.com")
.post(requestBody)
.get()
.build();