我使用以下方法在Java中创建Client API:
+ Apache Jena FrameWork
+ Hydra (用于超媒体驱动)
+ 我的私人词汇类似于Markus Lanther Event-API Vocab而不是 schema.org (对于Ontology / Vocabulary部分)
第1节:
在查看了这个Markus Lanther EventDemo repo和hydra-java之后。我发现他们正在为每个hydra创建类:将来可以破坏客户端的类。例如:
Person类(Person.java)
public class Person
{
String name;
};
但是在将来,需求名称也是一个类,例如:
public class Name
{
String firstName;
String LastName;
};
因此,为了满足此要求,我必须像这样更新Person类:
public class Person
{
Name name;
};
问题1:
我对此部分的理解是否正确?如果是,那么处理这部分的方法是什么?
第2节:
为了避免上述问题,我创建了一个GenericResource类(GenericResource.java)
public class GenericResource
{
private Model model;
public void addProperty(String propertyName,Object propertyValue)
{
propertyName = "myvocab:"+propertyName;
//Because he will pass propertyName only eg: "name" and I will map it to "myvocab:name"
//Some logic to add propertyName and propertyValue to model
}
public GenericResource retriveProperty(String propertyName)
{
propertyName = "myvocab:"+propertyName;
//Some logic to query and retrieve propertyName data from this Object add it to new GenericResource Object and return
}
public GenericResouce performAction(String actionName,String postData)
{
//Some logic to make http call give response in return
}
}
但我又遇到了很多问题:
问题1:
没有必要将每个propertyName映射到myvocab:propertyName。
有些可能映射到其他一些词汇,例如:hydra:propertyName,schema:propertyName, rdfs:propertyName,newVocab:propertyName等。
问题2:
如何验证此propertyName是否属于此类?
建议:
在GenericResource类中放置类型字段/变量。然后检查对应于该类的词汇表中的supportedProperty。
为了更清楚地假设上面的Person类也在词汇中定义并且有supportProperty:[姓名,年龄等]。所以我的GenericResource有类型" Person"并且在addProperty或其他一些操作时,我将通过vocab查询该属性是在supportedProperty列表中还是在performOction()中的supportedOperation列表中查询。
这是正确的方法吗?其他任何建议都会受到欢迎吗?
答案 0 :(得分:1)
问题1:我对此部分的理解是否正确?如是 那么处理这部分的方法是什么?
是的,这似乎是正确的。仅仅因为hydra-java决定创建类并不意味着你必须在你的实现中做同样的事情。我宁愿写一个mapper并注释一个内部类,然后可以保持稳定(你需要更新映射)。你的GenericResource方法看起来也不错。
问题1:没有必要将每个propertyName映射到 myvocab:propertyName的。有些可能映射到其他一些词汇,例如: hydra:propertyName,schema:propertyName,rdfs:propertyName, newVocab:propertyName等。
为什么不存储和访问包含完整网址的属性,即包含词汇?你当然可以实现一些方便的方法来简化你的词汇工作。
问题2:如何验证此propertyName是否属于此属性 班级
建议:在GenericResource类中放置类型字段/变量
节点对象中的JSON-LD @type
(不在@value
个对象中)对应rdf:type
。所以只需将其添加为其他所有属性。
然后检查对应于该类的词汇表中的supportedProperty。
请注意supportedProperty
仅告诉您已知哪些属性受支持。它没有告诉你哪些不是。换句话说,在对象/资源上具有除supportedProperty
列出的属性之外的属性是有效的。
答案 1 :(得分:1)
广告Q1: 为了您想要的灵活性,客户必须为语义和结构变化做好准备。
在可能的HTML中。服务器可以按照您概述的方式更改html表单的结构,方法是使用firstName和lastName字段而不仅仅是名称字段。客户端不会破坏,而是根据新语义调整其UI。诀窍是UI是生成的,而不是固定的。
尝试将传入消息解组为固定表示形式(例如Java bean)的客户端运气不好,我认为没有任何解决方案可以如何反序列化为Java bean并在更改之后存活下来你的。
如果您不尝试反序列化,但坚持阅读并将传入的消息处理为更灵活的表示,那么您可以实现您之后的那种可演化性。客户端必须能够相应地处理灵活的表示。它可以生成UI而不是将数据绑定到固定标记,这意味着它不会对数据的语义和结构做出任何假设。如果客户端必须知道数据元素的含义,那么服务器就无法改变相关的语义,它只能添加具有新语义的新项目,同时保持旧的语义。
如果服务器如何使用现有客户端的按需代码适配器分发新结构,那么服务器将获得大量的可演化性。但我还没有发现任何此类解决方案。
广告Q2: 如果您的目标是在客户端读取传入的json-ld响应到Jena模型,请参阅https://jena.apache.org/documentation/io/rdf-input.html
Model model = ModelFactory.createDefaultModel() ;
String base = null;
model.read(inputStream, base, "JSON-LD");
因此,您的客户端不会因为无法读取传入的响应而中断。我认为这也是GenericResource的成就。但是你可以直接在客户端使用Jena。基本上,您可以避免解组成固定类型。