Trying to get the rendered HTML of a component on the server side is still easy, but requires a little more work. Without knowing the inner workings of Sling, you might use Java's java.net.HttpUrlConnection class to construct and make an HTTP request from within your application to your application.
The better way is to use the SlingRequestProcessor service as the entry point into Sling's process. The processRequest method of the SlingRequestProcessor takes an HttpServletRequest, HttpServletResponse, and Resource Resolver as parameters. The only trick is that you need to provide a request that enables you to set the request path and a response that enables you to get the OutputStream as a String.
AEM provides the RequestResponseFactory where you can easily get such a request and response.
AemResourceResolutionServlet.java
package com.nateyolles.aem;
import org.apache.felix.scr.annotations.Reference;
import org.apache.felix.scr.annotations.sling.SlingServlet;
import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.SlingHttpServletResponse;
import org.apache.sling.api.servlets.SlingSafeMethodsServlet;
import org.apache.sling.engine.SlingRequestProcessor;
import com.day.cq.contentsync.handler.util.RequestResponseFactory;
import com.day.cq.wcm.api.WCMMode;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
@SlingServlet(paths={"/bin/foo"})
public class AemResourceResolutionServlet extends SlingSafeMethodsServlet {
/** Service to create HTTP Servlet requests and responses */
@Reference
private RequestResponseFactory requestResponseFactory;
/** Service to process requests through Sling */
@Reference
private SlingRequestProcessor requestProcessor;
@Override
protected void doGet(SlingHttpServletRequest request, SlingHttpServletResponse response) throws ServletException, IOException {
/* The resource path to resolve. Use any selectors or extension. */
String requestPath = "/content/myapp/us/en/index/jcr:content/myparsys/mycomponent_f93d.html";
/* Setup request */
HttpServletRequest req = requestResponseFactory.createRequest("GET", requestPath);
WCMMode.DISABLED.toRequest(req);
/* Setup response */
ByteArrayOutputStream out = new ByteArrayOutputStream();
HttpServletResponse resp = requestResponseFactory.createResponse(out);
/* Process request through Sling */
requestProcessor.processRequest(req, resp, request.getResourceResolver());
String html = out.toString();
}
}
You'll need to provide your own mock request and response in Apache Sling. Fortunately, it already exists. You need the HttpRequest, HttpResponse, and TestServletOutputStream classes.
SlingResourceResolutionServlet.java
package com.nateyolles.sling;
import org.apache.felix.scr.annotations.Reference;
import org.apache.felix.scr.annotations.sling.SlingServlet;
import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.SlingHttpServletResponse;
import org.apache.sling.api.servlets.SlingSafeMethodsServlet;
import org.apache.sling.engine.SlingRequestProcessor;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@SlingServlet(paths={"/bin/foo"})
public class SlingResourceResolutionServlet extends SlingSafeMethodsServlet {
/** Service to process requests through Sling */
@Reference
private SlingRequestProcessor requestProcessor;
@Override
protected void doGet(SlingHttpServletRequest request, SlingHttpServletResponse response) throws ServletException, IOException {
/* The resource path to resolve. Use any selectors or extension. */
String requestPath = "/content/myapp/us/en/index/jcr:content/myparsys/mycomponent_f93d.html";
/*
* Create a fake request and fake response. The response adds a method to make the HTML accessible.
* You need the following three files from Apache Sling:
*
* https://github.com/apache/sling/blob/trunk/testing/junit/scriptable/src/main/java/org/apache/sling/junit/scriptable/HttpRequest.java
* https://github.com/apache/sling/blob/trunk/testing/junit/scriptable/src/main/java/org/apache/sling/junit/scriptable/HttpResponse.java
* https://github.com/apache/sling/blob/trunk/testing/junit/scriptable/src/main/java/org/apache/sling/junit/scriptable/TestServletOutputStream.java
*/
final HttpRequest req = new HttpRequest(requestPath);
final HttpResponse resp = new HttpResponse();
/* Process request through Sling */
requestProcessor.processRequest(req, resp, request.getResourceResolver());
String html = resp.getContent();
}
}
You will need to include the org.apache.sling.engine dependency in your pom file. If your bundle resolves but your component remains unsatisfied, make sure sure you've included the package in the Import-Package section of your maven-bundle-plugin.
Style system doesn't work in this case.
ReplyDelete