【问题标题】:Using httpclient 4.1 as a proxy within a servlet在 servlet 中使用 httpclient 4.1 作为代理
【发布时间】:2015-10-25 13:50:00
【问题描述】:

我们正在编写一个 J2EE Java servlet,它作为浏览器客户端和另一个服务器之间的代理。我们在 servlet 中使用 httpclient 4.1 代码,充当浏览器请求和其他服务器调用之间的代理。这是问题的主要部分,httpclient 4.1 将返回用于下一组请求的 cookie,但它不会返回 cookie,因为它们完全是从服务器返回的。是否可以在 httpclient 中从服务器获取“真实的”“set-cookie”标头信息。

例如(这里是在 servlet 级别设置的代码的伪代码):

DefaultHttpClient httpClient = new DefaultHttpClient();
// Connect to another server //
List list = httpClient.getCookieStore().getCookies();

cookie 列表是(我相信)下一组请求所需的 cookie,但不是来自服务器的 cookie 的确切表示。

例如,如果服务器响应:

Set-Cookie: myval=;

...

在getCookies的列表中,列表为空。因为我们正在尝试创建一个代理调用,我们不希望列表为空,我们可以发送 myv​​al=;从 servlet 返回到浏览器客户端。

当 httpclient 处理响应时,是否可以注入某种监听器?或者 httpclient 是否对所有返回的“set-cookie”值进行了 api 调用?此外,当连接到服务器时,我们可能会遇到重定向,我们还希望收集那里的所有 set-cookie 调用。

编辑:基本上当使用 httpclient 向另一台服务器发出请求时,对 httpclient 的调用包括重定向。是否可以沿重定向路径收集cookie信息。

【问题讨论】:

  • 问题,为什么不使用 servlet 来重定向请求并检索 cookie?
  • 它确实与涉及向内部 REST 服务发出请求的应用程序用例相关联。 servlet-httpclient 代码之间连接的服务器在 Internet 上不可用。浏览器不可用。
  • 为什么不能使用 RequestDispatcher 来重定向请求?我问这个是因为我们有一个类似的用例,我们需要从传入请求中读取 cookie,然后将其重定向到不同的 servlet。
  • 请求调度程序如何连接到具有不同主机名的其他服务器? Httpclient 在这种情况下工作正常,问题是关于 httpclient。不是 servlet/j2ee 部分。
  • CloseableHttpResponse 中的getHeadergetAllHeader 方法呢?我正在使用 HttpClient 4.4.1

标签: java servlets cookies proxy


【解决方案1】:

由于 cookie 是使用标头设置的,因此您可以直接从响应中提取标头并转发它们:

使用 http://bing.com 的示例,因为它设置了一堆 cookie,而与用户代理无关:

HttpGet get = new HttpGet("http://bing.com");
final HttpResponse response = client.execute(get);
for(Header header: response.getHeaders("set-cookie")) {
    System.out.printf("%s: %s%n", header.getName(), header.getValue());
}

输出:

Set-Cookie: _FS=NU=1; domain=.bing.com; path=/
Set-Cookie: _HOP=; domain=.bing.com; path=/
Set-Cookie: _SS=SID=0E33DFF1E74942258D088E964991329D; domain=.bing.com; path=/
Set-Cookie: SRCHD=AF=NOFORM; expires=Fri, 11-Aug-2017 07:53:36 GMT; domain=.bing.com; path=/
Set-Cookie: SRCHUID=V=2&GUID=F9F751F2254D41AEBA076AF7737236E3; expires=Fri, 11-Aug-2017 07:53:36 GMT; path=/
Set-Cookie: SRCHUSR=AUTOREDIR=0&GEOVAR=&DOB=20150812; expires=Fri, 11-Aug-2017 07:53:36 GMT; domain=.bing.com; path=/
Set-Cookie: _EDGE_S=F=1&SID=1F7F788103616B0C246A708002856ABD; path=/; httponly; domain=bing.com
Set-Cookie: _EDGE_V=1; path=/; httponly; expires=Fri, 11-Aug-2017 07:53:36 GMT; domain=bing.com
Set-Cookie: MUID=3702A96D37A16DAA320AA16C36456C90; path=/; expires=Fri, 11-Aug-2017 07:53:36 GMT; domain=bing.com
Set-Cookie: MUIDB=3702A96D37A16DAA320AA16C36456C90; path=/; httponly; expires=Fri, 11-Aug-2017 07:53:36 GMT

此外,由于您作为代理运行,因此完全禁用 cookie 管理可能是个好主意,这样您就不会被来自不同客户端的 cookie 污染请求:

client.getParams().setParameter(ClientPNames.COOKIE_POLICY, CookiePolicy.IGNORE_COOKIES);

更新

这是一个示例 RedirectStrategy,它将所有遇到的 set-cookie 标头存储在 HttpContext - HttpContext 是所有重定向都相同,但在 execute 调用之间不一样 - 然后在最终响应中恢复所有重定向:

public class CookieTrackingRedirectStrategy extends DefaultRedirectStrategy {

    @Override
    public boolean isRedirected(final HttpRequest request, final HttpResponse response, final HttpContext context) throws ProtocolException {
        boolean isRedirected = super.isRedirected(request, response, context);
        List<String> allCookies = (List<String>) context.getAttribute("all-cookies");
        if(isRedirected) {
            // Store cookies from this response for future restoration
            if(allCookies == null) {
                allCookies = new ArrayList<>();
                context.setAttribute("all-cookies", allCookies);
            }
            Header[] cookies = response.getHeaders("set-cookie");
            for(Header cookie : cookies) {
                allCookies.add(cookie.getValue());
            }
        } else if(allCookies != null) {
            // Restore all cookies to this response
            for(String cookie : allCookies) {
                response.addHeader("set-cookie", cookie);
            }
        }
        return isRedirected;
    }
}

使用 DefaultHttpClient.setRedirectStrategy 设置它。

【讨论】:

  • 这很好,但不会收集所有带有重定向的 cookie。如果有 10 个重定向,您最终可能会根据最后一个服务器请求/响应打印出 0 个 cookie。
  • 您可以禁用自动重定向处理并自己处理它们以获取所有 cookie 标头或子类化 DefaultRedirectStrategy 以在处理重定向之前拦截响应并收集 cookie。
  • 我添加了一个示例 RedirectStrategy,它使用 HttpContext 来跟踪所有 cookie。
猜你喜欢
  • 2011-06-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-09-10
  • 1970-01-01
  • 2017-07-13
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多