使Java servlet充当代理的代码?

时间:2013-06-03 19:30:37

标签: java http servlets web-applications reverse-proxy

我有两个Java Web应用程序,它们有一个servlet,它被映射到一个特定的URL:

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)

我想把这些应用程序(我称之为“后端应用程序”)放在“代理应用程序”(servlet)后面,这将决定这两个应用程序中的哪一个最终将服务于客户端请求。

此代理Web应用程序将接收传入的HTTP请求,并确定将请求转发到的2个“后端应用程序”(红色或蓝色)中的哪一个。然后,该请求将被转发到http://red.example.com/doStuff(然后由RedServlet#doGet(...))或http://blue.example.com/doStuff处理(然后由BlueServlet#doGet(...)处理)。然后,后端应用程序返回的响应(同样,RedServlet#doGet(...)BlueServlet#doGet(...))将返回到代理Servlet,最终返回给客户端。

换句话说,在伪代码中:

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...
    }
}

这可能吗?如果是这样,我需要编写的代码和代码才能使其正常工作?

2 个答案:

答案 0 :(得分:10)

您可以使用RequestDispatcher以下列方式转发您的请求:

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);

...使用以下选项将useInlcude设置为您的选择:

  • 包含
    这可能是您要执行的操作:将forwardingAdress中的内容加载到您的回复中。
    • 这意味着您甚至可以将多个目标包含在一个响应中。
    • 客户甚至不会意识到这个程序,也不需要能够看到目标文件。
  • 转发
    forwardingAddress发送转发。这将告诉客户端向指定的URL提交新请求
    • 如果您在使用开发者工具的浏览器中执行此操作,则会看到第二个请求。
    • 客户端必须能够查看并加载目标网址。
    • 您只能转发到单个目标。

请参阅以下链接:

  • RequestDispatcher javadoc,特别是对于笔记:
      在将响应提交给客户端之前(在刷新响应正文输出之前),应该调用
    • forward 。如果响应已经提交,则此方法抛出IllegalStateException。响应缓冲区中的未提交输出将在转发前自动清除。
    • include :请求和响应参数必须与传递给调用servlet的服务方法的对象相同,或者是包装它们的ServletRequestWrapper或ServletResponseWrapper类的子类。 / LI>
  • URLRewriteFilter example虽然这个示例是使用Filter而不是Servlet实现的,但行为是相同的(注意:此示例是我的框架的一部分,因此在父类中包含一些开销。只需查看相关部分......)

答案 1 :(得分:0)

由于尚无批准的答案,因此我尝试使用apache-http-commons库编写如何查看此请求的解决方案。另外,我建议在writer上添加同花顺。

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;

}

}