简体   繁体   中英

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.

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].

This works great if I have a strongly typed object added to the variable resolver...

Because the variable resolver uses reflection to find the property names on a variable value, and does the replacement in json. But if the variable added to the resolver is a JsonObject, the properties I need are not available.

Examples:

I set a variable called 'project' in the resolver, from the output of this method. [projectResponse.rootNode]

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

Json Files -

First json file works because I added the project NodeReference to the variable resolver -

{
  "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.
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]

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 -

{
  "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.

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"]) (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.

Turns out the template engine I'm using can handle a Map object, and access the key like a property.
I fixed it by converting the JsonObject to a HashMap.

return response.mapTo(HashMap.class);

If you have a JSON String you can convert it to any class using the JsonUtil#readValue. I think this should be exposed if you are using the Mesh Rest Client. So in your case, for the request you can use 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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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