Adobe CQ / AEM - 从自定义登录模块连接到DB

时间:2015-07-29 16:13:46

标签: java cq5 aem

我有一个扩展org.apache.jackrabbit.core.security.authentication.AbstractLoginModule的自定义登录模块。它根据LDAP源检查凭据,现在我想转到数据库以获取一些额外的数据来写入配置文件。我想使用JDBC Connections Pool服务,但我无法弄清楚如何获取它。

我的第一个猜测是,可能有办法让Session方法通过doInit()方法提供服务,但我无法找到方法。

Session本身似乎由CallbackHandler设置。有没有办法通过编写Callback来获取服务引用?

编辑: 根据有用的评论,我还尝试了以下

BundleContext context = FrameworkUtil.getBundle(JdbcPoolService.class).getBundleContext();
//ServiceReference[] serviceRefs = context.getServiceReferences(JdbcPoolService.class.getName(), String.format("(%s=%s)", Constants.OBJECTCLASS, JdbcPoolService.class.getName()));
ServiceReference serviceRefs = context.getServiceReference(JdbcPoolService.class.getName());

FrameworkUtil确实可以让我访问正确的捆绑包。 (我可以在调试器中看到捆绑包ID,它确实与JDBC池提供程序匹配。)但我无法访问该服务。所有参考请求都返回null。我试过获得一个引用,但由于JDBC池是一个服务工厂,我也尝试(注释掉代码)获取数组 - 使用类名和过滤器作为参数,或者null和过滤器作为参数到getServiceReferences。 如果我使用@Reference注释,我会包含目标参数。我猜这就是我所缺少的。也许过滤到getServiceReferences是错误的?

1 个答案:

答案 0 :(得分:2)

此链接提供有关连接到SQL数据库的信息:https://docs.adobe.com/docs/en/cq/5-6-1/developing/jdbc.html。 本质上,它展示了如何在OSGi包中部署包装HSQLDB驱动程序的包。这是他们使用的POM:

<project xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">


<modelVersion>4.0.0</modelVersion>

  <groupId>com.adobe.example.myapp</groupId>
  <artifactId>hsqldb-jdbc-driver-bundle</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <name>wrapper-bundle-hsqldb-driver</name>
  <url>www.adobe.com</url>
  <description>Exports the HSQL JDBC driver</description>
  <packaging>bundle</packaging>
  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  </properties>
  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.felix</groupId> 
        <artifactId>maven-bundle-plugin</artifactId>
        <version>1.4.3</version> 
        <extensions>true</extensions> 
        <configuration> 
         <instructions> 
            <Embed-Dependency>*</Embed-Dependency>
            <_exportcontents>org.hsqldb.*</_exportcontents>
          </instructions>
        </configuration> 
      </plugin>
    </plugins>
  </build>
  <dependencies>
    <dependency>
      <groupId>hsqldb</groupId>
      <artifactId>hsqldb</artifactId>
      <version>2.2.9</version>
    </dependency>
  </dependencies>
</project>

然后您可以获得DataSourcePool服务以获取javax.sql.DataSource对象。本文展示了如何在JSP中获取它:

<%@include file="/libs/foundation/global.jsp"%><%
%><%@page session="false"%><%
%><%@ page import="com.day.commons.datasource.poolservice.DataSourcePool" %><%
%><%@ page import="javax.sql.DataSource" %><%
%><%@ page import="java.sql.Connection" %><%
%><%@ page import="java.sql.SQLException" %><%
%><%@ page import="java.sql.Statement" %><%
%><%@ page import="java.sql.ResultSet"%><%
%><html>
<cq:include script="head.jsp"/>
<body>
<%DataSourcePool dspService = sling.getService(DataSourcePool.class);
  try {
     DataSource ds = (DataSource) dspService.getDataSource("hsqldbds");   
     if(ds != null) {
         %><p>Obtained the datasource!</p><%
         %><%final Connection connection = ds.getConnection();
          final Statement statement = connection.createStatement();
          final ResultSet resultSet = statement.executeQuery("SELECT * from INFORMATION_SCHEMA.SYSTEM_USERS"); 
          int r=0;
          while(resultSet.next()){
             r=r+1;
          } 
          resultSet.close();
          %><p>Number of results: <%=r%></p><%
      } 
   }catch (Exception e) {
        %><p>error! <%=e.getMessage()%></p><%
    } 
%></body>
</html>

在servlet或服务中,您可以使用DataSourcePool注释获得对@Reference服务的引用:

@Reference
private DataSourcePool pool;

编辑:您可以尝试使用FrameworkUtil class

在组件外部获取服务
BundleContext context = FrameworkUtil.getBundle(serviceClass).getBundleContext();
ServiceReference serviceRef = context.getServiceReference(serviceClass.getName());
Object service = context.getService(serviceRef);

EDIT(由jwepurchase提供):对于JDBC服务,您需要通过其持久性ID获取服务

ServiceReference[] serviceRefs = context.getServiceReferences(null, String.format("(%s=%s)", Constants.SERVICE_PID, "com.day.commons.datasource.jdbcpool.JdbcPoolService.[your-id-here]"));
JdbcPoolService pool = (JdbcPoolService) context.getService(serviceRefs[0]);

请注意,getServiceReferences的第一个参数为null。将类名作为第一个参数传递似乎不起作用。