0

In my use case i have to use a RequestDispatcher in order to ridirect the request to another servlet deployed on the same server.

public void doFilter(ServletRequest req, ServletResponse resp, FilterChain arg2) throws IOException, ServletException {
   String generateRedirectUrl=FormURL((HttpServletRequest)req);
   ServletContext context = ((HttpServletRequest)req).getSession().getServletContext();
   ServletContext newContext = context.getContext("/myNewContext");
   RequestDispatcher dispatcher = newContext.getRequestDispatcher(generateRedirectUrl);  
   dispatcher.forward(req, resp);          
}

but i have to read response and to make some operations on it before the forward to be sent.

Is it possible?

Alex
  • 1,515
  • 2
  • 22
  • 44
  • Are you saying that you want to modify the response which is generated by the servlet you are forwarding the request to? What sort of modifications? – mmulholl Dec 02 '15 at 17:22
  • i have to read a boolean value inside the dispatched response... then i have to do a logical boolean operation on it and finally i have to rewrite the boolean result inside the response being forwarded to the client. – Alex Dec 02 '15 at 17:52
  • Does the forwarded servlet use a writer or output stream? Will try to come up with code samples to demonstrate. – mmulholl Dec 02 '15 at 20:00
  • It s a third part simple rest service which returns a json object – Alex Dec 02 '15 at 20:06
  • There is some info here on how a servlet can return a json object: http://stackoverflow.com/questions/2010990/how-do-you-return-a-json-object-from-a-java-servlet so I will assume a printWriter. – mmulholl Dec 03 '15 at 14:27
  • ok thanks in advance... – Alex Dec 03 '15 at 14:36
  • Is the 3rd party rest service which you are forwarding the request to installed on the same server as your filter? If not, can you add applications to the server it is installed on? – mmulholl Dec 07 '15 at 13:55
  • Yes i can run it on my server otherwise i could not use dispatcher ... I should have to use redirect – Alex Dec 07 '15 at 13:57
  • I updated my answer to cover your scenario. Let me know which server implementation you are using if you need help setting up the ServletContextListener to run for all apps. – mmulholl Dec 07 '15 at 14:43
  • Wildfly 9.2 it s my application server... I ll check your answer – Alex Dec 07 '15 at 15:16
  • I am not familiar with Wildly and did not find anything on how to set a global servletContextLiistener on Wildly based on a quick search. If you do not know how to do that it would be worth asking that as separate question. – mmulholl Dec 07 '15 at 15:40
  • Is servletcontextlistener described in zervlet specification? If yes there should be standard settings – Alex Dec 07 '15 at 15:46
  • ServletContextListener is defined in the servlet spec but only on a per-application basis. At least Tomcat and WebSphere provide a method for defining a ServletContextListener which runs for all apps, I would expect WildFly to do the same. – mmulholl Dec 07 '15 at 16:06
  • Ok thanks... Let me do somw checks and i ll let you know... Thanks in advance – Alex Dec 07 '15 at 16:08
  • Any luck getting this working? – mmulholl Dec 14 '15 at 15:10

1 Answers1

0

If you create a servletContextListener you can use it to add a new filter which runs as part of the forward request. You can then implement a HttpServletResponseWrapper which overrides the getPrintWriter() and getOutputStream() methods to return your own objects which basically buffer what is written, and then replace the response object with your wrapper before you call doChain() in your new filter. Then on return from doChain you pull the response data from your buffer, process it how you like and then write it out using a PrintWriter or OutputStream (whichever was used by the rest request). I suspect that the rest service will use a PrintWriter for output so that would be the route that you take.

There is great example of how to do this (minus the ServletContextListener) here:

http://www.java2s.com/Tutorial/Java/0400__Servlet/Filterthatusesaresponsewrappertoconvertalloutputtouppercase.htm

Where this example converts the response to upper case is where you look for the json name,value pair which you need to change and then modify it as needed.

Here is an example of a suitable ServletContextListener. Note that the listener needs to be added such that it is called for all apps and different server implementations provide different methods for doing this:

import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;

    @WebListener
    public class ServletContextListenerFilter implements ServletContextListener {

        public ServletContextListenerFilter() {}

        @Override
        public void contextDestroyed(ServletContextEvent arg0) {}

        @Override
        public void contextInitialized(ServletContextEvent sce) {
            ServletContext sc = sce.getServletContext();

            if (sc.getServletContextName().equals("Third party rest serice context name")) {
                sc.addFilter("FilterName", filterClass);
            }

        }
    }
mmulholl
  • 281
  • 2
  • 7
  • Sorry, this solution would only work if the filter was run on the forwarded request, but your filter does the forward request. Need a more complex solution. – mmulholl Dec 03 '15 at 22:36