java http servlets web-applications reverse-proxy

¿Código para obtener un servlet de Java para que actúe como proxy?



http servlets (2)

Puede usar un RequestDispatcher para reenviar su solicitud de la siguiente manera:

RequestDispatcher dispatcher = httpRequest.getRequestDispatcher(forwardingAddress); // here you have the choice whether to use include(..) or forward(..) see below if(useInclude) dispatcher.include(httpRequest, httpResponse); else dispatcher.forward(httpRequest, httpResponse);

... donde useInlcude se configura a su elección con las siguientes opciones:

  • incluir
    Esto es probablemente lo que quiere hacer: cargue el contenido de la dirección de forwardingAdress en su respuesta.
    • Esto significa que incluso podría incluir múltiples objetivos en una sola respuesta.
    • El cliente ni siquiera se dará cuenta de este procedimiento ni necesita poder ver el documento de destino.
  • adelante
    Enviar un reenvío a la dirección de forwardingAddress . Esto le indicará al cliente que envíe una nueva solicitud a la URL especificada.
    • Si lo haces en un navegador con herramientas de desarrollador, verás una segunda solicitud.
    • El cliente debe poder ver y cargar la URL de destino.
    • Solo puedes reenviar a un solo objetivo.

Vea, los siguientes enlaces, también:

  • RequestDispatcher javadoc , especialmente para las notas:
    • forward se debe llamar antes de que la respuesta se haya comprometido con el cliente (antes de que se haya vaciado la salida del cuerpo de respuesta). Si la respuesta ya se ha confirmado, este método lanza una excepción IllegalStateException. La salida no confirmada en el búfer de respuesta se borra automáticamente antes del reenvío.
    • incluir : Los parámetros de solicitud y respuesta deben ser los mismos objetos que se pasaron al método de servicio del servlet llamante o ser subclases de las clases ServletRequestWrapper o ServletResponseWrapper que los envuelven.
  • Ejemplo de URLRewriteFilter
    aunque este ejemplo se implementa utilizando un Filter lugar de un Servlet el comportamiento es el mismo (Nota: este ejemplo es parte de un marco de trabajo mío y, por lo tanto, contiene cierta sobrecarga en las clases primarias. Eche un vistazo a la sección relevante ... )

Tengo dos aplicaciones web Java que tienen un solo servlet que se asigna a una URL específica:

red.war/ WEB-INF/classes com.me.myorg.red.RedServlet (maps to http://red.example.com/doStuff) blue.war/ WEB-INF/classes com.me.myorg.blue.BlueServlet (maps to http://blue.example.com/doStuff)

Quiero poner estas aplicaciones (las llamo mis "aplicaciones backend") detrás de una "aplicación proxy" (servlet) que decidirá cuál de estas dos aplicaciones finalmente atenderá una solicitud del lado del cliente.

Esta aplicación web proxy tomaría una solicitud HTTP entrante y determinará a cuál de las 2 "aplicaciones backend" (rojo o azul) enviará la solicitud. La solicitud se reenviaría a http://red.example.com/doStuff (y luego se procesaría con RedServlet#doGet(...) ) o http://blue.example.com/doStuff (y luego se procesaría por BlueServlet#doGet(...) ). La respuesta devuelta de la aplicación backend (nuevamente, ya sea RedServlet#doGet(...) o BlueServlet#doGet(...) ) se devolverá al servlet proxy y, finalmente, se devolverá al cliente.

En otras palabras, en pseudocódigo:

public class ProxyServlet extends HttpServlet { @Override public doGet(HttpServletRequest request, HttpServletResponse response) { String forwardingAddress; if(shouldBeRed(request)) forwardingAddress = "http://red.example.com/doStuff"; else forwardingAddress = "http://blue.example.com/doStuff"; PrintWriter writer = response.getWriter(); writer.write(getResponseFromBackend(forwardingAddress, request)); } private String getResponseFromBackend(String addr, HttpServletRequest req) { // Somehow forward req to addr and get HTML response... } }

es posible? Si es así, ¿cómo y qué código necesitaría escribir para que funcione?


Ya que aún no hay una respuesta aprobada, trato de escribir cómo veo la solución a esta solicitud usando la biblioteca apache-http-commons. Además sugiero agregar un rubor al escritor.

public class ProxyServlet extends HttpServlet { @Override public doGet(HttpServletRequest request, HttpServletResponse response) { String forwardingAddress; if(shouldBeRed(request)) forwardingAddress = "http://red.example.com/doStuff"; else forwardingAddress = "http://blue.example.com/doStuff"; PrintWriter writer = response.getWriter(); writer.write(getResponseFromBackend(forwardingAddress, request)); **writer.flush();** } private String getResponseFromBackend(String addr, HttpServletRequest req) { HttpClient client = new HttpClient(); HttpMethod method = new GetMethod(url); client.executeMethod(method); String body=method.getResponseBodyAsString(); return body; }

}