устаревшая цепочка сервлетов с использованием псевдонимов сервлетов - PullRequest
0 голосов
/ 23 января 2012

Я пытаюсь перенести существующее приложение из IIS с ServletExec в tomcat. У меня все работает, кроме случая, когда есть цепочка сервлетов с двумя сервлетами.

Первый сервлет выполняет некоторую обработку, а второй сервлет выполняет некоторый перевод.

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

В моем случае я могу вызвать ProcessServlet, и он создает HTML с непереведенными тегами. Второй сервлет выглядит так, как будто он принимает html, находит общеизвестные теги перевода, переводит их и создает читабельную информацию для браузера.

Начиная с поиска в Google, цепочка сервлетов с использованием псевдонимов сервлетов больше не поддерживается / не рекомендуется ( на этой странице ), и те же функциональные возможности могут быть достигнуты с помощью фильтров, но классы должны реализовывать интерфейс, но, к сожалению, в В моем случае я должен работать с существующими файлами классов.

Эта страница определяет концепцию, но не имеет примеров.

Также с этой страницы

Как настроить цепочку сервлетов с помощью псевдонимов сервлетов

Использование подраздела Servlet Aliasing раздела настройки в Инструмент администрирования, список сервлетов может быть назван для конкретного Запрос URL. В таблице сервлетов при добавлении нового отображения вы разрешено вводить список сервлетов через запятую в порядке которые они должны вызывать при поступлении запроса на это конкретный URL. Это настраивает цепочку сервлетов, которая будет вызываться каждый раз время поступления запроса, соответствующего URL.

Может кто-нибудь указать пример или указать мне правильное направление, как заставить эту цепочку работать из web.xml?

UPDATE:

Набросок Кшнейда в его ответе, вот полная реализация, которая работала для меня

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 Ответ

1 голос
/ 23 января 2012

Я не очень знаком с деталями реализации цепочки сервлетов, но вот общий подход, который может сработать.Сопоставьте два сервлета с разными 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
}

... или что-то в этом роде;)

...