使用servlet别名进行遗留servlet链接

时间:2012-01-23 15:30:46

标签: tomcat servlets chaining

我正在尝试将现有的应用程序从带有ServletExec的IIS迁移到tomcat。我得到了一切工作,除了有一个带有两个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 Aliasing子部分   管理工具,可以为特定的servlet命名列表   网址请求。在servlets表中,添加新映射时,您就是   允许按顺序输入以逗号分隔的servlet列表   当请求到达时,应该调用它们   特定的URL。这将配置要调用的servlet链   与URL匹配的请求到达的时间。

任何人都可以指定一个示例,或指出我如何从web.xml中使用此链来实现正确的方向吗?

更新:

Per 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 个答案:

答案 0 :(得分: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
}

......或类似的东西;)