简体   繁体   English

Adobe CQ5自定义servlet路径

[英]Adobe CQ5 custom servlet path

I am trying to add some functionality to json processing for some nodes. 我正在尝试为某些节点的json处理添加一些功能。 So I wrote custom servlet extended from SlingSafeMethodsServlet which I need to be executed when user makes GET for the following url : /data/events/any_sequence/any_sequence.json or /data/events/any_sequence/any_sequence.infinity.json or for example /data/events/any_sequence/any_sequence.2.json where any_sequence of course means any valid sequence of symbols. 因此,我编写了从SlingSafeMethodsServlet扩展的自定义servlet,当用户对以下网址进行GET时,需要执行该自定义servlet: /data/events/any_sequence/any_sequence.json/data/events/any_sequence/any_sequence.anyfinity.json或例如/数据/事件/any_sequence/any_sequence.2.json ,其中any_sequence当然是指任何有效的符号序列。

The problem is that I cannot find in the sling docs how to map this template like urls. 问题是我无法在吊索文档中找到如何映射此模板(如url)的方法。

I've been trying to set properties like this: 我一直在尝试设置如下属性:

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

But it didn't help. 但这没有帮助。 I checked felix console and found out that my service had started and running, so the problem is how to set url mappings. 我检查了felix控制台,发现我的服务已经启动并正在运行,所以问题在于如何设置URL映射。 So my question is how to set url mapping in my case to invoke doGet of my custom servlet ? 所以我的问题是在我的情况下如何设置URL映射以调用自定义servlet的doGet?

Thanks. 谢谢。

As far as I understand CQ5 does not provide ability to map custom servlets on wildcard urls. 据我了解,CQ5没有提供在通配符URL上映射自定义servlet的功能。 The only way to accomplish goal similiar to one I needed is to use some unique for this servlet selector like this: 实现与我所需目标相似的目标的唯一方法是为此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")
})

This code means that if I'll try to make GET on some node with *.advanced.json selector and extension then request will be forwarded to my custom servlet. 此代码意味着,如果我尝试使用*.advanced.json选择器和扩展名在某个节点上进行GET,则请求将转发至我的自定义servlet。

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

I've solved this, exactly as the original poster was hoping. 我已经按照原始海报希望的那样解决了这个问题。 All other answers are effectively "it can't be done" or "here's a way to do it if you're willing to dirty up your clean RESTful API with selectors" 所有其他答案实际上都是“无法完成”或“如果您愿意使用选择器来修饰干净的RESTful API,则可以采用以下方法”

If you want to keep the clean API you envisioned, here's how. 如果要保留您设想的干净API,请按以下步骤操作。 This works also for Apis without extensions, like /myservice/mythings/123123 , where 123123 is some dynamic ID 这也适用于不带扩展名的Apis,例如/ myservice / mythings / 123123,其中123123是一些动态ID

Create Two Files: 创建两个文件:

  • ResourceProvider 资源提供者
  • Servlet Servlet

The ResourceProvider 资源提供者

The purpose of this is only to listen to all requests at /data/events and then produce a "Resource" at that virtual path, which doesn't actually exist in the JCR. 这样做的目的仅是侦听/ 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;
}
}

The Servlet Servlet

Now you just write a servlet which handles any of the resources coming from that path - but this is accomplished by handling any resources with the resource type which is produced by the ResourceProvider listening at that path. 现在,您只需编写一个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();
        }
    }
}

This is the syntax I have used to accomplish similar tasks: 这是我用来完成类似任务的语法:

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

I had a similar problem and I needed wildcards I used 我有一个类似的问题,我需要使用通配符

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

Call is [server]:[port]/bin/resolver/gb.[wildcard] 呼叫是[服务器]:[端口] / bin / resolver / gb。[通配符]

So what can be done is : [server]:[port]/bin/resolver/gb.en/something 所以可以做的是:[服务器]:[端口] /bin/resolver/gb.en/something

Everything after "." “。”之后的所有内容。 is considered an extension so need to be handled in the servlet, but helped me achieve my requirement 被认为是扩展,因此需要在servlet中进行处理,但有助于我达到要求

It seems that the path of your servlet is same.Just selectors are varying. 看来servlet的路径是相同的,只是选择器在变化。 When used with path, other things are ignored in SlingServlet. 与路径一起使用时,SlingServlet中将忽略其他内容。 So using something like this should serve the purpose: @SlingServlet(paths = " /data/events/any_sequence/any_sequence", extensions = "json") 因此,使用类似这样的东西应该可以达到目的:@SlingServlet(paths =“ / data / events / any_sequence / any_sequence”,extensions =“ json”)

You would need to add /data in execution paths from Felix console(/system/console/configMgr) as is it not there by default in Apache Sling Servlet Resolver property 您需要在Felix控制台(/ system / console / configMgr)的执行路径中添加/ data,因为默认情况下Apache Sling Servlet Resolver属性中不存在/ data

This can be accomplished using the desired external URI pattern by constructing a Sling mapping or Apache rewrite to effectively move the JSON extension to just after "data" in the URI, so the single servlet at "/data" ends up receiving the arbitrary path via the suffix of the request. 通过构造Sling映射或Apache重写以有效地将JSON扩展名移动到URI中的“数据”之后,可以使用所需的外部URI模式完成此操作,因此位于“ / data”的单个servlet最终通过接收了任意路径。请求的后缀。 If you are also using data from selectors, you'll need to move them along with the extension. 如果您还使用选择器中的数据,则需要将其与扩展名一起移动。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM