Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/typo3/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 有没有办法访问POJO中的SlingRepository?_Java_Osgi_Aem_Sling - Fatal编程技术网

Java 有没有办法访问POJO中的SlingRepository?

Java 有没有办法访问POJO中的SlingRepository?,java,osgi,aem,sling,Java,Osgi,Aem,Sling,有没有一种方法可以访问非OSGI管理的POJO中的SlingRepository 例如,我们可能有一个名为Site的POJO: public class Site { private String domainName; public String getDomainName() { return domainName; } public void setDomainName(String domainName) { this.domainName = domain

有没有一种方法可以访问非OSGI管理的POJO中的
SlingRepository

例如,我们可能有一个名为
Site
的POJO:

public class Site {

    private String domainName;

    public String getDomainName() { return domainName; }

    public void setDomainName(String domainName) { this.domainName = domainName; }

    public void validate() throws Exception {
        SlingRepository repo = ...;
        // validation logic dependent on repo
    }
}
这是这样使用的:

Site site = new Site();
site.validate();
public class UniquePropertyValidator implements ConstraintValidator<UniqueProperty, String {

    @Override
    public void initialize(UniqueProperty constraintAnnotation) {
        ...
    }

    @Override
    public boolean isValid(String object, ConstraintValidatorContext constraintContext) {
        // need to execute a JCR query here
    }
}


更新(关于托梅克的回答) 我无法使用
@Reference
或当前请求的
resourcesolver
的原因是因为我正在尝试实现JSR-303(又名Bean验证)验证器

在我们的Sling应用程序中,我们有一组servlet从浏览器接收JSON有效负载。然后我们将其转换为POJO:

Person p = new Gson().fromJson(json, Person.class)
validate(p); // Validate p using Bean Validation
Person
是一个简单的POJO,带有JSR-303注释:

public class Person {

    @NotNull
    private String name;

    @UniqueProperty(
      name = "email", 
      path = "/content/myapp", 
      nodeType = "cq:PageContent"
    )
    private String email;

}
简而言之,我的目标是实现
@UniqueProperty
验证。在上面的示例中,如果存在
/content/myapp
下的
cq:PageContent
类型的节点,并且该节点具有与此模型相同的
email
属性,则验证失败

验证程序类本身如下所示:

Site site = new Site();
site.validate();
public class UniquePropertyValidator implements ConstraintValidator<UniqueProperty, String {

    @Override
    public void initialize(UniqueProperty constraintAnnotation) {
        ...
    }

    @Override
    public boolean isValid(String object, ConstraintValidatorContext constraintContext) {
        // need to execute a JCR query here
    }
}

公共类UniquePropertyValidator实现ConstraintValidator通常,您不应该从pojo检索外部资源。只需添加一个constructor或setter,将SlingRepository注入到执行新操作的位置。这样做的好处是pojo独立于OSGi,可以在不同的环境中使用。使用这种方法,单元测试也更容易

Site site = new Site(slingRepository);
当然,这只是将问题转移到创建实例的类。我想在某个时候,您可以从激活器开始,在激活器中您可以访问BundleContext并可以查找服务

在极少数情况下,如果您确实希望直接查找服务,请使用

FrameworkUtil.getBundle(this.getClass()).getBundleContext(); 

从那里您可以查找服务。

正如Christian Schneider所写,您可以使用以下内容:

BundleContext bundleContext = FrameworkUtil.getBundle(this.getClass()).getBundleContext();
ServiceReference serviceReference = bundleContext.getServiceReference(SlingRepository.class);
SlingRepository slingRepository;
if (serviceReference != null) {
   slingRepository = (SlingRepository) bundleContext.getService(serviceReference);
}

首先,如果您使用Sling,那么使用
ResourceResolver
通常比
SlingRepository
更可取。它为您提供了一个有用的
资源
抽象层,您仍然可以使用
adapto()
方法获得底层JCR
会话
对象

但回到你的问题,POJO总是生活在一个环境中,有一些入口点运行着整个过程。在Sling中有几个这样的地方:JSP、servlet或OSGi组件。在所有这些入口点中,至少有一种方法可以访问存储库:

  • JSP
    • 使用
      resourcesolver
      绑定
    • 使用
      getService(resourcesolverfactory.class)
      创建管理冲突解决程序
  • Servlet或过滤器
    • 使用
      request.getResourceResolver()
      获取请求会话
    • 或者看看下一点
  • 任何OSGi服务(包括servlet或过滤器)
    • 使用
      @Reference resourcesolverfactory
      获取工厂并创建管理解析程序
  • 之后,您可以将资源解析器传递给POJO构造函数。我认为这是一个比在
    FrameworkUtil
    中使用hack更好的选择,原因如下:

    • 如果将
      resourcesolver
      传递给POJO构造函数,很明显,这个特定的类在存储库上运行
    • 您不必担心关闭会话(因为POJO可能没有定义的生命周期)
    • 如果您在servlet或组件(案例1和案例2)中创建POJO,最好使用请求的会话来避免处理管理会话
    刚刚找到了一个解决方案,您可以利用ConstraintValidator的生命周期

    见:


    第2.5章。ConstraintValidatorFactory可能会帮助您。如果您在例如Activator中注册ConstraintValidatorFactory,则可以将其与SlingRepository一起提供。然后,工厂可以将SlingRepository转发给它创建的验证器。因此,您可以将OSGi逻辑排除在验证器之外。

    谢谢您的回答。我已经更新了问题,以便更清楚地说明为什么我需要访问
    SlingRepository
    ,并且我不能使用
    resourcesolver
    。这将使模型依赖Sling,这不是一个好主意。想想如果我们必须在基于JDBC的程序中向POJO传递JDBC连接,会发生什么。或者,如果我们必须将EntityManager传递给JavaEE应用程序中的实体。回头看我。我见过人们按照你在Sling应用程序中的建议去做,我认为他们这样做只是因为他们别无选择。我还更新了帖子,提到POJO实际上是一个JSR-303验证器,由Hibernate验证器实例化,而不是由我显式实例化。在您的问题中,您表示希望在站点内部使用SlingRepository。这就是为什么我在示例中显示了这一点。在更新的问题中,您似乎更需要UniquePropertyValidator中的存储库。由于您不控制此类的生命周期,FrameworkUtl方法看起来是一个很好的解决方案。