user1328333
user1328333

Reputation: 21

mapping filters and servlet in Sling

I have a requirement where my requests to pages are to be filtered by an intercepting filter. Based on different conditions, the request has to be redirected to different pages.

I have created a bundle and registered the servlet and filter in the bundle activator, taking a cue from here.

Following is the code snippet:

Hashtable initParams = new Hashtable(); // to  pass a dictionary object to
                                        // service.register
initParams.put("sling.servlet.resourceTypes","/login");
initParams.put("sling.servlet.extensions","jsp");
service.registerServlet("/myServlet", this.myServlet, initParams, null);
initParams = new Hashtable();
initParams.put("sling.filter.scope","REQUEST");
service.registerFilter(this.checkPageRequest, "/.*",null, 2, null);
service.registerFilter(this.checkValidSession, "/.*", null, 1, null);

I am facing two issues:

  1. I am not able to identify where I am mapping a filter to corresponding servlet. My understanding is that the checkPageRequest filter would be called followed by checkValidSession. if there is no requestdispatcher.forward(..), the myServlet servlet would be hit. In my case, the filters are getting called as expected by using filterChain.doFilter(..), but the servlet is not getting called.

  2. Since my filters have to intercept all the page requests, so when I do a requestdispatcher.forward(..) to any page, the same filter gets called again, getting into a loop.

I am developing this as OSGi bundle to be deployed on a DayCQ environment.

Upvotes: 2

Views: 4064

Answers (2)

Oliver
Oliver

Reputation: 6250

Well your Filter and Servlet should have the same URL mapping. Ofcourse the Filter will get called first.

Let the Filter preprocess the data and let the servlet add the data in request object and dispatch it to JSP. See below Example,

@SlingFilter(order=1)

@Properties({
    @Property(name="service.pid", value="com.videojet.hiresite.filters.AddNewUserFilter",propertyPrivate=false),
    @Property(name="service.description",value="Preproceesing Filter", propertyPrivate=false),
    @Property(name="service.vendor",value="XXX Tech", propertyPrivate=false),
    @Property(name="pattern",value="/services/videojet/v1/.*", propertyPrivate=false) 
//  The Property Above property Maps your Filter to URL
})
public class AddNewUserFilter implements javax.servlet.Filter{

    private final Logger log = LoggerFactory.getLogger(this.getClass());
    public void destroy() {
        // TODO Auto-generated method stub

    }

    public void doFilter(ServletRequest request, ServletResponse response,
            FilterChain chain) throws IOException, ServletException {

        log.info("AddNewUserFilter Invoked Invoked");
// Preprocessing here and just call chain.doFilter(xxx);

And the Servlet

@SlingServlet(
        paths={"/services/videojet/v1/AddNewUserController/view","/services/videojet/v1/AddNewUserController/userExists"
                ,"/services/videojet/v1/AddNewUserController/addUser"}
)
@Properties({
    @Property(name="service.pid", value="com.videojet.hiresite.controllers.AddNewUserController",propertyPrivate=false),
    @Property(name="service.description",value="Adds new user", propertyPrivate=false),
    @Property(name="service.vendor",value="XXX Tech", propertyPrivate=false)
})
public class AddNewUserController extends SlingAllMethodsServlet{

    /**
     * @author Oliver Kaunds
     */
    ///content/dam/videojetdocuments
    private static final long serialVersionUID = 1L;

    private final Logger log = LoggerFactory.getLogger(this.getClass());

    @Reference
    protected AddNewUserService addNewUserService;

    @Override
    protected void doGet(SlingHttpServletRequest request, SlingHttpServletResponse response) throws ServletException, IOException
    {


        log.info(":: Do GET Called ");
        String path =request.getRequestURI();
        log.info("PATH :: "+ path);
        try{
            if(path.equals("/services/videojet/v1/AddNewUserController/view"))
            {
                /* Do the dispatching here  One Servlet can have more than one Request 
                 Mappings . My Each mapping serves a purpose. */

                List<HRRepresentative> list =addNewUserService.getHRRepresentative();
                request.setAttribute("hrList",list );
                HttpSession session = request.getSession();
                String userOperation =(String)session.getAttribute("userOp");
                request.setAttribute("userOp", userOperation);
                session.removeAttribute("userOp");
                //throw new Exception("My Exception");
                RequestDispatcher dispatcher =request.getRequestDispatcher("/content/videojet/en/addnewuser.html"); // Dispatch to JSP here
                dispatcher.forward(request, response); 
            }

This is a Tried and Tested code

Upvotes: 1

Bertrand Delacretaz
Bertrand Delacretaz

Reputation: 6100

As you're working with Sling, you should rather use Sling's standard SCR-based methods to register your components, described at http://sling.apache.org/site/filters.html for filters and http://sling.apache.org/site/servlets.html for servlets.

Registering servlets and filters directly with the HttpService as you seem to be doing will "fight" with the SlingMainServlet, which should get all requests in a Sling application.

Upvotes: 2

Related Questions