4

I created a sling servlet skeleton like so...

@SlingServlet(paths = "/bin/foo/bar", methods = "POST")
public class FooBarServlet extends SlingAllMethodsServlet {

    private final Logger LOGGER = LoggerFactory.getLogger(this.getClass());
    @Override
    protected void doPost(SlingHttpServletRequest request, SlingHttpServletResponse response) throws ServletException, IOException {

        response.setHeader("Content-Type", "text/plain");
        response.getWriter().write("foo bar");
        LOGGER.info("hello world");
    }
}

I created an edit config for my component

<jcr:root xmlns:cq="http://www.day.com/jcr/cq/1.0"
    xmlns:jcr="http://www.jcp.org/jcr/1.0"
    jcr:primaryType="cq:EditConfig">
    <cq:listeners jcr:primaryType="cq:EditListenersConfig"
                  afteredit="myapp.components.foobar" />
</jcr:root>

I created an cq:ClientLibraryFolder and added this js to it

var myapp = { components : {}  };
myapp.components.foobar = function(component, reloadPage) {
    var oncomplete = function(success) {
        if (success) {
            if (reloadPage) document.location.reload();
            else component.refreshSelf();
        } else
            console.log('could not foobar on component ' + component.path);
        };

        CQ.HTTP.post('/bin/boo/bar', oncomplete, { path : component.path });
};

My page loads, my component loads, my clientlib js loads, I see no errors in console. I edit my component and hit ok. My servlet is hit, I tail the log server side and see no errors. I see no errors client side when I open the console to trace. My response is 200 ok. Everything looks great! Except that I keep getting an "Unspecified Error" at the top right corner of my browser

Unspecified Error

Does anyone know where I even begin to troubleshoot this given that I am seeing no errors on the server side log, and no errors on the client side console?

Update

Thanks to @rakhi4110 for the reference to CQ.HTTP. I was able to come up with some stuff from that documentation

First, setting the suppressErrorMsg flag hid the error message

CQ.HTTP.post('/bin/foo/bar', oncomplete, { path : component.path }, null, true);

Second, I do not like to suppress things, so I tried to craft my response like so

{
    "headers" :
    {
         "Status":200,
         "Message":"foo bar"
    }
}

However that did nothing.

Third, while looking at the CQ.HTTP api, I noticed that a lot of it was depricated in favor of CQ.shared.HTTP. Simply using the post function from that, without the suppress, worked

CQ.shared.HTTP.post('/bin/foo/bar', oncomplete, { path : component.path });

For now I'm sticking with option #3 until I can figure out the proper json response.

Juan Ayala
  • 3,388
  • 2
  • 19
  • 24

3 Answers3

2

The Unspecified error is due to the default config that is getting applied to CQ.HTTP.post()

It tries to retrieve the message from the response header and notifies it to the user. Since your custom servlet doesn't provide any such message, you received this notification.

It is possible to suppress this notification by setting the suppressErrorMsg parameter as true. i.e.,

CQ.HTTP.post('/bin/boo/bar', oncomplete, { path : component.path }, null, true);

On futher observation, it appears that the notification message is built from the response when

  1. The response is HTML
  2. The response contains an HTML tag with id as "Message". In such cases the content of the tag is considered as the message.

A sample HTML response using which the notification message might work is

<html>
<head>
    <title>OK</title>
</head>
<body>
<h1>OK</h1>
<table>
    <tbody>
        <tr>
            <td>Status</td>
            <td><div id="Status">200</div></td>
        </tr>
        <tr>
            <td>Message</td>
            <td><div id="Message">Demo Notification Message</div></td>
        </tr>
    </tbody>
</table>
</body>
</html>

For further config, refer to CQ.HTTP

rakhi4110
  • 9,253
  • 2
  • 30
  • 49
  • The suppress worked. I tried to create a json response like { "headers": { "Status": 200, "Message": "foo bar" }}. Any pointers on a proper json response? – Juan Ayala Sep 24 '14 at 15:54
0
@Properties({
    @Property(name = "sling.servlet.extensions", value = "json"),
    @Property(name = "sling.servlet.methods", value = "POST"),
    @Property(name = "service.description", value = " foo bar Servlet")
}

in servlet

@Override
    protected final void doPost(final SlingHttpServletRequest request, final SlingHttpServletResponse response)
        throws ServletException, IOException {
        final String value = request.getRequestParameter("value").getString();
            // create response

        response.setContentType("application/json");
        response.setCharacterEncoding("utf-8");

        try {
            final JsonGenerator generator = FACTORY.createJsonGenerator(response.getWriter());

            MAPPER.writeValue(generator, Collections.singletonMap("Message", "success"));
        } catch (final JsonGenerationException jge) {
            LOG.error("error generating JSON response", jge);
        } catch (final JsonMappingException jme) {
            LOG.error("error mapping JSON response", jme);
        } catch (final IOException ioe) {
            LOG.error("error writing JSON response", ioe);
        }
    }

In dialog do something like

postfunction="function(value) {
    var dialog = this.findParentByType('dialog');
    var url = CQ.HTTP.addParameter(dialog.path + '.json', 'value', value);
    var result = CQ.HTTP.eval(url);
    return result;
}
Tomasz Szymulewski
  • 2,003
  • 23
  • 23
amitdeol
  • 279
  • 1
  • 14
  • can you answer this question http://stackoverflow.com/questions/29745246/how-to-validate-a-field-using-cq-http-post-method-in-adobe-cq5/29768664?noredirect=1#comment47673194_29768664 – user2142786 Apr 22 '15 at 06:30
-1

You can use one of the ootb sling classes to generate the proper response:

HtmlResponse --> For responses in HTML format

JSONResponse --> For responses in JSON format

The all inherit from https://sling.apache.org/apidocs/sling7/org/apache/sling/servlets/post/AbstractPostResponse.html and you can use one of their onXXX method to write your changes.

Example:

JSONResponse result = new JSONResponse();
result.setStatus(200, "Content changed");
result.onChange;
result.onCopied;
result.onCreated;
result.onDeleted;
result.onModified;
result.onMoved;
boolean setStatus = true;

result.send(slingHttpServletResponse, setStatus);
  • I do not agree with this. If the linked page changes, that means the answer is no longer correct/valid. I would refrain from copy&paste in this case. I would not make this a general rule. – Nono Junang Jan 05 '16 at 05:08