我正在使用 Apache HttpClient 4.5的Fluent API ,方法如下:
CloseableHttpClient client = HttpClientBuilder.create().build();
Executor executor = Executor.newInstance(client);
Response resp = executor.execute(Request.Get(url));
很遗憾,我无法找到获取重定向位置的正确方法( RedirectLocation 类)。 它们通常存储在 HttpContext 对象中;但是在使用Fluent API时,其实例是在 Executor.execute(...)中本地创建的,并且从未公开过:
public Response execute(final Request request) {
final HttpClientContext localContext = HttpClientContext.create();
/* ... */
return new Response(request.internalExecute(this.httpclient, localContext));
}
我尝试通过创建装饰器/代理类来覆盖 Executor.execute(...)方法;通过创建子类;甚至通过将其源代码复制粘贴到我自己的包中。 这些解决方案都不可行(例如, Executor 调用其他类的包本地方法)。
我到目前为止找到的唯一解决方法是实现我自己的 RedirectStrategy 并将其传递给 HttpClient :
public class MyRedirectStrategy extends DefaultRedirectStrategy {
private HttpContext context;
public RedirectLocations getRedirectLocations() {
return (RedirectLocations) context.getAttribute(REDIRECT_LOCATIONS);
}
@Override
public URI getLocationURI(final HttpRequest request, final HttpResponse response, final HttpContext context) {
this.context = context; // to keep the HttpContext!
return super.getLocationURI(request, response, context);
}
}
/* ... */
RedirectStrategy stra = new MyRedirectStrategy();
CloseableHttpClient client = HttpClientBuilder.create().setRedirectStrategy(stra).build();
Executor executor = Executor.newInstance(client);
Response resp = executor.execute(Request.Get(url));
for (final String redirectedUri : stra.getRedirectLocations()) {
/* process redirectedUri's */
}
但是,我认为这不是一个合适的解决方案。据我所知, RedirectStrategies 旨在成为不可变的无状态类,因为它们被传递给 HttpClient ,可以由多个线程/连接共享。 换句话说:逻辑上, HttpContext 不是 RedirectStrategy 的属性。
有什么想法吗? 谢谢!
答案 0 :(得分:0)
你做不到。 HC fluent API隐藏了来自消费者的HttpContext实例方式。考虑直接使用HttpClient API。