Search code examples
aemsling

AEM::Writing outputstream to response object


I am working on a requirement to display a PDF document on the page. This document is pulled from a back end service in the form of byte array. I convert this byte array to outputstream and then write it to the response in a Sling Servlet. The Servlet gets the byte array from an OSGi Service. I am wondering if is possible for me to use a Sling Model instead of a Sling Servlet. The Sling Model would call the OSGi Service to get the byte array but I am not sure about the next steps. I injected the response object in Sling Model using

@SlingObject
private SlingHttpServletResponse response;

But it won't do the trick. Any guidance would be helpful.

Thanks in advance


Solution

  • Disclaimer

    Without knowing your specific requirements I would recommend using a servlet instead of using a Sling Model. A Sling Model is meant to be a representation of a JCR resource in the repository not be abused as servlet.


    A Sling Model has a different "life cycle" than a servlet. While a servlet is instantiated as a OSGi service/component (which is a singleton in most cases) a Sling Model can be instantiated multiple times during a single request. So be aware of that difference and the consequences.

    That said, you have two options to write the PDF to the response with a Sling Model:

    1. During the initialisation of the Sling Model
    2. When a specific method is called

    Example for 1:

    @Model(adaptables = SlingHttpServletRequest.class)
    public class MyModel {
    
        @SlingObject
        private SlingHttpServletResponse response;
    
        @OSGiService
        private PDFService pdfService;
    
        @PostConstruct
        public void init() {
            response.setContentType("application/pdf");
    
            [... code to write PDF to response ...]
        }
    }
    

    The method annotated with @PostConstruct is called after all annotated fields are injected, so that you can run your initialisation code.

    Example for 2:

    @Model(adaptables = SlingHttpServletRequest.class)
    public class MyModel {
    
        @SlingObject
        private SlingHttpServletResponse response;
    
        @OSGiService
        private PDFService pdfService;
    
        public void writePDFtoResponse() {
            response.setContentType("application/pdf");
    
            [... code to write PDF to response ...]
        }
    }
    

    Obviously, with the second example you would have to have some kind of code that instantiates the model and calls writePDFtoResponse().