Servlets Adobe CQ5自定义servlet路径

Servlets Adobe CQ5自定义servlet路径,servlets,adobe,aem,Servlets,Adobe,Aem,我试图为一些节点的json处理添加一些功能。因此,我编写了从SlingSafeMethodServlet扩展而来的定制servlet,当用户为以下url生成GET时,我需要执行该servlet:/data/events/any_sequence/any_sequence.json或/data/events/any_sequence/any_sequence.infinity.json或例如/data/events/any_sequence/any_sequence.2.json其中any_seq

我试图为一些节点的json处理添加一些功能。因此,我编写了从
SlingSafeMethodServlet
扩展而来的定制servlet,当用户为以下url生成GET时,我需要执行该servlet:/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当然指任何有效的符号序列

问题是我在sling文档中找不到如何像URL一样映射此模板

我一直在尝试设置如下属性:

@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")
})
@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")
})
但这没用。我检查了felix控制台,发现我的服务已经启动并运行,所以问题是如何设置url映射。所以我的问题是如何在我的例子中设置url映射来调用自定义servlet的doGet


谢谢。

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

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

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

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

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

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


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

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


请参见

我遇到了类似的问题,需要使用通配符

@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());
    }
}
调用为[server]:[port]/bin/resolver/gb。[通配符]

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


“.”之后的所有内容都被视为扩展,因此需要在servlet中处理,但帮助我实现了我的要求

我遇到了类似的问题,需要使用通配符

@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());
    }
}
调用为[server]:[port]/bin/resolver/gb。[通配符]

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


“.”之后的所有内容都被认为是一个扩展,因此需要在servlet中处理,但帮助我实现了我的要求

看起来您的servlet的路径是相同的。只是选择器是不同的。与path一起使用时,SlingServlet中的其他内容将被忽略。因此,使用类似的方法应该达到以下目的: @SlingServlet(path=“/data/events/any_sequence/any_sequence”,extensions=“json”)


您需要从Felix控制台(/system/console/configMgr)在执行路径中添加/data,因为默认情况下,Apache Sling Servlet解析器属性中没有/data。您的Servlet的路径似乎是相同的。只是选择器不同而已。与path一起使用时,SlingServlet中的其他内容将被忽略。因此,使用类似的方法应该达到以下目的: @SlingServlet(path=“/data/events/any_sequence/any_sequence”,extensions=“json”)


您需要在Felix控制台(/system/console/configMgr)的执行路径中添加/data,因为在Apache Sling Servlet解析器属性中默认情况下不存在/data。这可以通过构建Sling映射或Apache重写来使用所需的外部URI模式来实现,从而有效地将JSON扩展移到“data”之后在URI中,“/data”处的单个servlet最终通过请求的后缀接收任意路径。如果您也在使用选择器中的数据,则需要将其与扩展一起移动。

这可以通过使用所需的外部URI模式来实现,方法是构造一个Sling映射或Apache重写,以有效地将JSON扩展移动到URI中“data”之后,因此“/data”处的单个servlet最终通过请求的后缀接收任意路径。如果您还使用选择器的数据,则需要将其与扩展一起移动。

我已经解决了这个问题,正如原始海报所希望的那样。所有其他答案实际上都是“这不可能完成”或“如果你想用选择器弄脏你干净的RESTful API,这里有一种方法可以做到”

如果您想保持所设想的干净API,下面是如何实现的。这也适用于没有扩展的API,如/myservice/mythings/123123,其中123123是一些动态ID

创建两个文件:

  • 资源提供者
  • Servlet
资源提供者

这样做的目的只是侦听/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;
}
}
@组件
@服务(值=ResourceProvider.class)
@性质({
@属性(name=ResourceProvider.root,value=“data/events”),
@属性(name=ResourceProvider.OWNS\u root,value=“true”)
})
公共类ImageResourceProvider实现ResourceProvider{
@凌驾
公共资源getResource(ResourceResolver ResourceResolver,字符串路径){
抽象资源抽象资源;
abstractResource=新的abstractResource(){
@凌驾
公共字符串getResourceType(){
返回TypeServlet.RESOURCE\u类型;
}
@凌驾
公共字符串getResourceSuperType(){
返回null;
}
@凌驾
公共字符串getPath(){
返回路径;
}
@凌驾
公共资源解析程序getResourceResolver(){
返回资源解析程序;
}
@凌驾
公共资源元数据getResourceMetadata(){
返回新的ResourceMetadata();
}
};
返回资源;
}
@凌驾
P