2013-06-03 33 views
14

我有有被映射到特定的URL,單個Servlet兩個Java Web應用程序:獲取Java servlet充當代理的代碼?

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

這可能嗎?如果是這樣,我需要怎樣編寫代碼才能使其工作?

+1

我們使用[j2ep](http://j2ep.sourceforge.net/)... – Lucas

+2

你需要向後端服務器做一個HTTP請求,看一看在http://hc.apache.org/httpcomponents-core-ga/httpcore/index.html – Woody

+4

我已經嘗試https://github.com/dsmiley/HTTP-Proxy-Servlet,並發現它體面 – Chris

回答

7

你可以使用一個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。
    • 如果您使用開發人員工具在瀏覽器中執行此操作,您將看到第二個請求。
    • 客戶端必須能夠查看並加載目標URL。
    • 您只能轉發到單個目標。

參見以下鏈接,太:

  • RequestDispatcher javadoc,特別是對注:之前的響應一直致力於爲客戶
    • 向前應該叫(在響應主體輸出已被刷新之前)。如果響應已被提交,則此方法將引發IllegalStateException。在轉發之前,響應緩衝區中未提交的輸出會自動清除。
    • 包括:請求和響應參數必須與傳遞給調用servlet的服務方法的對象相同,或者是包裝它們的ServletRequestWrapper或ServletResponseWrapper類的子類。
  • URLRewriteFilter example
    雖然這個例子是使用Filter,而不是一個Servlet的行爲是相同的(注實現的:這個例子是我的一個框架的一部分,因此包含在父類中的某些開銷,只要有一個看相關部分...)
+2

我認爲這個解決方案只有在「後端」servlet部署在同一個應用程序上時纔會起作用。由於紅色和藍色servlet部署在不同的主機上,因此可能無法獲得其上下文的分派器。查看更多解釋http://stackoverflow.com/questions/4889113/how-to-forward-request-from-web1-servlet-to-web2-servlet – jesantana