I'm trying to migrate an existing application from IIS with ServletExec to tomcat. I got everything working except for the case where there is a servlet chain with two servlets.
The first servlet does some processing and the second servlet does some translation.
request-->ProcessServlet--> (untranslated html) -->TranslateServlet --> response
In my case, I can call the ProcessServlet and it produces html with untranslated tags. The second servlet looks like it takes the html, locates well known translation tags and translates them and produces readable outupt to the browser.
From googling, looks like servlet chaining using servlet aliasing is no longer supported/recommended( from this page) and the same functionality can be achieved with filters but the classes have to implement an interface but unfortunately in my case I have to work with the existing class files.
This page specifies the concept but has no examples.
Also from this page
How to Configure a Servlet Chain Using Servlet Aliasing
Using the Servlet Aliasing subsection of the setup section in the Administration Tool, a list of servlets can be named for a particular URL request. In the servlets table, when adding a new mapping, you are allowed to enter a comma-separated list of servlets in the order in which they should be invoked when a request arrives for that particular URL. This configures a servlet chain to be invoked every time a request that matches the URL arrives.
Can anyone specify an example or point me in the right direction as to how to get this chain to work from web.xml?
UPDATE:
Per kschneid's outline in his answer, here's the full implementation that worked for me
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();
}
}