如何发送 Json 对象请求,并在 Mesh RestClient 中接收节点响应?

How can I send a JsonObject request, and recieve a NodeResponse in the MeshRestClient?

在我的 Gentics Mesh 插件中,我从 json 文件创建节点。

我创建了一个脚本进程,用实际值替换 json 文件中的变量占位符 [例如,来自之前的节点创建事件]。

如果我将强类型对象添加到变量解析器中,这会非常有效...

因为变量解析器使用反射在变量值上查找 属性 名称,并在 json 中进行替换。 但是如果添加到解析器的变量是一个Json对象,我需要的属性就得不到了。

示例:

我根据此方法的输出在解析器中设置了一个名为 'project' 的变量。 [projectResponse.rootNode]

private ProjectResponse createProject(String project) {
    ProjectCreateRequest createProject = new ProjectCreateRequest()
            .setName(project)
            .setSchemaRef("folder");
    return this.adminClient.createProject(createProject).blockingGet();
}

Json 个文件 -

第一个 json 文件有效,因为我将项目 NodeReference 添加到变量解析器 -

{
  "parentNode" : {
    "uuid" : "<project.uuid>"
  },
  "schema" : {
    "name" : "folder"
  },
  "language" : "en",
  "fields" : {
    "name" : "node1 - child of project root node"
  }
}

该创建的响应是一个 Json对象,然后我将其传递给变量解析器。
然后我创建第二个节点。
注意 我正在使用通用 post 方法 [我不知道如何从 json 字符串创建 NodeCreateRequest,这也可以解决这个问题]

private JsonObject createNode(String project, String processedNode) {
        JsonObject request = new JsonObject(processedNode);
        JsonObject response = this.adminClient.post(String.format("/%s/nodes", project), request).blockingGet();
        return response;
    }

第二个 json 文件不起作用,因为 node1 是一个 Json 对象,并且没有 uuid 属性 -

{
  "parentNode" : {
    "uuid" : "<node1.uuid>"
  },
  "schema" : {
    "name" : "folder"
  },
  "language" : "en",
  "fields" : {
    "name" : "node2 - child of node1"
  }
}

我无法自动将 JsonObject 映射到 NodeResponse - FieldMap 有许多不同的实现,所以我不知道是否可以添加 Mapper 模块来解决这个问题。

private NodeResponse createNode(String project, String processedNode) {
        JsonObject request = new JsonObject(processedNode);
        JsonObject response = this.adminClient.post(String.format("/%s/nodes", project), request).blockingGet();
        return response.mapTo(NodeResponse.class);
}

Caused by: com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot construct instance ofcom.gentics.mesh.core.rest.node.FieldMap(no Creators, like default construct, exist): abstract types either need to be mapped to concrete types, have custom deserializer, or contain additional type information at [Source: UNKNOWN; line: -1, column: -1] (through reference chain: com.gentics.mesh.core.rest.node.NodeResponse["fields"])

我想我已经通过将 Map 包装在另一个 class 中解决了类似的用例,然后当反射发生时,我 return 我自己的 属性 值基于Map 中的键...但那是 C#...而且是很久以前的事了。

事实证明,我使用的模板引擎可以处理 Map 对象,并像 属性 一样访问密钥。
我通过将 JsonObject 转换为 HashMap 来修复它。

return response.mapTo(HashMap.class);

如果您有一个 JSON 字符串,您可以使用 JsonUtil#readValue 将其转换为任何 class。如果您使用的是 Mesh Rest Client,我认为这应该公开。因此,在您的情况下,对于请求,您可以使用 JsonUtil.readValue(json, NodeCreateRequest.class).

如果你还想使用泛型方法,我认为最好的方法是将 JsonObject 转换为 String,然后使用 readValue 方法。