Expand my Community achievements bar.

Nomination window for the Adobe Community Advisor Program, Class of 2025, is now open!
SOLVED

Rendering CQ templates as part of servlet call on the same resource

Avatar

Community Advisor

Currently working on the PoC where I have a servlet that listens on CQ resource e.g.

@Component(metatype = true, label = "IndexingPage") @Service @Properties({ @Property(name = "sling.servlet.resourceTypes", value = {"indexing/components/pages/page"}), @Property(name = "sling.servlet.methods", value = "GET"), @Property(name = "sling.servlet.extensions", value = { "html" }) })


Servlet performs logic to retrieve data from another system, after servlet finish I want to render a page using CQ templating mechanism e.g. natively I would call

Resource resource = request.getResource(); request.getRequestDispatcher(resource.getPath() + ".html", new RequestDispatcherOptions()).forward(request, response);


            
However, since they both listen on the same path and servlet just keeps executing itself I get Recursion too deep exception...
To solve this have used approach with ServletResolver service:

final Servlet servlet = servletResolver.resolveServlet(request.getResource(), "/apps/indexing/components/pages/page/page.jsp"); request.setAttribute("data", dataFromAnotherSystem); servlet.service(request, response);


Now, when I call the servlet it first triggers servlet to assemble the data from indexing system and then triggers the cq:Template by calling it's root jsp file.
While it works, it doesn't feel like the best approach to this problem.


What would be a better approach ?


Thanks, Peter

1 Accepted Solution

Avatar

Correct answer by
Employee

Hi Peter,

This is how I would do this:

RequestDispatcherOptions options = new RequestDispatcherOptions(); options.setReplaceSelectors("page"); RequestDispatcher requestDispatcher = request.getRequestDispatcher(request.getResource(), options); requestDispatcher.include(request, response);

HTH,

Justin

View solution in original post

2 Replies

Avatar

Correct answer by
Employee

Hi Peter,

This is how I would do this:

RequestDispatcherOptions options = new RequestDispatcherOptions(); options.setReplaceSelectors("page"); RequestDispatcher requestDispatcher = request.getRequestDispatcher(request.getResource(), options); requestDispatcher.include(request, response);

HTH,

Justin

Avatar

Employee Advisor

Hi,

I would reorganize this. Build a regular template/component to render the page and have the call to the external system as a separate OSGI service. When you move this service call to a dedicated OSGI service, it is better testable as when you have it in a servlet.

Jörg