2

How can I write a filter class to pass the response from one servlet to another along with the GET parameters?

This is the outline of what I've tried (I got most of it from this question)

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 {

    chain.doFilter(request, response);
    ..

    RequestDispatcher dispatch = request.getRequestDispatcher("/Translate");
    dispatch.forward(request, response); 
    ..
  }
}

and this in the web.xml

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

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

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

But it doesn't not work. It's not forwarding to the second servlet. I don't have a debugging environment setup so I can't tell where it's failing but can someone point me in the right direction?

Community
  • 1
  • 1
Professor Chaos
  • 8,850
  • 8
  • 38
  • 54
  • `chain.doFilter(request, response);`is this conditional ? – jmj Jan 24 '12 at 16:16
  • @JigarJoshi are you asking if it returns a boolean? – Professor Chaos Jan 24 '12 at 16:20
  • Why wouldn't you post this as part of your original question? You've omitted some important details of the answer I provided, namely that you should pass a response wrapper that acts as a buffer instead of the original response object. – kschneid Jan 24 '12 at 17:03
  • @kschneid Previously I didn't realize using a filter would solve my issue; my first question was very generic. I was trying to implement the filter but I'm not quite there yet. In this post I was trying to get some answers regarding implementing filters. – Professor Chaos Jan 24 '12 at 19:37

1 Answers1

9

The FilterChain#doFilter() continues the request processing and only returns when the target controllers have finished their job and the response is been rendered and committed.

You should not invoke it if your intent is to change the request to a different server side destination by RequestDispatcher#forward() (or when you want to let the client side send a new request by HttpServletResponse#sendRedirect()). You should have noticed this by seeing IllegalStateException: response already committed in the server logs.

So, either remove it so that you only end up with the forward,

request.getRequestDispatcher("/Translate").forward(request, response); 

or make it a conditional

if (someCondition) {
    chain.doFilter(request, response);
} else {
    request.getRequestDispatcher("/Translate").forward(request, response); 
}

Unrelated to the concrete question, if I understand/guess your actual functional requirement right, you're more looking for the RequestDispatcher#include() in the /process servlet. See also How do I execute multiple servlets in sequence?

Community
  • 1
  • 1
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • If you look at the original question, and my comment on this question, you'll notice that some important details have been omitted... – kschneid Jan 24 '12 at 17:04