Rendering CQ templates as part of servlet call on the same resource | Community
Skip to main content
Peter_Puzanovs
Community Advisor
Community Advisor
October 16, 2015
Solved

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

  • October 16, 2015
  • 2 replies
  • 1365 views

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

This post is no longer active and is closed to new replies. Need help? Start a new post to ask your question.
Best answer by JustinEd3

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

2 replies

JustinEd3Adobe EmployeeAccepted solution
Adobe Employee
October 16, 2015

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

joerghoh
Adobe Employee
Adobe Employee
October 16, 2015

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