2012-01-23 47 views
0

我試圖將現有的應用程序從使用ServletExec的IIS遷移到tomcat。除了有兩個servlet的servlet鏈的情況之外,我得到了一切工作。使用servlet別名的傳統servlet鏈接

第一個servlet做了一些處理,第二個servlet做了一些翻譯。

request-->ProcessServlet--> (untranslated html) -->TranslateServlet --> response 

在我的情況下,我可以調用ProcessServlet並生成帶有未轉換標籤的html。第二個servlet看起來像是需要html,找到衆所周知的翻譯標籤並翻譯它們併產生可讀的瀏覽器輸出。

從谷歌搜索,看起來像servlet鏈接使用servlet別名不再支持/推薦(from this page)和相同的功能可以實現與過濾器,但類必須實現一個接口,但不幸的是在我的情況下,我必須與現有的類文件。

This page指定的概念,但沒有例子。

this page

如何配置一個Servlet鏈使用Servlet的別名

使用servlet混疊的 管理工具的安裝部分的第

而且,小服務程序的列表可以被命名爲特別是 URL請求。在servlets表中,當添加一個新的映射時,允許您按照 中的順序輸入以逗號分隔的servlet列表,當請求到達該特定URL時應調用它們。這將配置一個servlet鏈,以便在每個 與URL匹配的請求到達時調用它。

任何人都可以指定一個例子或指向我在正確的方向如何讓這個鏈從web.xml工作?

UPDATE:

每在他的回答kschneid的輪廓,這裏是爲我工作

import java.io.*; 
import javax.servlet.*; 
import javax.servlet.http.*; 

public class TranslateFilter implements Filter { 

    private FilterConfig config = null; 

    public void init(FilterConfig config) throws ServletException { 
    this.config = config; 
    } 

    public void destroy() { 
    config = null; 
    } 

    public void doFilter(ServletRequest request, ServletResponse response, 
        FilterChain chain) throws IOException, ServletException { 

     HttpServletResponse httpResponse = (HttpServletResponse) response; 
     MyHttpServletResponseWrapper processResponse = new MyHttpServletResponseWrapper(httpResponse); 
     chain.doFilter(request, processResponse); 
     String content = processResponse.toString(); 
     config.getServletContext().log("CONTENT: " + content); 
     HttpServletRequest httpRequest = (HttpServletRequest) request; 
     MyHttpServletRequestWrapper processResponseAsRequest = new MyHttpServletRequestWrapper(httpRequest, content); 

     RequestDispatcher dispatch = request.getRequestDispatcher("/Translate"); 
     response.setContentType("text/html"); 
     dispatch.forward(processResponseAsRequest, response); // forward to translate servlet with response from process servlet as the request and the original response 
    } 

} 

class MyHttpServletResponseWrapper 
    extends HttpServletResponseWrapper { 

    private StringWriter sw = new StringWriter(); 

    public MyHttpServletResponseWrapper(HttpServletResponse response) { 
    super(response); 
    } 

    public PrintWriter getWriter() throws IOException { 
    return new PrintWriter(sw); 
    } 

    public ServletOutputStream getOutputStream() throws IOException { 
    throw new UnsupportedOperationException(); 
    } 

    public String toString() { 
    return sw.toString(); 
    } 
} 

class MyHttpServletRequestWrapper 
    extends HttpServletRequestWrapper { 
    private String content; 
    public MyHttpServletRequestWrapper(HttpServletRequest request) { 
     super(request); 
    } 

    public MyHttpServletRequestWrapper(HttpServletRequest request, String content) { 
     super(request); 
     this.content = content; 
    } 

    public ServletInputStream getInputStream() 
    { 
     return new MyServletInputStream(content); 
    } 

    public BufferedReader getReader() 
    { 
     InputStreamReader in= new InputStreamReader(getInputStream()); 
     return new BufferedReader(in); 
    } 
    } 

class MyServletInputStream extends ServletInputStream 
{ 
    private InputStream is; 

    public MyServletInputStream(String content) 
    { 
     is = new ByteArrayInputStream(content.getBytes()); 
    } 

    public int read() throws IOException 
    { 
     return is.read(); 
    } 
} 

回答

1

我不是很熟悉的servlet鏈接的實現細節的全面實施,但這裏有一個一般可能有效的方法。在兩個servlet映射到不同的URL:

<servlet-mapping> 
    <servlet-name>process</servlet-name> 
    <url-pattern>/process</url-pattern> 
</servlet-mapping> 

<servlet-mapping> 
    <servlet-name>translate</servlet-name> 
    <url-pattern>/translate</url-pattern> 
</servlet-mapping> 

過濾器然後映射到process的servlet:

<filter-mapping> 
    <filter-name>processChain</filter-name> 
    <servlet-name>process</servlet-name> 
</filter-mapping> 

processChain過濾器會做這樣的事情:

public void doFilter(ServletRequest request, 
        ServletResponse response, 
        FilterChain chain) throws IOException, ServletException { 
    ServletResponseWrapper processResponse = ...; // response buffer 
    chain.doFilter(request, processResponse); // let process servlet populate response buffer 
    ServletRequestWrapper processResponseAsRequest = ...; // use processResponse to create request for translate servlet 
    RequestDispatcher dispatch = request.getRequestDispatcher("/translate"); 
    dispatch.forward(processResponseAsRequest, response); // forward to translate servlet with response from process servlet as the request and the original response 
} 

...或類似的東西;)

+0

哪個類會有'doFilter()'方法?我有兩個需要鏈接的servlet的類文件,所以我無法修改它們。我想我可以介紹一個新班級。 –

+0

沒關係,我可以通過一些Google搜索來弄清楚。如果這個解決方案有效,我會接受這個答案。 –

+0

您至少需要三個新類:用於緩衝進程servlet輸出的響應包裝器;請求封裝器將該響應作爲請求公開;最後,過濾器。 – kschneid