如何在后台线程中获取 ResourceResolver?
How to get ResourceResolver in a background thread?
我正在 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);
}
并且在提供商中 class:
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();
...
}
}
}
但是 ResourceResolverFactory 是空的,所以我在请求解析器时崩溃了。显然,没有工厂被注入 @Reference
我真的不想在主线程上做这些工作;下载文件后,我将转身从 JCR 读取它并将其复制到其他地方。这两个操作都可能很慢或失败。我在原始 URL 处有一份文件副本,因此最终用户不必关心我的 download/uploads 是否有问题。我只想向他们发送确认信息,以便他们继续开展业务。
关于如何在单独的线程中获取 ResourceResolver 的任何建议?
Note: @daniil-stelmakh brings a good point in his answer, sling jobs are much better suited for your purpose, to add to his answer, here is a sling tutorial that demonstrates sling jobs: https://sling.apache.org/documentation/tutorials-how-tos/how-to-manage-events-in-sling.html
直接回答你的问题:
问题,确实是 @Reference
注释的位置。
该注释由 Maven SCR Plugin 处理,它应该放在注释为 class.
的“@Component”的私有成员上
基本上移动您的 ResourceResolverFactory
声明成为您的 class 的私有成员,而不是线程。
@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();
...
}
}
}
}
对于 post\background 处理之类的事情,您可以使用 Sling Jobs。请参阅 documentation 以了解一些详细信息。
我正在 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);
}
并且在提供商中 class:
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();
...
}
}
}
但是 ResourceResolverFactory 是空的,所以我在请求解析器时崩溃了。显然,没有工厂被注入 @Reference
我真的不想在主线程上做这些工作;下载文件后,我将转身从 JCR 读取它并将其复制到其他地方。这两个操作都可能很慢或失败。我在原始 URL 处有一份文件副本,因此最终用户不必关心我的 download/uploads 是否有问题。我只想向他们发送确认信息,以便他们继续开展业务。
关于如何在单独的线程中获取 ResourceResolver 的任何建议?
Note: @daniil-stelmakh brings a good point in his answer, sling jobs are much better suited for your purpose, to add to his answer, here is a sling tutorial that demonstrates sling jobs: https://sling.apache.org/documentation/tutorials-how-tos/how-to-manage-events-in-sling.html
直接回答你的问题:
问题,确实是 @Reference
注释的位置。
该注释由 Maven SCR Plugin 处理,它应该放在注释为 class.
基本上移动您的 ResourceResolverFactory
声明成为您的 class 的私有成员,而不是线程。
@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();
...
}
}
}
}
对于 post\background 处理之类的事情,您可以使用 Sling Jobs。请参阅 documentation 以了解一些详细信息。