在java中创建基于JsonLd + Hydra的通用客户端API。有没有可供参考的项目?

时间:2017-02-01 08:33:30

标签: java sparql jena apache-jena hydra-core

我使用以下方法在Java中创建Client API:
+ Apache Jena FrameWork
+ Hydra (用于超媒体驱动)
+ 我的私人词汇类似于Markus Lanther Event-API Vocab而不是 schema.org (对于Ontology / Vocabulary部分)

第1节:
在查看了这个Markus Lanther EventDemo repohydra-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列表中查询。
这是正确的方法吗?其他任何建议都会受到欢迎吗?

2 个答案:

答案 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。基本上,您可以避免解组成固定类型。