在 Jackrabbit 服务器上执行远程查询
我们使用的是部署在 Glassfish 应用服务器上的 Jackrabbit 2.2.6 ( webapp)。我们还构建了一个客户端,使用服务器公开的 rmi 接口将文件上传到服务器。我们能够使用标准 JCR API 从客户端登录并将文件上传到远程服务器。但是,我们很难查询远程服务器(我们使用的是 JCR-SQL2)。这是我们用来查询远程服务器的代码片段:
public static List<Node> getNode(Session session, String q) {
try {
QueryManager qman = session.getWorkspace().getQueryManager();
Query query = qman.createQuery(q, Query.JCR_SQL2);
QueryResult result = query.execute();
RowIterator rowIt = result.getRows();
System.err.println("Found results " + rowIt.hasNext());
List<Node> nList = new LinkedList<Node>();
while (rowIt.hasNext()) {
Row row = rowIt.nextRow();
nList.add(row.getNode());
}
return nList;
} catch (RepositoryException ex) {
Logger.getLogger(BasicArtifacts.class.getName()).log(Level.SEVERE, null, ex);
}
return null;
}
这是我们执行代码时得到的结果:
javax.jcr.UnsupportedRepositoryOperationException: TODO: JCRRMI-26
at org.apache.jackrabbit.rmi.client.ClientRow.getNode(ClientRow.java:70)
看起来nList.add(row.getNode());是罪魁祸首。看起来这不是在 Jackrabbit 服务器上进行远程查询的最佳方法。
我们确认它可以在本地临时存储库上运行。
在查看 Jackrabbit 代码库时,我们遇到了 RemoteQuery 和相关类。我尝试编写一些代码 - 但无法完全使其工作。这是片段
public static List<Node> getNode(Session session, String q) throws RemoteException {
try {
QueryManager qman = session.getWorkspace().getQueryManager();
ServerAdapterFactory factory = new ServerAdapterFactory();
RemoteQueryManager rqman = factory.getRemoteQueryManager(session, qman);
RemoteQuery rquery = rqman.createQuery(q, Query.JCR_SQL2);
//this is a basic query - not yet sure how to implement the constraints as yet.
RemoteQueryResult rresult = rquery.execute();
RemoteIterator rit = rresult.getRows();
Object[] objs = rit.nextObjects();
System.err.println("Found results " + rit.getSize() );
List<Node> nList = new LinkedList<Node>();
for(Object obj:objs){
//System.err.println(row.getPath());
ServerRow row = (ServerRow)obj;
for(Value val:row.getValues()){
System.err.println("Value:"+ val.getString());
}
//How to get the Node out of the ServerRow?
//nList.add(row.);
}
return nList;
}
catch (RepositoryException ex) {
Logger.getLogger(UploadContentToRemote.class.getName()).log(Level.SEVERE, null, ex);
}
return null;
}
任何帮助,指针将不胜感激。谢谢。
We are using Jackrabbit 2.2.6 ( webapp) deployed on a Glassfish Application server. We are also building a client to upload files to the server using the rmi interface exposed by the server. We are able to login and upload files using the standard JCR API from the client to the remote server. However, we are having hard time querying the remote server ( we are using JCR-SQL2). Here is the snippet of the code that we are using to query the remote server:
public static List<Node> getNode(Session session, String q) {
try {
QueryManager qman = session.getWorkspace().getQueryManager();
Query query = qman.createQuery(q, Query.JCR_SQL2);
QueryResult result = query.execute();
RowIterator rowIt = result.getRows();
System.err.println("Found results " + rowIt.hasNext());
List<Node> nList = new LinkedList<Node>();
while (rowIt.hasNext()) {
Row row = rowIt.nextRow();
nList.add(row.getNode());
}
return nList;
} catch (RepositoryException ex) {
Logger.getLogger(BasicArtifacts.class.getName()).log(Level.SEVERE, null, ex);
}
return null;
}
This is what we got when executing the code:
javax.jcr.UnsupportedRepositoryOperationException: TODO: JCRRMI-26
at org.apache.jackrabbit.rmi.client.ClientRow.getNode(ClientRow.java:70)
It seems like nList.add(row.getNode()); is the culprit. Looks like this is not the best way to do remote query on a Jackrabbit server.
We confirmed that it works on the local transient repository.
While looking through the Jackrabbit code base, we encountered the RemoteQuery and related classes. I tried to write some code - but could not quite make it work. Here is the snippet
public static List<Node> getNode(Session session, String q) throws RemoteException {
try {
QueryManager qman = session.getWorkspace().getQueryManager();
ServerAdapterFactory factory = new ServerAdapterFactory();
RemoteQueryManager rqman = factory.getRemoteQueryManager(session, qman);
RemoteQuery rquery = rqman.createQuery(q, Query.JCR_SQL2);
//this is a basic query - not yet sure how to implement the constraints as yet.
RemoteQueryResult rresult = rquery.execute();
RemoteIterator rit = rresult.getRows();
Object[] objs = rit.nextObjects();
System.err.println("Found results " + rit.getSize() );
List<Node> nList = new LinkedList<Node>();
for(Object obj:objs){
//System.err.println(row.getPath());
ServerRow row = (ServerRow)obj;
for(Value val:row.getValues()){
System.err.println("Value:"+ val.getString());
}
//How to get the Node out of the ServerRow?
//nList.add(row.);
}
return nList;
}
catch (RepositoryException ex) {
Logger.getLogger(UploadContentToRemote.class.getName()).log(Level.SEVERE, null, ex);
}
return null;
}
Any help, pointers will be appreciated. Thanks.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您是否尝试过使用 NodeIterator:
我正在使用 JackRabbit RMI 到 CRX 后端,这很有效。
Have you tried using a NodeIterator:
I'm using JackRabbit RMI to CRX backend and this works.
SQL2 是随 JSR-283 引入的。 JSR-283 尚未通过 RMI 得到完全支持(请参阅 JCRRMI-26 )。
您可以尝试在 XPATH 中重新编写查询,或者使用 DavEx 而不是 RMI 进行远程处理。
SQL2 was introduced with JSR-283. JSR-283 is not fully supported (yet) through RMI (see JCRRMI-26).
You can either try to reformulate your query in XPATH or use DavEx instead of RMI for remoting.
在具体的查询方面,我建议您使用XPath。它在技术上已被弃用,但似乎被社区广泛使用,这意味着实现已完成并被广泛使用。我怀疑 RMI 远程堆栈中的它也更完整。
您可能已经知道这一点,另一个答案也提到了这一点,但是 jackrabbit 的 rmi 远程处理似乎并不适合实际使用,如 这个一个。
davex 远程处理似乎是首选方式,虽然它也没有完全实现,但似乎有足够的地方可以完成您需要做的所有事情。
In specific terms of querying, I would recommend that you use the XPath. It's technically deprecated, but seems to be widely used by the community, which means that the implementation is complete and widely used. I suspect that it's more complete in the RMI remote stack as well.
You might already know this, and the other answer alludes to this, but the rmi remoting of jackrabbit doesn't seem to be intended for real usage, as mentioned in threads like this one.
The davex remoting seems to be the preferred way, and, while it's not completely implemented either, there seems to be enough in place to do everything you would need to do.