获得列表
在上一步中我们已经把数据保存到了内容仓库中,那我们如何确定数据确实保存进去了呢?getBlogList() 这个方法将返回根节点下所有名为blogEntry.的子节点。

public ArrayList getBlogList() throws BlogApplicationException {
    Session session = JackrabbitPlugin.getSession();
    ArrayList blogEntryList = new ArrayList();
    Node rootNode = session.getRootNode();
    NodeIterator blogEntryNodeIterator = rootNode.getNodes();

while (blogEntryNodeIterator.hasNext()) {
        Node blogEntry = blogEntryNodeIterator.nextNode();
        if (blogEntry.getName().equals("blogEntry") == false)
            continue;
        String title = blogEntry.getProperty("title").getString();
        String blogContent = blogEntry.getProperty("blogContent").getString();
        Value creationTimeValue = (Value) blogEntry.getProperty(
                "creationTime").getValue();
        String userName = blogEntry.getProperty("userName").getString();
        BlogEntryDTO blogEntryDTO = new BlogEntryDTO(userName, title,
                blogContent, creationTimeValue.getDate());
        blogEntryList.add(blogEntryDTO);
    }
    return blogEntryList;
}

一旦你获得了根节点这个对象,你就可以通过调用getNodes()这个方法来获取它所有的子节点。如果这个节点没有子节点,将返回一个空的NodeIterator 对象。我们可以遍历这个NodeIterator 对象来获得名为blogEntry 的节点集合,然后通过getProperty()方法来获得节点上的属性,即我们保存的真实数据。getProperty()方法返回Value对象的一个实例。因为存储数据类型的不同,所以返回的Value对象实例是不同的。根据不同的数据类型,你应该调用特定的方法来获取数据,比如getString()来获取字符串,而getDate()获得一个日期。

查找内容(用XPath的方式)
JSR-170定义了两种方式来查找内容(也可以理解为查找节点)。一种使用XPath语法,另一种使用SQL语法。JSR-170要求Level 1必须实现XPath的方式,而SQL的方式则作为一个可选的功能。

XPath原本是一种设计用来查找XML元素的语言。因为我们的workspace是树状的结构,很像XML。所以XPath语法非常适合于在这里查找内容。下面的代码演示了通过作者名来查找节点。

Session session = JackrabbitPlugin.getSession();
    Workspace workSpace = session.getWorkspace();
    QueryManager queryManager = workSpace.getQueryManager();

StringBuffer queryStr = new StringBuffer(
            "//blogEntry[@"+PROP_BLOGAUTHOR +"= '");
    queryStr.append(userName);
    queryStr.append("']");
    Query query = queryManager.createQuery(queryStr.toString(),
            Query.XPATH);

QueryResult queryResult = query.execute();

NodeIterator queryResultNodeIterator = queryResult.getNodes();
    while (queryResultNodeIterator.hasNext()) {

Node blogEntry = queryResultNodeIterator.nextNode();
        String title = blogEntry.getProperty(PROP_TITLE).getString();
        String blogContent = blogEntry.getProperty(PROP_BLOGCONTENT).getString();
        Value creationTimeValue = (Value) blogEntry.getProperty(
                PROP_CREATIONTIME).getValue();
        BlogEntryDTO blogEntryDTO = new BlogEntryDTO(userName, title,
                blogContent, creationTimeValue.getDate());
        blogEntryList.add(blogEntryDTO);
    }

首先获得session 对象,通过它获得它连接的workspace,然后就可以通过workspace获得这个workspace的QueryManager 。QueryManager 接口定义了很多用来查询的方法。接下来我们要做的是创建一条查询语句。我们这里这样写"//blogEntry[@blogAuthor='<bloggerName>'"。这句话的意思是查找所有名为blogEntry ,含有blogAuthor 属性且属性值为<bloggerName>的节点。具体可以看JSR-170规范。

通过queryManager's createQuery()方法创建一个查询对象,这个方法需要两个参数,一个是我们的查询语句,另一个是查询的方式,这里使用XPath。获得这个Query 查询对象后,调用它的execute() 方法开始执行查询,返回一个QueryResult 对象。注意,查询的结果受到当前session的限制,换句话说,就是如果这个session没有权限查看一个特定的节点,哪怕这个节点满足我们查询的条件,在我们的查询结果里也是看不到这个节点的。所有的查询数据来自于该workspace已经持久化的数据,哪些已经改变但还没有通过session.save()(item.save())持久化到workspace的数据不在查询之列。获得QueryResult 对象后,我们就可以通过调用getNodes()方法来获得符合查询条件的节点的一个遍历。

剩下的两个未实现的方法是updateBlogEntry() 和 removeBlogEntry(),它们实现起来都很简单。我们把BOLG 标题作为主键,通过标题来获得相关的节点。在updateBlogEntry()方法里,我们直接设定需要改变的属性;在 removeBlogEntry()方法里,我们获得目标节点后直接在节点上调用remove()方法。最后别忘了一定要调用session.save()方法把我们改变的数据持久化。

处理二进制内容
对内容仓库来说,处理二进制内容是个很基本的要求,比如说图片。现在我们的示例程序容许给每个BLOG附加一张图片。下面分别是附加图片和获取图片的方法。

public void attachFileToBlogEntry(String blogTitle,
  InputStream uploadInputStream) throws BlogApplicationException {
    Session session = JackrabbitPlugin.getSession();
    Node blogEntryNode = getBlogEntryNode(blogTitle, session);
    blogEntryNode.setProperty(PROP_ATTACHMENT, uploadInputStream);
    session.save();

}
public InputStream getAttachedFile(String blogTitle) throws BlogApplicationException {
    InputStream attachFileIS = null;
    Node blogEntryNode = getBlogEntryNode(blogTitle);
    Value attachFileValue = (Value) blogEntryNode.getProperty(PROP_ATTACHMENT).getValue();
    attachFileIS = attachFileValue.getStream();
  return attachFileIS;
}

