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

时间:2018-02-16 19:52:49

标签: java osgi aem sling jcr

我正在使用Adobe Experience Manager(AEM)中的解决方案,该解决方案接收包含文件URL的HTTP请求,我想将其下载并存储在JCR中。

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

我可以正常下载该文件,但是我无法获得可用的ResourceResolver来将文件存储在我的线程的JCR中。

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

的Servlet

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

在提供者类中:

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

但那并没有奏效。在阅读了解析器与线程之后,我认为我最好创建一个新的Resolver实例,所以我尝试注入一个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();
            ...
        }
    }
}

但是ResourceResolverFactory为null,所以当它要求解析器时我崩溃了。显然,没有工厂注入@Reference

我真的不想在主线程上做工作;下载文件后,我将转身从JCR读取并将其复制到其他地方。这两种操作都可能很慢或失败。我在原始网址上有该文件的副本,因此最终用户无需关心我的下载/上传是否有问题。我只想向他们发送确认函,以便他们继续开展业务。

有关如何在单独的线程中获取ResourceResolver的任何建议吗?

2 个答案:

答案 0 :(得分:2)

对于post \ background处理等内容,您可以使用Sling Jobs。请参阅documentation了解一些详细信息。

答案 1 :(得分:1)

  

注意:@ daniil-stelmakh在他的回答中提出了一个很好的观点,吊索工作更适合您的目的,添加到他的答案,这是一个展示吊索工作的吊索教程:https://sling.apache.org/documentation/tutorials-how-tos/how-to-manage-events-in-sling.html

直接回答您的问题:

问题,实际上是@Reference注释的位置。 该注释由Maven SCR Plugin处理,并且应该放在'@Component'注释类的私有成员上。

基本上将您的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();
               ...
           }
       }
    }
}