Including a JSP into a sling servlet

aem, osgi, sling

Solution

Including scripts

Use following construction to include script `/apps/test.jsp` inside the servlet and pass some values (bindings) to it:

@Reference
private ServletResolver servletResolver;

public void doGet(SlingHttpServletRequest request, SlingHttpServletResponse response) throws ServletException, IOException {
    Servlet servlet = servletResolver.resolveServlet(request.getResource(), "/apps/test.jsp");
    request.setAttribute("sampleBinding", "bindingValue");
    servlet.service(request, response);
}

The script itself may look like this:

<%@page session="false" contentType="text/html; charset=utf-8"
%><%@include file="/libs/foundation/global.jsp"%>

Binding value: ${sampleBinding}

Using models

You may also consider a second approach - don't create servlet for each component, but stick to JSP and at the beginning of each script create a model object. Sample script:

<%@page session="false" contentType="text/html; charset=utf-8"
%><%@include file="/libs/foundation/global.jsp"%><%
  pageContext.setAttribute("model", new MyModel(slingRequest, slingResponse));
%>

Value from model: ${model.value}

And sample model:

public class MyModel {

    private final SlingHttpServletRequest request;

    private final SlingHttpServletResponse response;

    public MyModel(SlingHttpServletRequest request, SlingHttpServletResponse response) {
        this.request = request;
        this.response = response;
    }

    public String getValue() {
        // you may use request & response objects here
        return "sample value";
    }
}

If you like this approach, you may use a framework that makes writing such models easier. Two interesting solutions are:

- Sling models

- Slice

Problem

I'm currently working on a small project, trying to help someone figure out how to wire up a component. Ideally we'd like to do 2 things: - have a jsp that renders the template - have all our business login in a SlingAllMethodServlet Gist of servlet definition: ``` package definition... import statements... @SuppressWarnings("serial") @SlingServlet( resourceTypes="path/to/my/component", methods="GET", extentions="HTML") @Properties({ @Property(name="service.pid", value="<my service class>", propertyPrivate=false), @Property(name="service.description",value="<description>", propertyPrivate=false), @Property(name="service.vendor",value="<company>", propertyPrivate=false) }) public class MyComponentServlet extends SlingAllMethodsServlet { @Override protected void doGet (SlingHttpServletRequest pRequest, SlingHttpServletResponse pResponse) throws ServletException, IOException { ... } @Override protected void doPost(SlingHttpServletRequest pRequest, SlingHttpServletResponse pResponse) throws ServletException, IOException { ... } } ``` This actually works great, when I include the component on a page this runs. The problem (as you might expect) is that I'm consuming the HTML extension here. So "component.jsp" isn't getting picked up for render. I'm curious if someone knows how to do one of the following: Include the JSP for render in this servlet (i.e. i saw some interesting stuff on 6dimensions regarding pageContext#include and pageContext#pushBody: http://labs.sixdimensions.com/blog/2013-08-13/cq-resource-inclusion-servlet/) Set up this servlet, so that this servlet runs at that path before the JSP is rendered. Any insight would be great. thank you, brodie

Original source