正如你看到的那样,我们的代码在处理二进制内容和一般内容间并没有什么太大的区别。仅仅一点不同的是你要通过InputStream 对象来保存和获取二进制数据。在我们的配置文件里关于persistent manager会有一个externalBLOBs 属性。把这个属性设为true, 图片将会保存在文件里,相反则会保存在数据库的blob字段里。

总结
到这里,我们对 JSR-170, Jackrabbit以及如何使用 JSR-170 API开发一个简单的应用程序都有了大概的了解。我们的讨论更多的在于基础。相信大家一定会对内容仓库有个初步的认识。

http://www.blogjava.net/ronghao 荣浩原创,Thanks!

转载于:https://www.cnblogs.com/SingleCat/archive/2008/09/26/1299721.html

什么是JAVA内容仓库(Java Content Repository)(4完)相关推荐

  1. 什么是JAVA内容仓库(Java Content Repository)(3)

    开发我们的例子程序 jackrabbit已经配置好了,现在让我们来创建我们的示例程序.这个例子程序将调用JCR-170 API.很显然,我们需要做两件事情:一个是作为后台的对数据进行增删改查(持久层) ...

  2. 什么是JAVA内容仓库(Java Content Repository)

    内容仓库模型 JSR-170 是这样定义内容仓库的,内容仓库由一组 workspace(工作空间)组成,这些workspace通常应该包含相似的内容.一个内容仓库有一个到多个 workspace.每个 ...

  3. 集成Java内容仓库和Spring

    保存各种信息对于应用程序来说非常平常,大多数时候它们是保存在关系数据库中.数据库处理规范数据类型十分在行,但是在处理如图像.文档等二进制数据时却不是那么得心应手.尽管可以用文件系统作为替代--而且它们 ...

  4. java.lang.RuntimeException: java.lang.RuntimeException: org.codehaus.plexus.component.repository.exc

    我用的是Intellij IDEA 2021版本,配的Maven版本为3.8.5版本,创建Maven工程时会报如下错误: java.lang.RuntimeException: java.lang.R ...

  5. 已解决java.lang.RuntimeException: java.lang.RuntimeException: org.codehaus.plexus.component.repository.

    已解决java.lang.RuntimeException: java.lang.RuntimeException: org.codehaus.plexus.component.repository. ...

  6. 如何从文件内容创建Java字符串?

    我已经在下面使用过一段时间了. 至少在我访问过的网站上,它似乎是分布最广的. 在Java中,是否有更好/不同的方式将文件读取为字符串? private String readFile(String f ...

  7. java 压缩jar 仓库,java服务安装(一):使用java service wrapper及maven打zip包

    tags: java jsw maven zip 1.概述 使用java开发程序,在windows平台下,一般有web应用,后台服务应用,桌面应用: web应用多数打成war包在web容器(如tomc ...

  8. 解决java.lang.IllegalStateException: The content of the adapter has changed but ListView...的问题

    我写了一个Dialog,Dialog中有一个ListView,想要点ListView中的一项后,跳转到另外一个Activity去. 但在使用时,会偶尔报出下面的错误: 02-21 14:54:28.9 ...

  9. java设置text默认内容_Eclipse自定义内容辅助基于默认Java内容辅助结果

    我正在实施任务工具.作为其中的一部分,我正在制作一个 Eclipse插件来反映某些代码级别的问题. 在Eclipse插件中,我的目标是根据主机任务的状态将一些可视化辅助工具附加到不同的Java元素.我 ...

最新文章

  1. swift使用xib绘制UIView
  2. 什么是CPU的虚拟化技术?优势又是什么
  3. CTFshow 爆破 web26
  4. python闭环最短路径_python实现最短路径的实例方法
  5. VTK:网格之SplitPolyData
  6. leetcode 775. Global and Local Inversions | 775. 全局倒置与局部倒置(Java)
  7. orton效果_如何使图片发光:Orton效果
  8. css动画与js动画的区别
  9. liunx 下的动态地址分配服务DHCP
  10. 清华大学 TUNA 协会
  11. python 一组数据 正态分布散点图_python高维数据型图表矩阵散点图
  12. 设计模式(五) 注解方式实现AOP
  13. LeedCode知识点之位运算
  14. python 图像识别男女_python实现图像识别功能
  15. 【LTspice】【LTspice添加第三方***.lib文件】
  16. Excel VBA单元格数据自增1
  17. Linux中修改或重置密码
  18. 浏览器控制bartender打印方案
  19. CSDN博客中Markdown代码转为pdf
  20. 数据库原理——T-SQL、游标

热门文章

  1. java-环境变量的配置
  2. pycharm搭建spark环境
  3. 把用户输入的文本转义(主要针对特殊符号和emoji表情)
  4. 跳转系统设置相关界面的方法
  5. ACM POJ 2965 The Pilots Brothers' refrigerator
  6. 13muduo_base库源码分析(四)
  7. 微信视频不能连接到服务器,微信无法连接到服务器
  8. 多目标优化算法_阿里提出多目标优化全新算法框架,同时提升电商GMV和CTR
  9. coco 数据集_Tensorflow对COCO目标检测数据预处理
  10. 你爱我,我爱你,IP被封很头疼【Python爬虫实战:ip代理js逆向采集】