Adobe CQ/AEM - 从自定义登录模块连接到数据库
Adobe CQ/AEM - connect to DB from custom login module
我有一个扩展 org.apache.jackrabbit.core.security.authentication.AbstractLoginModule
的工作自定义登录模块。它根据 LDAP 源检查凭据,现在我想去数据库获取一些额外的数据以写入配置文件。我想使用 JDBC 连接池服务,但我不知道如何获取对它的引用。
我的第一个猜测是,可能有办法让doInit()
方法中传递的Session
对象提供服务,但我找不到办法。
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 池提供程序匹配。)但我无法访问该服务。所有对参考的请求都返回空值。我试过获取单个引用,但因为 JDBC 池是一个服务工厂,我也尝试(注释掉代码)获取数组 - 使用 class 名称和过滤器作为参数,或者null 和过滤器作为 getServiceReferences
的参数。
如果我使用 @Reference
注释,我会包含目标参数。我猜这就是我所缺少的。也许 getServiceReferences
的过滤器是错误的?
此 link 提供有关连接到 SQL 数据库的信息:https://docs.adobe.com/docs/en/cq/5-6-1/developing/jdbc.html。
从本质上讲,它展示了如何部署将 HSQLDB 驱动程序包装在 OSGi 包中的包。这是他们使用的 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 或服务中,您可以使用 @Reference
注释获取对 DataSourcePool
服务的引用:
@Reference
private DataSourcePool pool;
编辑:您可以尝试使用 FrameworkUtil class
在组件外部获取服务
BundleContext context = FrameworkUtil.getBundle(serviceClass).getBundleContext();
ServiceReference serviceRef = context.getServiceReference(serviceClass.getName());
Object service = context.getService(serviceRef);
编辑(通过 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
的第一个参数为空。将 class 名称作为第一个参数传递似乎不起作用。
我有一个扩展 org.apache.jackrabbit.core.security.authentication.AbstractLoginModule
的工作自定义登录模块。它根据 LDAP 源检查凭据,现在我想去数据库获取一些额外的数据以写入配置文件。我想使用 JDBC 连接池服务,但我不知道如何获取对它的引用。
我的第一个猜测是,可能有办法让doInit()
方法中传递的Session
对象提供服务,但我找不到办法。
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 池提供程序匹配。)但我无法访问该服务。所有对参考的请求都返回空值。我试过获取单个引用,但因为 JDBC 池是一个服务工厂,我也尝试(注释掉代码)获取数组 - 使用 class 名称和过滤器作为参数,或者null 和过滤器作为 getServiceReferences
的参数。
如果我使用 @Reference
注释,我会包含目标参数。我猜这就是我所缺少的。也许 getServiceReferences
的过滤器是错误的?
此 link 提供有关连接到 SQL 数据库的信息:https://docs.adobe.com/docs/en/cq/5-6-1/developing/jdbc.html。 从本质上讲,它展示了如何部署将 HSQLDB 驱动程序包装在 OSGi 包中的包。这是他们使用的 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 或服务中,您可以使用 @Reference
注释获取对 DataSourcePool
服务的引用:
@Reference
private DataSourcePool pool;
编辑:您可以尝试使用 FrameworkUtil class
在组件外部获取服务BundleContext context = FrameworkUtil.getBundle(serviceClass).getBundleContext();
ServiceReference serviceRef = context.getServiceReference(serviceClass.getName());
Object service = context.getService(serviceRef);
编辑(通过 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
的第一个参数为空。将 class 名称作为第一个参数传递似乎不起作用。