Search code examples
aemsling

CQ5.5 get .infinity.json of a resource in a servlet


If we had component resource set up as such:

  • mycomponent
    • mycomponent.jsp
    • mycomponent.JSON.jsp

We can Assume it will work as such:

  • /path/to/mycomponent.html => see html
  • /path/to/mycomponent.json => see my json

Also in a servlet we might be able to do something like

Resource myResource = resourceResolver.getResource(request, "path/to/mycomponent");

I'm just curious how I might be able to get the .json representation in a servlet context as well.

I've done something that sort of solves this, but I was wondering if there was an alternate way, as this solution has huge limitations. Basically I load the Node at the path and do JSONDumps of the Node and it's children. This would allow me to get a larger set of JSON from the resource at the mycomponent.getPath(), but it doesn't allow me the ability to pull the custom JSON view i've created via mycomponent.JSON.jsp.

any thoughts/advice would be great, thank you.


Solution

  • The title of the question sounds like you want wanted to get the equivalent of a cURL/AJAX call to /path/to/mycomponent.-1.json but within a Servlet or other Java class.

    You can use the org.apache.sling.commons.json.jcr.JsonItemWriter class to dump a JCR node into a JSONObject with infinite recursion. By passing in a Set into the constructor you can specify which properties to exclude from the final JSON. See http://www.nateyolles.com/blog/2015/12/converting-aem-sling-resources-to-json for more examples.

    Resource resource = resolver.getResource("/content/my-app/my-page");
    
    if (resource != null) {
        Node node = resource.adaptTo(Node.class);
        StringWriter stringWriter = new StringWriter();
        JsonItemWriter jsonWriter = new JsonItemWriter(null);
    
        try {
            jsonWriter.dump(node, stringWriter, -1);
            JSONObject jsonObject = new JSONObject(stringWriter.toString());
        } catch (RepositoryException | JSONException e) {
            LOGGER.error("Could not create JSON", e);
        }
    }
    

    You can also use the org.apache.sling.engine.SlingRequestProcessor class as Bertrand discussed above. See http://www.nateyolles.com/blog/2015/10/get-rendered-html-for-an-aem-resource-or-component for more examples.

    @Reference
    private RequestResponseFactory requestResponseFactory;
    
    @Reference
    private SlingRequestProcessor requestProcessor;
    
    @Override
    protected void doGet(SlingHttpServletRequest request, SlingHttpServletResponse response)
            throws ServletException, IOException {
    
        /* Setup request */
        HttpServletRequest req = requestResponseFactory.createRequest("GET",
                "/content/my-app/my-page.-1.json");
    
        /* Setup response */
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        HttpServletResponse resp = requestResponseFactory.createResponse(out);
    
        /* Process request through Sling */
        requestProcessor.processRequest(req, resp, request.getResourceResolver());
        String jsonString = out.toString();
    }