3

我需要编写一个 servlet,它基本上只是将每个传入请求代理到不同主机上的相同 URL 路径。这是我使用 Apache Commons Http Client 4.1.3 得出的结果:

@WebServlet("/data/*")
public class ProxyServlet extends HttpServlet {

  protected void doGet (HttpServletRequest request, HttpServletResponse response)
  throws ServletException, IOException {
    HttpClient client = new DefaultHttpClient();
    try {
      String url = getMappedServiceUrlFromRequest(request);
      HttpGet get = new HttpGet(url);
      copyRequestHeaders(request, get);

      HttpResponse getResp = client.execute(get);
      response.setStatus(getResp.getStatusLine().getStatusCode());
      copyResponseHeaders(getResp, response);

      HttpEntity entity = getResp.getEntity();
      if (entity != null) {
        OutputStream os = response.getOutputStream();
        try {
          entity.writeTo(os);
        } finally {
          try { os.close(); } catch (Exception ignored) { }
        }
      }
    } catch (Exception e) {
      throw new ServletException(e);
    } finally {
      client.getConnectionManager().shutdown();
    }
  }

  private void getMappedServiceUrlFromRequest (...)
  private void copyResponseHeaders (...)
  private void copyRequestHeaders (...)
}

这在第一次调用 servlet 时工作得很好。但是,第一次之后,servlet 挂在client.execute(get)行上。

“HttpClient 执行挂起”有很多谷歌点击,其中大部分建议使用 ThreadSafeClientConnManager 的实例。试过了,可惜没用。

我花了几个小时在谷歌上搜索这个问题,但我还没有找到任何可以解决它的东西。我非常感谢任何关于我在这里做错了什么的指示。

4

1 回答 1

0

我建议你以艰难的方式做到这一点。只需编写一个进行重定向的过滤器。

甚至只是一个 TCP 服务器,它在端口上侦听并只是来回复制字节。您根本不需要在代理中使用 HTTP 协议,除非您正在实施 CONNECT 命令,在这种情况下,这是您需要了解的唯一 HTTP 部分,并且它的回复是您需要的唯一 HTTP 响应要知道。其他一切都只是字节。

于 2012-05-25T07:20:37.873 回答