I have a SlingServlet that implements a JSON query service (very similar to the AEM Query Builder servlet). It creates a SyntheticResource to respond with a JSP "view", which is the JSON to be served. This JSP uses a to include each result object, which are cq:Page nodes.
When the tries to include a node which can not be rendered, it results in a 400 error, but in a peculiar way. The error appears first, followed by the expected JSON (which is malformed, because the value that could not be included is missing). I am able to override the 400 error text, so as to return "null", but I can not get the error to appear inline.
Consider:
response.api.json.jsp
{
"metadata": {
"page": ${pageIndex},
},
"data": [
<%
String[] results = (String[])slingRequest.getAttribute("results");
int i = 0;
if (results != null) {
for (String path : results) {
if (i > 0) {
%>
,
<%
}
%>
<sling:include path="<%=path%>"/>
<%
i++;
}
}
%>
]
}
the current response
<400.jsp error message up here>
{
"metadata": {
"page": 0,
},
"data": [
, // <- failed to include the path
{
"key1": , // <- failed to include the value string/object/etc
"key2": "value2"
}
]
}
the expected response
{
"metadata": {
"page": 0,
},
"data": [
<400.jsp error message>, // <- failed to include the path
{
"key1": <400.jsp error message>, // <- failed to include the value string/object/etc
"key2": "value2"
}
]
}
the expected response (assuming 400.jsp contains only "null")
{
"metadata": {
"page": 0,
},
"data": [
null, // <- failed to include the path
{
"key1": null, // <- failed to include the value string/object/etc
"key2": "value2"
}
]
}
Is there any way to get the error page (400.jsp) to appear inline, so that I can return null?
More info
response.api.json.jsp (main "view" for the service response)
{
"metadata": {
"page": ${pageIndex},
},
"data": [
<%
String[] results = (String[])slingRequest.getAttribute("results");
int i = 0;
if (results != null) {
for (String path : results) {
if (i > 0) {
%>
,
<%
}
%>
<sling:include path="<%=path%>"/>
<%
i++;
}
}
%>
]
}
page/api.json.jsp (data[] nodes included by the response.api.json.jsp)
{
"uid": <%=getFormattedString("jcr:uuid", properties)%>,
"pageTitle": <sling:include path="pageTitle"/>, // text component
"body": <sling:include path="body"/> // parsys component
}
text/api.json.jsp (pageTitle node included by each page/api.json.jsp)
{
"text": <%=getFormattedString("text", properties)%>,
"lastModified": <%=getFormattedDate("jcr:lastModified", properties)%>,
"resourceType": <%=getFormattedString("sling:resourceType", properties)%>
}
parsys/api.json.jsp (body node included by each page/api.json.jsp)
{
"resourceType": "${properties['sling:resourceType']}",
"children": [
<%
NodeIterator children = currentNode.getNodes();
int i = 0;
if (children != null && children.getSize() > 0) {
while (children.hasNext()) {
Node child = children.nextNode();
if (i > 0) {
%>
,
<%
}
%>
<sling:include path="<%=child.getPath()%>"/> // any component resource type
<%
i++;
}
}
%>
]
}