代码之家  ›  专栏  ›  技术社区  ›  Val

如何在后台线程中获取ResourceResolver?

  •  1
  • Val  · 技术社区  · 8 年前

    我正在Adobe Experience Manager(AEM)中开发一个解决方案,该解决方案接收到一个HTTP请求,其中包含一个指向文件的URL,我想下载并存储在JCR中。

    因此,我有一个servlet来接收请求。它生成一个线程,以便我可以在后台进行下载,然后重定向到确认页面。这允许我在尝试下载文件时,无需等待即可发送用户。

    我可以很好地下载该文件,但我很难从我的线程获得一个可用的ResourceResolver来将该文件存储在JCR中。

    首先,我只是在后台线程中引用了请求的ResourceResolver:

    Servlet:

    public void doGet(SlingHttpServletRequest request, SlingHttpServletResponse response)
    throws ServletException, IOException {
        ...
        signingProvider.getDocFromService(params, request.getResourceResolver());
        response.sendRedirect(confirmationPage);
    }
    

    在provider类中:

    public void getDocFromService(Map<String, String> params, ResourceResolver resolver) {
        new Thread( new Runnable() {
            public void run() {
                Session session = null;
                if (resolver != null) { 
                    session = resolver.adaptTo(Session.class); 
                    Node root = session.getRootNode();
                    ...
                }
            }
        }
    }
    

    但那没用。在阅读了解析器与线程的相关内容后,我认为最好创建一个新的解析器实例,因此我尝试注入一个ResourceResolverFactory:

    Servlet:

    signingProvider.getDocFromService(params);
    

    供应商:

    public void getDocFromService(Map<String, String> params) {
        new Thread( new Runnable() {
            @Reference
            private ResourceResolverFactory resolverFactory;
    
            // security hole, fix later
            ResourceResolver resolver = resolverFactory.getAdministrativeResourceResolver(null);
            Session session = null;
            if (resolver != null) {
                session = resolver.adaptTo(Session.class);
                Node root = session.getRootNode();
                ...
            }
        }
    }
    

    但是resourcesolverfactory为null,所以我在请求解析器时崩溃了。显然,没有工厂被注入 @Reference

    我真的宁愿不做主线上的工作;下载完文件后,我将回头从JCR中读取并将其复制到其他地方。这两种操作都可能很慢或失败。我在原始URL上有一份文件副本,因此最终用户不必关心我的下载/上载是否有问题。我只想给他们发个确认信,这样他们就可以继续做生意了。

    关于如何在单独的线程中获取ResourceResolver,有什么建议吗?

    2 回复  |  直到 8 年前
        1
  •  2
  •   Daniil Stelmakh    8 年前

    对于后期\后台处理,可以使用Sling作业。请参阅 documentation 了解一些细节。

        2
  •  1
  •   Ahmed Musallam    8 年前

    注:@Daniel stelmakh在他的回答中提出了一个很好的观点,吊索作业更适合您的目的,为了补充他的回答,这里有一个吊索教程,演示吊索作业: https://sling.apache.org/documentation/tutorials-how-tos/how-to-manage-events-in-sling.html

    要直接回答您的问题:

    问题是 @Reference 注释。 该注释由 Maven SCR Plugin 并且应该将其放置在“@组件”注释类的私有成员上。

    基本上移动 ResourceResolverFactory

    @Component(
        label = "sample service",
        description = "sample service"
    )
    @Service
    public class ServiceImpl {
        @Reference
        private ResourceResolverFactory resolverFactory;
    
        public void getDocFromService(Map<String, String> params) {
            new Thread( new Runnable() {
    
               // security hole, fix later
               ResourceResolver resolver = resolverFactory.getAdministrativeResourceResolver(null);
               Session session = null;
               if (resolver != null) {
                   session = resolver.adaptTo(Session.class);
                   Node root = session.getRootNode();
                   ...
               }
           }
        }
    }