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