Your achievements

Level 1

0% to

Level 2

Tip /
Sign in

Sign in to Community

to gain points, level up, and earn exciting badges like the new
BedrockMission!

Learn More

View all

Sign in to view all badges

RequestResponseFactory and FakeRequest

Avatar

Avatar
Level 1
Linda_Jufferma1
Level 1

Likes

0 likes

Total Posts

5 posts

Correct Reply

0 solutions
View profile

Avatar
Level 1
Linda_Jufferma1
Level 1

Likes

0 likes

Total Posts

5 posts

Correct Reply

0 solutions
View profile
Linda_Jufferma1
Level 1

15-03-2018

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

Replies

Avatar

Avatar
Validate 25
Level 10
smacdonald2008
Level 10

Likes

1,409 likes

Total Posts

12,671 posts

Correct Reply

2,278 solutions
Top badges earned
Validate 25
Validate 10
Validate 1
Give back 900
Give back 600
View profile

Avatar
Validate 25
Level 10
smacdonald2008
Level 10

Likes

1,409 likes

Total Posts

12,671 posts

Correct Reply

2,278 solutions
Top badges earned
Validate 25
Validate 10
Validate 1
Give back 900
Give back 600
View profile
smacdonald2008
Level 10

15-03-2018

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);

Avatar

Avatar
Level 1
Linda_Jufferma1
Level 1

Likes

0 likes

Total Posts

5 posts

Correct Reply

0 solutions
View profile

Avatar
Level 1
Linda_Jufferma1
Level 1

Likes

0 likes

Total Posts

5 posts

Correct Reply

0 solutions
View profile
Linda_Jufferma1
Level 1

16-03-2018

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).

Avatar

Avatar
Validate 25
Level 10
smacdonald2008
Level 10

Likes

1,409 likes

Total Posts

12,671 posts

Correct Reply

2,278 solutions
Top badges earned
Validate 25
Validate 10
Validate 1
Give back 900
Give back 600
View profile

Avatar
Validate 25
Level 10
smacdonald2008
Level 10

Likes

1,409 likes

Total Posts

12,671 posts

Correct Reply

2,278 solutions
Top badges earned
Validate 25
Validate 10
Validate 1
Give back 900
Give back 600
View profile
smacdonald2008
Level 10

16-03-2018

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.

Avatar

Avatar
Validate 25
Level 10
smacdonald2008
Level 10

Likes

1,409 likes

Total Posts

12,671 posts

Correct Reply

2,278 solutions
Top badges earned
Validate 25
Validate 10
Validate 1
Give back 900
Give back 600
View profile

Avatar
Validate 25
Level 10
smacdonald2008
Level 10

Likes

1,409 likes

Total Posts

12,671 posts

Correct Reply

2,278 solutions
Top badges earned
Validate 25
Validate 10
Validate 1
Give back 900
Give back 600
View profile
smacdonald2008
Level 10

16-03-2018

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)

Avatar

Avatar
Level 1
Linda_Jufferma1
Level 1

Likes

0 likes

Total Posts

5 posts

Correct Reply

0 solutions
View profile

Avatar
Level 1
Linda_Jufferma1
Level 1

Likes

0 likes

Total Posts

5 posts

Correct Reply

0 solutions
View profile
Linda_Jufferma1
Level 1

20-03-2018

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.

Avatar

Avatar
Level 1
sherrylynnh1858
Level 1

Likes

0 likes

Total Posts

3 posts

Correct Reply

0 solutions
View profile

Avatar
Level 1
sherrylynnh1858
Level 1

Likes

0 likes

Total Posts

3 posts

Correct Reply

0 solutions
View profile
sherrylynnh1858
Level 1

14-05-2018

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:

Get the rendered HTML for an AEM resource, component or page - Adobe Experience Manager | AEM/CQ | A...

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.

Avatar

Avatar
Level 1
Linda_Jufferma1
Level 1

Likes

0 likes

Total Posts

5 posts

Correct Reply

0 solutions
View profile

Avatar
Level 1
Linda_Jufferma1
Level 1

Likes

0 likes

Total Posts

5 posts

Correct Reply

0 solutions
View profile
Linda_Jufferma1
Level 1

14-05-2018

I did not overcome the issue; for pages we're using an HTTP request in stead of the requestResponseFactory solution.

Avatar

Avatar
Coach
Employee
Jörg_Hoh
Employee

Likes

1,133 likes

Total Posts

3,161 posts

Correct Reply

1,079 solutions
Top badges earned
Coach
Give back 600
Ignite 5
Ignite 3
Ignite 1
View profile

Avatar
Coach
Employee
Jörg_Hoh
Employee

Likes

1,133 likes

Total Posts

3,161 posts

Correct Reply

1,079 solutions
Top badges earned
Coach
Give back 600
Ignite 5
Ignite 3
Ignite 1
View profile
Jörg_Hoh
Employee

14-05-2018

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

Avatar

Avatar
Level 1
sherrylynnh1858
Level 1

Likes

0 likes

Total Posts

3 posts

Correct Reply

0 solutions
View profile

Avatar
Level 1
sherrylynnh1858
Level 1

Likes

0 likes

Total Posts

3 posts

Correct Reply

0 solutions
View profile
sherrylynnh1858
Level 1

17-05-2018

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.