简体   繁体   English

如何发送 JsonObject 请求,并在 MeshRestClient 中接收 NodeResponse?

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

In my Gentics Mesh plugin, I'm creating Nodes from json files.在我的 Gentics Mesh 插件中,我从 json 文件创建节点。

I've created a scripting process that replaces variable placeholders in a json file, with actual values [for example, from a previous node creation event].我创建了一个脚本过程,用实际值 [例如,来自先前的节点创建事件] 替换 json 文件中的变量占位符。

This works great if I have a strongly typed object added to the variable resolver...如果我将强类型 object 添加到变量解析器中,这将非常有用...

Because the variable resolver uses reflection to find the property names on a variable value, and does the replacement in json.因为变量解析器使用反射来查找变量值上的属性名称,并在 json 中进行替换。 But if the variable added to the resolver is a JsonObject, the properties I need are not available.但是如果添加到解析器的变量是JsonObject,我需要的属性不可用。

Examples:例子:

I set a variable called 'project' in the resolver, from the output of this method.我在解析器中设置了一个名为“project”的变量,来自此方法的 output。 [projectResponse.rootNode] [projectResponse.rootNode]

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

Json Files - Json 文件 -

First json file works because I added the project NodeReference to the variable resolver -第一个 json 文件有效,因为我将项目 NodeReference 添加到变量解析器 -

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

The response of that creation is a JsonObject, which I then pass into the variable resolver.该创建的响应是一个 JsonObject,然后我将其传递给变量解析器。
Then I create a second node.然后我创建第二个节点。
Note I'm using the generic post method [I don't know how to create a NodeCreateRequest from a json string, which could also solve this]注意我使用的是通用 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;
    }

Second json file doesn't work because node1 is a JsonObject, and doesn't have a uuid property -第二个 json 文件不起作用,因为node1是 JsonObject,并且没有 uuid 属性 -

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

I can't automatically map the JsonObject to a NodeResponse - And a FieldMap has many different implementations, so I don't know if I could add a Mapper module to fix this.我不能将 JsonObject 自动 map 到 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 of com.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"]) Caused by: com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot construct instance of com.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"]) (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"])

I think I've solved a similar use case by wrapping a Map in another class, then when the reflection occurs, I return my own property values based on the keys in the Map... but that was C#... and a long time ago. I think I've solved a similar use case by wrapping a Map in another class, then when the reflection occurs, I return my own property values based on the keys in the Map... but that was C#... and a long过去。

Turns out the template engine I'm using can handle a Map object, and access the key like a property.原来我使用的模板引擎可以处理 Map object,并像访问属性一样访问密钥。
I fixed it by converting the JsonObject to a HashMap.我通过将 JsonObject 转换为 HashMap 来修复它。

return response.mapTo(HashMap.class);

If you have a JSON String you can convert it to any class using the JsonUtil#readValue.如果您有 JSON 字符串,您可以使用 JsonUtil#readValue 将其转换为任何 class。 I think this should be exposed if you are using the Mesh Rest Client.如果您使用的是 Mesh Rest 客户端,我认为这应该暴露出来。 So in your case, for the request you can use JsonUtil.readValue(json, NodeCreateRequest.class) .因此,在您的情况下,对于请求,您可以使用JsonUtil.readValue(json, NodeCreateRequest.class)

If you still want to use the generic methods, I believe the best way is to convert the JsonObject to a String and then use the readValue method.如果你还想使用泛型方法,我认为最好的方法是将 JsonObject 转换为 String ,然后使用 readValue 方法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM