【问题标题】:CQ5 component aftereditCQ5 组件编辑后
【发布时间】:2014-09-23 19:01:09
【问题描述】:

我像这样创建了一个 sling servlet 骨架......

@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");
    }
}

我为我的组件创建了一个编辑配置

<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>

我创建了一个cq:ClientLibraryFolder 并添加了这个js

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 });
};

我的页面加载,我的组件加载,我的 clientlib js 加载,我在控制台中没有看到任何错误。我编辑我的组件并点击确定。我的 servlet 被命中,我跟踪日志服务器端并没有看到任何错误。当我打开控制台进行跟踪时,我看不到客户端错误。我的回答是 200 好的。一切看起来都很棒!除了我在浏览器的右上角不断收到“未指定的错误”

鉴于我在服务器端日志上没有看到任何错误,在客户端控制台上也没有任何错误,有谁知道我什至从哪里开始解决这个问题?

更新

感谢@rakhi4110 对CQ.HTTP 的引用。我能够从该文档中找到一些东西

首先,设置suppressErrorMsg标志隐藏错误信息

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

第二,我不喜欢压抑的东西,所以我试着像这样制作我的回应

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

然而这并没有起到任何作用。

第三,在查看 CQ.HTTP api 时,我注意到其中很多内容被贬低为支持CQ.shared.HTTP。简单地使用 post 函数,没有抑制,工作

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

现在我坚持使用选项 #3,直到我能找出正确的 json 响应。

【问题讨论】:

    标签: aem sling


    【解决方案1】:

    Unspecified error 是由于应用到CQ.HTTP.post() 的默认配置

    它尝试从响应头中检索消息并将其通知给用户。由于您的自定义 servlet 未提供任何此类消息,因此您收到了此通知。

    可以通过将suppressErrorMsg 参数设置为true 来抑制此通知。即,

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

    进一步观察,通知消息似乎是根据响应构建的

    1. 响应是 HTML
    2. 响应包含一个 ID 为“消息”的 HTML 标记。在这种情况下,标签的内容被视为消息。

    通知消息可能使用的示例 HTML 响应是

    <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>
    

    更多配置请参考CQ.HTTP

    【讨论】:

    • 压制奏效了。我试图创建一个 json 响应,如 {“headers”:{“Status”:200,“Message”:“foo bar”}}。有关正确 json 响应的任何指针?
    【解决方案2】:
    @Properties({
        @Property(name = "sling.servlet.extensions", value = "json"),
        @Property(name = "sling.servlet.methods", value = "POST"),
        @Property(name = "service.description", value = " foo bar 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);
            }
        }
    

    在对话框中做类似的事情

    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;
    }
    

    【讨论】:

    【解决方案3】:

    您可以使用 ootb 吊索类之一来生成正确的响应:

    HtmlResponse --> HTML 格式的响应

    JSONResponse --> JSON 格式的响应

    全部继承自https://sling.apache.org/apidocs/sling7/org/apache/sling/servlets/post/AbstractPostResponse.html,您可以使用其中一种 onXXX 方法来编写您的更改。

    例子:

    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);
    

    【讨论】:

    • 我不同意这一点。如果链接页面发生更改,则意味着答案不再正确/有效。在这种情况下,我会避免复制和粘贴。我不会将此作为一般规则。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多