3 Replies Latest reply on Nov 16, 2012 3:53 AM by Mohd Riyaz Ahmed

    Problem with Felix filter in forwarding the request to CQ page.

    durganuvvula

      My scenario is Apache webserver would direct the calls to CQ Servlet filter which i write. At the filter,

      I would do some business process to verify its the CQ pages or our webapp vanity pages. If it is a CQ page,

      forward to that CQ page or if it is a webapp vanity, i would redirect to that webapp page from CQ using 301 redirect..

       

       

      I want the apache webserver to hit my filter directly and then my filter should do the routing accordingly at the CQ.

       

       

      In my case I have choosen felix filter as I want my filter to intercept all the calls before actually go to sling engine. For testing purpose, I am hitting the filter and apache webserver configuration is not in place yet, I am trying to forward the request to /content/geometrixx/en/products.html from the filter and getting 500 error. I have looked into error.log, system.log and access.log but of no help.

       

      Any pointers/suggestions towards the solution would be really appreciable. Am I doing any thing wrong ? Please suggest if any better ways to do this.

       

       

      public class Activator implements BundleActivator {

          private static final Logger log = LoggerFactory.getLogger(Activator.class);

          private ServiceRegistration registration;

       

       

          public void start(BundleContext context) throws Exception {

                    ServiceReference sRef = context.getServiceReference(ExtHttpService.class.getName());

                        if (sRef != null)

                        {

                          ExtHttpService service = (ExtHttpService) context.getService(sRef);

                          service.registerFilter(new VanityUrlFilter(), "/testVanityFilter", null, 0, null);

                        }

                      }

            

          }

      }

       

       

      public class VanityUrlFilter implements Filter{

                 private static final Logger logger = LoggerFactory.getLogger(VanityUrlFilter.class);

       

       

                public void doFilter(ServletRequest request, ServletResponse response,

                                    FilterChain chain) throws IOException, ServletException {

      logger.info("Inside Felix Filter");

                          response.setContentType("text/plain");

              response.setCharacterEncoding("UTF-8");

                          response.getWriter().write("Filter got registered successfully");

              response.getWriter().flush();

            

                 RequestDispatcher requestDispatcher = request.getRequestDispatcher("/content/geometrixx/en/products.html"); //tried with out html extension also.

                //RequestDispatcher requestDispatcher = request.getRequestDispatcher("/content/geometrixx/en/products");

                requestDispatcher.forward(request, response);

                //even I have tried response.sendRedirect with no luck.

                //response.sendRedirect("/content/geometrixx/en/products.html")

       

       

                }

      }

       

       

      when I hit the url http://localhost:4502/totalVanityFilter

       

       

      Iam getting the following message in the browser.

       

       

      Inside Felix Filter

       

       

      <html><head><title>

      500

      Internal Server Error

      </title></head><body><h1>

      Internal Server Error

      </h1>

      </body></html>

       

       

      --Durga

        • 1. Re: Problem with Felix filter in forwarding the request to CQ page.
          shrik046 Level 1

          I think the problem might be with you committing the response output before sending the redirect. Try commenting out these lines and see if it works.

           

          response.setContentType("text/plain");
          response.setCharacterEncoding("UTF-8");
          response.getWriter().write("Filter got registered successfully");
          response.getWriter().flush();
          

           

          As for the implementation itself, I believe you are on the right path based on your requirements. I had to do a similar thing few weeks ago where we needed a filter to be in place before the request chains to the sling engine.

           

          The only way I found to make this work with an implementation similar to what you have now. Here is how my activator looks -

           

           

          public class Activator implements BundleActivator {
              private final Logger logger = LoggerFactory.getLogger(Activator.class);
              private ServiceTracker tracker;
              private HttpServiceExtFilter contentRequestFilter = new HttpServiceExtFilter("contentRequestFilter", "/testFilter", 0);
          
              public void start(BundleContext context) throws Exception {
                  logger.info("Starting bundle {}", context.getBundle().getSymbolicName());
          
                  this.tracker = new ServiceTracker(context, ExtHttpService.class.getName(), null) {
                      @Override
                      public Object addingService(ServiceReference ref) {
                          Object service =  super.addingService(ref);
                          serviceAdded((ExtHttpService)service);
                          return service;
                      }
            
                      @Override
                      public void removedService(ServiceReference ref, Object service) {
                          serviceRemoved((ExtHttpService)service);
                          super.removedService(ref, service);
                      }
                  };
            
                  this.tracker.open();
                  logger.info("Bundle {} started successfully", context.getBundle().getSymbolicName());
              }
          
          
              public void stop(BundleContext context) throws Exception {
                  this.tracker.close();
              }
          
              private void serviceAdded(ExtHttpService service) {
                   try {
                          logger.info("Adding {} filter", this.contentRequestFilter.getClass());
                          logger.info("Filter params: pattern={}, rank={}",this.contentRequestFilter.pattern, this.contentRequestFilter.rank);
                          service.registerFilter(
                                  this.contentRequestFilter, 
                                  this.contentRequestFilter.pattern, 
                                  null,
                                  this.contentRequestFilter.rank, 
                                  null);
                  } catch (Exception e) {
                      logger.error(e.getMessage());
                  }
              }
          
              private void serviceRemoved(ExtHttpService service) {
                  logger.info("Removing service {}", this.contentRequestFilter.getClass());
                  service.unregisterFilter(this.contentRequestFilter);
              }
          }
          
          1 person found this helpful
          • 2. Re: Problem with Felix filter in forwarding the request to CQ page.
            durganuvvula Level 1

            Thanks for your reply Shrik. Problem with 500 internal server is solved yesterday as nelson has replied that in another thread. the problem was with response being committed before forward.

             

            Issue now I am facing is with the request dispatcher forwarding.

             

            public class VanityUrlFilter implements Filter{

                       private static final Logger logger = LoggerFactory.getLogger(VanityUrlFilter.class);

                      @Override

                      public void destroy() {

                                // TODO Auto-generated method stub

             

                      }

             

                      @Override

                      public void doFilter(ServletRequest request, ServletResponse response,

                                          FilterChain chain) throws IOException, ServletException {

                                SlingHttpServletRequest slingRequest = (SlingHttpServletRequest)request;

                                RequestDispatcher requestDispatcher = slingRequest.getRequestDispatcher("/content/geometrixx/en/products.html");

                                requestDispatcher.forward(request, response);

                 }

             

            ((HttpServletResponse) response).sendRedirect("/content/geometrixx/en/products.html") is working fine in the above case instead of forward, but response.sendRedirect changes the url in the browser.

             

            Thats the reason I want the request dispatcher forwarding work as forward does not change the url in browser.

             

            I have looked into the docuemntation for SlingHttpServletRequest to get the dispatcher. but there are no examples as such.

             

            Any pointers/suggestions to solve this requestDispatcher forward would be appreciable.

             

            http://dev.day.com/docs/en/cq/current/javadoc/org/apache/sling/api/SlingHttpServletRequest .html#getRequestDispatcher(org.apache.sling.api.resource.Resource, org.apache.sling.api.request.RequestDispatcherOptions)

             

             

             

            --Durga

            • 3. Re: Problem with Felix filter in forwarding the request to CQ page.
              Mohd Riyaz Ahmed

              HI

               

              Thanks for your reply Shrik. Problem with 500 internal server is solved yesterday as nelson has replied that in another thread. the problem was with response being committed before forward.

               

              Will you the solution solution you got from nelson? I am alos facing 500 erro with ConstraintViolation exception?

               

              Thanks

              Riyaz