Adobe CQ5自定义servlet路径

时间:2012-06-25 17:50:42

标签: servlets adobe cq5

我正在尝试为某些节点添加一些json处理功能。所以我编写了从SlingSafeMethodsServlet扩展的自定义servlet,我需要在用户为以下URL进行GET时执行: /data/events/any_sequence/any_sequence.json / data /events/any_sequence/any_sequence.infinity.json 或者例如 /data/events/any_sequence/any_sequence.2.json 其中 any_sequence 当然意味着任何有效符号序列。

问题是我在吊索文档中找不到如何将此模板映射为网址。

我一直试图设置这样的属性:

@Component
@Service
@Properties({
    @Property(name = "sling.servlet.resourceTypes", value = "data/events/-/-"),
    @Property(name = "sling.servlet.extensions", value = "json"),
    @Property(name = "sling.servlet.methods", value = "GET"),
    @Property(name = "service.description", value = "JSON advanced renderer")
})

但它没有帮助。我检查了felix控制台,发现我的服务已经启动并运行,所以问题是如何设置url映射。所以我的问题是如何在我的情况下设置url映射来调用我的自定义servlet的doGet?

感谢。

6 个答案:

答案 0 :(得分:5)

据我所知,CQ5不提供在通配符URL上映射自定义servlet的功能。实现类似于我需要的目标的唯一方法是使用这个servlet选择器的一些唯一的,如下所示:

@Component
@Service
@Properties({
    @Property(name = "sling.servlet.resourceTypes", value = "sling/servlet/default"),
    @Property(name = "sling.servlet.extensions", value = "json"),
    @Property(name = "sling.servlet.selectors", value = "advanced"),
    @Property(name = "sling.servlet.methods", value = "GET"),
    @Property(name = "service.description", value = "JSON advanced renderer")
})

这段代码意味着如果我尝试在*.advanced.json选择器和扩展名的某个节点上进行GET,那么请求将被转发到我的自定义servlet。

请参阅http://apache-sling.73963.n3.nabble.com/Register-servlet-for-subtree-td84106.html

答案 1 :(得分:1)

我已经解决了这个问题,正如原始海报所希望的那样。所有其他答案实际上是“它无法完成”或“如果你愿意用选择器弄脏你干净的RESTful API,这就是一种方法”

如果您想保留您想象的干净API,请按照以下方式进行操作。这也适用于没有扩展名的Apis,例如/ myservice / mythings / 123123,其中123123是一些动态ID

创建两个文件:

  • ResourceProvider
  • 的Servlet

ResourceProvider

这样做的目的只是为了侦听/ data / events中的所有请求,然后在该虚拟路径上生成一个“资源”,这在JCR中实际上并不存在。

@Component
@Service(value=ResourceProvider.class)
@Properties({
        @Property(name = ResourceProvider.ROOTS, value = "data/events"),
        @Property(name = ResourceProvider.OWNS_ROOTS, value = "true")
})
public class ImageResourceProvider implements ResourceProvider  {

@Override
public Resource getResource(ResourceResolver resourceResolver, String path) {

    AbstractResource abstractResource;
    abstractResource = new AbstractResource() {
        @Override
        public String getResourceType() {
            return TypeServlet.RESOURCE_TYPE;
        }

        @Override
        public String getResourceSuperType() {
            return null;
        }

        @Override
        public String getPath() {
            return path;
        }

        @Override
        public ResourceResolver getResourceResolver() {
            return resourceResolver;
        }

        @Override
        public ResourceMetadata getResourceMetadata() {
            return new ResourceMetadata();
        }
    };

    return abstractResource;
}

@Override
public Resource getResource(ResourceResolver resourceResolver, HttpServletRequest httpServletRequest, String path) {
    return getResource(resourceResolver , path);
}

@Override
public Iterator<Resource> listChildren(Resource resource) {
    return null;
}
}

Servlet

现在您只需编写一个servlet来处理来自该路径的任何资源 - 但这是通过处理资源类型来完成的,该资源类型由在该路径上侦听的ResourceProvider生成。

@SlingServlet(
        resourceTypes = TypeServlet.RESOURCE_TYPE,
        methods = {"GET" , "POST"})
public class TypeServlet extends SlingAllMethodsServlet {


    static final String RESOURCE_TYPE = "mycompany/components/service/myservice";

    @Override
    protected void doGet(SlingHttpServletRequest request, SlingHttpServletResponse response) throws ServletException, IOException {

        final String [] pathParts = request.getResource().getPath().split("/");
        final String id = pathParts[pathParts.length-1];
        response.setContentType("text/html");
        PrintWriter out = response.getWriter();
        try {
            out.print("<html><body>Hello, received this id: " + id + "</body></html>");
        } finally {
             out.close();
        }
    }
}

答案 2 :(得分:0)

这是我用来完成类似任务的语法:

@Component(immediate = true, description = "JSON advanced renderer")
@Service(value = javax.servlet.Servlet.class)
@Properties(value = {
        @Property(name = "sling.servlet.extensions", value = { "json" }),
        @Property(name = "sling.servlet.methods", value = { "GET" }),
        @Property(name = "sling.servlet.paths", value = {
                        "/data/events/any_sequence/any_sequence",
                        "/data/events/any_sequence/any_sequence.infinity",
                        "/data/events/any_sequence/any_sequence.2"
        })
})

答案 3 :(得分:0)

我有类似的问题,我需要使用的通配符

@Service
@Component
@Properties({
        @Property(name = "sling.servlet.paths", value = "/bin/resolver/gb"),
        @Property(name = "sling.servlet.extensions", value = "*")
})
public class Test extends SlingAllMethodsServlet {
    @Override
    public void doGet(SlingHttpServletRequest request, SlingHttpServletResponse response) throws ServletException, IOException {
       PrintWriter out = response.getWriter();
       out.print("The path you used is:" + request.getPathInfo());
    }
}

呼叫是[服务器]:[端口] / bin /解析器/ gb。[通配符]

所以可以做的是:[服务器]:[port] /bin/resolver/gb.en/something

&#34;。&#34;之后的一切被认为是一个扩展,所以需要在servlet中处理,但帮助我实现了我的要求

答案 4 :(得分:0)

似乎你的servlet的路径是相同的。只是选择器是变化的。与path一起使用时,SlingServlet中会忽略其他内容。所以使用这样的东西应该达到目的: @SlingServlet(paths =“/ data / events / any_sequence / any_sequence”,extensions =“json”)

你需要在Felix控制台(/ system / console / configMgr)的执行路径中添加/ data,就像在Apache Sling Servlet Resolver属性中默认不存在一样

答案 5 :(得分:0)

这可以通过构建Sling映射或Apache重写来使用所需的外部URI模式来有效地将JSON扩展有效地移动到&#34; data&#34;之后。在URI中,所以单个servlet位于&#34; / data&#34;最终通过请求的后缀接收任意路径。如果您还在使用选择器中的数据,则需要将它们与扩展程序一起移动。