3

基本的に、各着信要求を別のホストの同じ 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 (...)
}

これは、サーブレットが初めて呼び出されたときにうまく機能します。ただし、初回以降、サーブレットはclient.execute(get)行でハングします。

「HttpClient execute hangs」に関する Google のヒットはたくさんありますが、そのほとんどは ThreadSafeClientConnManager のインスタンスを使用することを提案しています。試してみましたが、残念ながら役に立ちませんでした。

この問題について数時間グーグルで調べましたが、まだ修正するものは見つかりませんでした。ここで私が間違っていることについての指針を真剣に感謝します。

4

1 に答える 1

0

これを難しい方法で行っていることをお勧めします。リダイレクトを行うFilterを書くだけです。

または、ポートでリッスンし、バイトを前後にコピーするだけの TCP サーバーでさえあります。プロキシで HTTP プロトコルに関与する必要はまったくありません。ただし、CONNECT コマンドを実装している場合を除きます。この場合、理解する必要がある HTTP の唯一の部分であり、その応答が必要な唯一の HTTP 応答です。について知ること。それ以外はすべてバイトです。

于 2012-05-25T07:20:37.873 に答える