Hi,
We use the RequestResponseFactory to retrieve content from AEM inside an OSGi bundle:
The service is obtained through:
@Reference
private RequestResponseFactory requestResponseFactory;
And used like this:
final HttpServletRequest servletRequest = requestResponseFactory.createRequest("GET", path);
WCMMode.DISABLED.toRequest(servletRequest);
final ByteArrayOutputStream responseOutputStream = new ByteArrayOutputStream();
final HttpServletResponse servletResponse = requestResponseFactory.createResponse(responseOutputStream);
servletResponse.getWriter().flush();
byte[] content = responseOutputStream.toByteArray();
Most methods of the FakeRequest class return null; e.g. getHeader, getServerName.
FakeRequest seems to cause errors that normal requests don't, e.g.:
15.03.2018 11:22:30.322 *ERROR* [pool-5-thread-2] com.day.cq.wcm.tags.IncludeTag Error while executing script view.jsp
org.apache.sling.api.scripting.ScriptEvaluationException:
at org.apache.sling.scripting.core.impl.DefaultSlingScript.call(DefaultSlingScript.java:388)
at org.apache.sling.scripting.core.impl.DefaultSlingScript.eval(DefaultSlingScript.java:171)
at org.apache.sling.scripting.core.impl.DefaultSlingScript.service(DefaultSlingScript.java:463)
at com.day.cq.wcm.tags.IncludeTag.includeScript(IncludeTag.java:176)
...
Caused by: java.lang.UnsupportedOperationException: null
at com.day.cq.contentsync.impl.handler.util.FakeRequest$FakeHttpSession.getAttribute(FakeRequest.java:64)
at org.apache.sling.scripting.jsp.jasper.runtime.PageContextImpl.doFindAttribute(PageContextImpl.java:470)
at org.apache.sling.scripting.jsp.jasper.runtime.PageContextImpl.findAttribute(PageContextImpl.java:455)
at org.apache.jsp.apps.lgi_002dforms.components.forms.honeypot.honeypot_jsp._jspService(honeypot_jsp.java:122)
where honeypot_jsp.java:122 is:
currentNode = (javax.jcr.Node) _jspx_page_context.findAttribute("currentNode");
which is compiled from this line in the JSP:
<cq:defineObjects />
We use the RequestResponseFactory with the SlingRequestProcessor for ContentSync handler and a customer service that uploads pages to an FTP server. Should we use RequestResponseFactory for these or is there a better method? How can we work around the issues described above?
Linda
Views
Replies
Total Likes
Can you point to the URL where you found this information. We can see if we can reproduce your issue.
Typically to get node information from the AEM JCR - you use code like this with a system user.
Map<String, Object> param = new HashMap<String, Object>();
param.put(ResourceResolverFactory.SUBSERVICE, "datawrite");
ResourceResolver resolver = null;
try {
//Invoke the adaptTo method to create a Session used to create a QueryManager
resolver = resolverFactory.getServiceResourceResolver(param);
session = resolver.adaptTo(Session.class);
Views
Replies
Total Likes
There's Retrieve the HTML contents of a cq:Page and RequestResponseFactory ("The Adobe AEM Quickstart and Web Application.") ...
I'm not trying to get node information, I'm trying to retrieve content (HTML and client libraries).
Views
Replies
Total Likes
Interesting - we do not have any HELPX examples on this use case. Let me try and find a better example than the one referencd in the URL. However - this provided a lot more detail on what you are trying to do.
Views
Replies
Total Likes
Here is a much better example of how to perform this use case. Nate is an internal Adobe Community member: Get the rendered HTML for an AEM resource, component or page - Adobe Experience Manager | AEM/CQ | A...
Of course, you can always use a Java URL object to read the HTML of a Page too -- Reading Directly from a URL (The Java™ Tutorials > Custom Networking > Working with URLs)
Views
Replies
Total Likes
I noticed I forgot to paste 1 line of code in my question (this would be line #5):
slingRequestProcessor.processRequest(servletRequest, servletResponse, resourceResolver);
I tried the code from https://gist.githubusercontent.com/nateyolles/1dc9f8699fce70916764/raw/e344a064804dc920f5fc7e79ec868... but calling that servlet (on /bin/foo) causes the same error:
Caused by: java.lang.UnsupportedOperationException: null
at com.day.cq.contentsync.impl.handler.util.FakeRequest$FakeHttpSession.getAttribute(FakeRequest.java:64)
at org.apache.sling.scripting.jsp.jasper.runtime.PageContextImpl.doFindAttribute(PageContextImpl.java:470)
at org.apache.sling.scripting.jsp.jasper.runtime.PageContextImpl.findAttribute(PageContextImpl.java:455)
at org.apache.jsp.apps.lgi_002dforms.components.forms.honeypot.honeypot_jsp._jspService(honeypot_jsp.java:122)
at org.apache.sling.scripting.jsp.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:725)
at org.apache.sling.scripting.jsp.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:502)
... 560 common frames omitted
I still suspect this is due to the FakeRequest object lacking certain implementations of the HttpServletRequest; tho I don't have the source for FakeRequest.java so I can't tell what's on line 64.
I may resort to doing an HTTP request for the page (on publisher:4503/content/path/to/page) tho the SlingRequestProcessor seems cleaner (if it works) and wouldn't add the overhead of an HTTP request.
Views
Replies
Total Likes
I too am encountering this problem for a specific instance of 6.3 but the line number is a little different:
Caused by: java.lang.UnsupportedOperationException: null
at com.day.cq.contentsync.impl.handler.util.FakeRequest$FakeHttpSession.getAttribute(FakeRequest.java:68)
at org.apache.sling.scripting.jsp.jasper.runtime.PageContextImpl.doFindAttribute(PageContextImpl.java:470)
at org.apache.sling.scripting.jsp.jasper.runtime.PageContextImpl.findAttribute(PageContextImpl.java:455)
at org.apache.jsp.apps.intel.dm.components.pages.data.head_jsp._jspService(head_jsp.java:121)
at org.apache.sling.scripting.jsp.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:725)
at org.apache.sling.scripting.jsp.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:502)
We take a copy of the rendered HTML and send it to our API that then analyses it.
Did you overcome the issue? Our OSGi component follows the same pattern as the aforementioned blog post:
Could this be something to do with session use as per Tip 1 found here:
Three AEM / DPS Tips - Blog - 6D Global
However the JSPs do not use "in page" sessions but session are being used.
Views
Replies
Total Likes
I did not overcome the issue; for pages we're using an HTTP request in stead of the requestResponseFactory solution.
Views
Replies
Total Likes
I ran about this issue some time ago: Sling - Users - Fake request/response classes
As follow up [SLING-5428] Move MockSlingHttpServletRequest+Response to org.apache.sling.servlet-helpers - ASF JIR... has been created and it should be available in a separate bundle you can deploy to your instance (not sure if it's provided ootb in AEM in the meanwhile).
Jörg
Views
Replies
Total Likes
Thanks Jorg and Linda for you replies.
Linda, I've tried the URL approach but find I get a 401
Jorg,
So I've tried to use Apache Sling :: Sling Servlet Helpers but don't appear to be able to get at the content... I can't be using the servlet helpers correctly?
I added the dependency to my pom as follows:
<dependency>
<groupId>org.apache.sling</groupId>
<artifactId>org.apache.sling.servlet-helpers</artifactId>
<version>1.1.2</version>
</dependency>
and replaced response and request with mock versions as you'll see below (I've commented them out). I had to move things around because MockSlingHttpServletRequest requires a ResourceResolver.
@SlingServlet(
paths={"/services/foo/bar"},
methods = "GET"
)
@Slf4j
public class MyAnalysisServlet extends SlingSafeMethodsServlet {
private static final long serialVersionUID = 1L;
private static final String HEADER_REFERRER = "referer";
private static final String EDITOR_PATH_PREFIX = "/editor.html";
@Reference
private transient RequestResponseFactory requestResponseFactory;
@Reference
private transient ResourceResolverFactory resourceResolverFactory;
@Reference
private transient SlingRequestProcessor requestProcessor;
@Override
protected void doGet(SlingHttpServletRequest request, SlingHttpServletResponse response) throws ServletException, IOException {
final String referrer = request.getHeader(HEADER_REFERRER);
handleRequest(request, response, referrer);
}
private void handleRequest(SlingHttpServletRequest request, SlingHttpServletResponse response, final String referrer) throws ServletException, IOException {
final String content = loadContent(referrer);
try {
sendResultResponse(request, response, referrer, content);
} catch (ExecutionException e) {
sendErrorOrThrow(response, e);
}
}
private String loadContent(String referrer) throws ServletException, IOException {
String contentPath = getContentPath(referrer);
final HttpServletRequest request = requestResponseFactory.createRequest("GET", contentPath);
WCMMode.PREVIEW.toRequest(request);
final ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
final HttpServletResponse response = requestResponseFactory.createResponse(outputStream);
// final MockSlingHttpServletResponse response = new MockSlingHttpServletResponse();
ResourceResolver resourceResolver = null;
try {
// ** the bundle is whitelisted as getAdministrativeResourceResolver(null) is deprecated **
resourceResolver = resourceResolverFactory.getAdministrativeResourceResolver(null);
// MockSlingHttpServletRequest request = new MockSlingHttpServletRequest(resourceResolver);
// WCMMode.PREVIEW.toRequest(request);
requestProcessor.processRequest(request, response, resourceResolver);
} catch (LoginException e) {
throw new ServletException("Error obtaining administrative resource resolver", e);
} finally {
if (resourceResolver != null) {
resourceResolver.close();
}
}
final String content = outputStream.toString(Charsets.UTF_8.name());
// strip HTML comments
return content.replaceAll("(?s)<!--.*?-->", "<!-- [Stripped comment placeholder] -->");
}
private String getContentPath(String referrer) throws MalformedURLException {
return //does stuff to the path;
}
private void sendResultResponse(SlingHttpServletRequest request, final SlingHttpServletResponse response, final String url, final String content) {
// does stuff
}
private void sendErrorOrThrow(SlingHttpServletResponse response, ExecutionException e) throws IOException, ServletException {
// does stuff
}
}
Any ideas/pointers?
Many thanks for you time.
Views
Replies
Total Likes
Views
Likes
Replies
Views
Likes
Replies