2012-01-23 2 views
0

ServletExec이있는 IIS에서 tomcat으로 기존 애플리케이션을 마이그레이션하려고합니다. 두 개의 서블릿이있는 서블릿 체인이있는 경우를 제외하고는 모든 것이 작동합니다.서블릿 앨리어싱을 사용하는 레거시 서블릿 체인

첫 번째 서블릿은 일부 처리를 수행하고 두 번째 서블릿은 일부 변환을 수행합니다. 내 경우

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

, 나는 ProcessServlet를 호출 할 수 있으며 번역되지 않은 태그를 HTML을 생성합니다. 두 번째 서블릿은 html을 취하고 잘 알려진 번역 태그를 찾고 번역 한 다음 브라우저에서 읽을 수있는 outupt를 생성합니다.

서블릿 앨리어싱을 사용하는 서블릿 체인과 같은 모양이 더 이상 지원되지 않지만 (/123.) 필터를 사용하여 동일한 기능을 구현할 수 있지만 클래스는 인터페이스를 구현해야하지만 불행히도 제 경우에는 함께 작업해야합니다. 기존 클래스 파일

This page은 개념을 지정하지만 예제가 없습니다. 관리 도구에서 설정 섹션의 하위 섹션을 앨리어싱 서블릿을 사용하여

서블릿 앨리어싱을 사용하여 서블릿 체인을 구성하는 방법

this page에서 또한

는 서블릿의 목록은 지명 될 수있다 특히 URL 요청 서블릿 테이블에서 새로운 매핑을 추가 할 때 은 쉼표로 구분 된 서블릿 목록을 의 순서로 입력 할 수 있으며 특정 URL에 대한 요청이 도착하면 호출해야합니다. 이렇게하면 번마다 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

내가 서블릿 체인의 구현 세부 사항에 정말 익숙하지 해요 나를 위해 일한 전체 구현은, 그러나 일반적인이다 접근 방식이 효과가있을 수 있습니다. 다른 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 서블릿에 필터를지도 :

<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()'메소드를 가질 것인가? 두 개의 서블릿에 대한 클래스 파일을 연결해야하므로 수정할 수 없습니다. 나는 새로운 수업을 시작할 수 있다고 생각한다. –

+0

신경 쓰지 마라, 나는 조금의 인터넷 검색으로 그것을 이해할 수 있었다.이 솔루션이 작동하면이 대답을 수락합니다. –

+0

적어도 세 개의 새로운 클래스가 필요합니다. 프로세스 서블릿의 출력을 버퍼링하는 응답 래퍼. 요청 랩퍼는 요청으로서 해당 응답을 노출합니다. 그리고 마지막으로 필터. – kschneid