• Document Up to Date

Render Page Components as JSON

CaaS (Content as a Service) is a common need in today’s multi-channel world. Typically CaaS use cases require that the content is devoid of presentation markup so that the consumer can present the content as it desires. Other times comsumers may wish to pull rendered content. This cookbook provides a simple REST example (a single Groovy based rest controller script) that will give you a way to render all of the components associated to a page.

Prerequisites

  • None

Step 1: Create a REST Controller

  • Under Scripts/rest right click and click create controller
    • Enter get-rendered-components.get as the controller name

  • Add the following code to the controller.

  1import java.io.ByteArrayOutputStream
  2import java.io.IOException
  3import java.io.PrintWriter
  4
  5import javax.servlet.Filter
  6import javax.servlet.FilterChain
  7import javax.servlet.FilterConfig
  8import javax.servlet.ServletException
  9import javax.servlet.ServletOutputStream
 10import javax.servlet.ServletRequest
 11import javax.servlet.ServletResponse
 12import javax.servlet.http.HttpServletRequest
 13import javax.servlet.http.HttpServletResponse
 14import javax.servlet.http.HttpServletResponseWrapper
 15import javax.servlet.WriteListener
 16import groovy.util.XmlSlurper
 17
 18def result = [:]
 19def targetPage = params.pageId
 20
 21if (targetPage != null) {
 22        result.page = targetPage
 23
 24        def pageItem = siteItemService.getSiteItem(targetPage)
 25
 26        if (pageItem != null) {
 27                def componentPaths = pageItem.queryValues("//include")
 28                result.components = []
 29
 30                if (componentPaths != null) {
 31                        componentPaths.each { componentPath ->
 32                                if (componentPath.endsWith(".xml") && !componentPath.startsWith("/site/website") ) {
 33                                        logger.info("Including component ${componentPath} into JSON response")
 34
 35                                        def component = [:]
 36                                        component.id = componentPath
 37
 38                                        // wrap the response to capture the output
 39                                        def wrappedResponse = new CapturingResponseWrapper(response)
 40
 41                                        // "include" the page that does the actual work
 42                                        request.getRequestDispatcher("/crafter-controller/component?path=" + componentPath).include(request, wrappedResponse)
 43
 44                                        // get the captured output, parse it and prepare the actual response
 45                                        def capturedOut = wrappedResponse.getCaptureAsString()
 46
 47                                        component.markup = capturedOut
 48
 49                                        result.components.add(component)
 50                                }
 51                        }
 52                } else {
 53                        result.message = "No components found"
 54                }
 55        } else {
 56                result.message = "Page '${targetPage}` not found"
 57        }
 58} else {
 59        result.message = "Parameter pageId is required."
 60}
 61
 62return result
 63
 64protected class CapturingResponseWrapper extends HttpServletResponseWrapper {
 65
 66        private final ByteArrayOutputStream capture
 67        private ServletOutputStream output
 68        private PrintWriter writer
 69
 70        public CapturingResponseWrapper(HttpServletResponse response) {
 71                super(response)
 72                capture = new ByteArrayOutputStream(response.getBufferSize())
 73        }
 74
 75        @Override
 76        public ServletOutputStream getOutputStream() {
 77                if (writer != null) {
 78                        throw new IllegalStateException("getWriter() has already been called on this response.")
 79                }
 80
 81                if (output == null) {
 82                        output = new ServletOutputStream() {
 83
 84                                @Override
 85                                public void write(int b) throws IOException {
 86                                        capture.write(b)
 87                                }
 88
 89                                @Override
 90                                public void flush() throws IOException {
 91                                        capture.flush()
 92                                }
 93
 94                                @Override
 95                                public void close() throws IOException {
 96                                        capture.close()
 97                                }
 98
 99                                @Override
100                                public void setWriteListener(WriteListener writeListener) {
101                                }
102
103                                @Override
104                                public boolean isReady() {
105                                        return true
106                                }
107                        }
108                }
109
110                return output
111        }
112
113        @Override
114        public PrintWriter getWriter() throws IOException {
115                if (output != null) {
116                        throw new IllegalStateException("getOutputStream() has already been called on this response.")
117                }
118
119                if (writer == null) {
120                        writer = new PrintWriter(new OutputStreamWriter(capture, getCharacterEncoding()))
121                }
122
123                return writer
124        }
125
126        @Override
127        public void flushBuffer() throws IOException {
128                super.flushBuffer()
129
130                if (writer != null) {
131                        writer.flush()
132                }
133                else if (output != null) {
134                        output.flush()
135                }
136        }
137
138        public byte[] getCaptureAsBytes() throws IOException {
139                if (writer != null) {
140                        writer.close()
141                }
142                else if (output != null) {
143                        output.close()
144                }
145
146                return capture.toByteArray()
147        }
148
149        public String getCaptureAsString() throws IOException {
150                return new String(getCaptureAsBytes(), getCharacterEncoding())
151        }
152
153}

Step 2: Execute the Service