我们正在评估一些技术来构建我们组织中使用的 WSDL 和 XSD 的存储库。我们的选择之一是使用Apache JackRabbit,实现 JCR 1.0 和 2.0。它几乎满足了我们对上传内容、身份验证和版本控制的期望。但是,我们还计划将几条元数据(例如,createdBy、lastModifiedBy、lastModifiedTime 等)与 WSDL 和 XSD 一起上传到存储库。我们已经阅读了 JackRabbit 网站上关于 StackOverflow、JCR 规范和 wiki 页面的几篇文章,但不太明白 - 如何验证我们上传的元数据?例如,如果我们将元数据作为 XML 格式的内容上传,我们希望存储库根据 XML 模式验证 XML。就 JCR API 而言,有没有办法在通过Session.importXML导入 XML 内容时启用 XML 验证?
2 回答
正如 Randall 所说,JCR API 不提供在您存储内容时验证内容的挂钩。
一种常见的模式是将数据上传到 JCR 树中的中间位置,例如 /incoming,并让 JCR 观察者观察这些传入的数据,对其进行验证,如果有效则将其移动到其最终位置。
另一种选择是使用 Apache Sling [1],它在 JCR 存储库之上提供了一个基于 OSGi 的可脚本化应用程序层。使用 Sling,您可以拦截 HTTP POST 请求,例如,在存储数据之前验证数据。
您可以尝试查看ModeShape。它也是一个开源(LGPL 许可)JCR 实现,但它具有“定序器”的概念,可以自动从上传的文件中获取信息,并将该信息作为结构化内容(例如,节点和属性的子图)存储在存储库中,可以像任何其他存储库内容一样搜索、查询和访问它。ModeShape 已经有很多序列,但还没有 WSDL 或 XSD 序列器(它们计划在 2011 年 5 月左右的下一个版本中出现)。
我是 ModeShape 的项目负责人,我也使用它来存储 WSDL 和 XSD 文件(以及其他文件格式)。事实上,我们正在使用 JCR 存储库来存储各种结构化元数据。
正如您所提到的,JCR 确实提供了一种导入内容的方法,但导入的 XML 文件是 JCR 规范定义的两种格式之一(系统视图和文档视图)。System View XML 格式使用 JCR 特定的元素和属性,而 Document View 将元素映射到节点,将属性映射到属性(实际上它更细微)。并且因为这个导入过程会产生额外的存储库内容(节点和属性),所以 JCR 存储库确实使用 JCR 的节点类型机制来验证这个结构。
以下是文档视图格式的 XML 文件示例:
<?xml version="1.0" encoding="UTF-8"?>
<Hybrid xmlns:car="http://www.modeshape.org/examples/cars/1.0"
xmlns:jcr="http://www.jcp.org/jcr/1.0"
xmlns:nt="http://www.jcp.org/jcr/nt/1.0"
xmlns:mix="http://www.jcp.org/jcr/mix/1.0"
jcr:primaryType="nt:unstructured"
jcr:uuid="7e999653-e558-4131-8889-af1e16872f4d"
jcr:mixinTypes="mix:referenceable">
<Toyota_x0020_Prius jcr:primaryType="car:Car"
jcr:mixinTypes="mix:referenceable"
jcr:uuid="e92eddc1-d33a-4bd4-ae36-fe0a761b8d89"
car:year="2008" car:msrp="$21,500" car:mpgHighway="45"
car:model="Prius" car:valueRating="5" car:maker="Toyota"
car:mpgCity="48" car:userRating="4"/>
<Toyota_x0020_Highlander jcr:primaryType="car:Car"
jcr:mixinTypes="mix:referenceable"
jcr:uuid="f6348fbe-a0ba-43c4-9ae5-3faff5c0f6ec"
car:year="2008" car:msrp="$34,200" car:mpgHighway="25"
car:model="Highlander" car:valueRating="5" car:maker="Toyota"
car:mpgCity="27" car:userRating="4"/>
</Hybrid>
在这里,“Hybrid”是一个“nt:unstructured”节点,它包含两个“car:Car”节点类型的节点。'car:Car' 节点类型定义如下:
[car:Car] > nt:unstructured, mix:created
- car:maker (string)
- car:model (string)
- car:year (string) < '(19|20)\d{2}' // any 4 digit number starting with '19' or '20'
- car:msrp (string) < '[$]\d{1,3}[,]?\d{3}([.]\d{2})?' // of the form "$X,XXX.ZZ", "$XX,XXX.ZZ" or "$XXX,XXX.ZZ"
// where '.ZZ' is optional
- car:userRating (long) < '[1,5]' // any value from 1 to 5 (inclusive)
- car:valueRating (long) < '[1,5]' // any value from 1 to 5 (inclusive)
- car:mpgCity (long) < '(0,]' // any value greater than 0
- car:mpgHighway (long) < '(0,]' // any value greater than 0
- car:lengthInInches (double) < '(0,]' // any value greater than 0
- car:wheelbaseInInches (double) < '(0,]' // any value greater than 0
- car:engine (string)
- car:alternateModels (reference) < 'car:Car'
如果此节点类型已在 JCR 存储库中注册,它将确保您导入的内容结构根据节点类型定义是有效的。
如果您正在谈论验证内容的值(例如,元数据值、二进制文件的结构等),我不知道有任何 JCR 存储库实现可以开箱即用地做到这一点。JCR 存储库更通用,因此您的应用程序可以通过使用 JCR 事件侦听器来观察新 XML 文件(或内容)何时上传到存储库,获取刚刚上传的二进制内容,并使用其他库来执行验证。
最后,您谈到在上传的文件上存储额外的属性。前段时间我写了一篇博文,讨论了如何定义和使用 mixin 节点类型来处理 JCR 'nt:file' 和 'nt:folder' 节点。
希望这可以帮助。