简体   繁体   中英

I want to add a response from an api call to a json schema -- java

I have this response from calling an API:


           HttpResponse<String> response = Unirest.post(url)
                        .field("files", file)
                        .asString();

The response.getbody() from API looks like this:

[{
  "step1": {
    "name1": "Will",
    "name2": "Smith",
    "name2_2":"Kara"
  },
  "step2": {
    "name3": "Margaret",
    "name4": "Maria",
    "name5": "Gordon",
    "name6":"Alex"
  },
"step3":{
   "name7":"Dana",
   "name8:"Sarah"

}
}]

And I want to map the responseAPI to the schema below to the matched keys:

{
  "step1": {
    "name1": "null",
    "name2": "null"
  },
  "step2": {
    "name3": "null",
    "name4": "null",
    "name5": "null"
  }
}

By default, there is no magic going on mapping the incoming response to your desired schema (or maybe better: template). You have to map it yourself and you have several options:

Define your schema as model Pojos and use the ObjectMapper's readValue() method to let the ObjectMapper try to parse the body response into your desired format ( further reading ). This is the more scalable approach as you can use all of Jackson's annotation magic.

Alternatively, if you want a quick manual solution, you can extend your code and manually map the properties like this:

public static void main(String[] args) throws JsonMappingException, JsonProcessingException {
  ObjectMapper mapper = new ObjectMapper();
  String apiSchemaFile = "{\n  \"step1\": {\n    \"name1\": \"null\",\n    \"name2\": \"null\"\n  },\n  \"step2\": {\n    \"name3\": \"null\",\n    \"name4\": \"null\",\n    \"name5\": \"null\"\n  }\n}";
  String apiResponse = "[{\n  \"step1\": {\n    \"name1\": \"Will\",\n    \"name2\": \"Smith\",\n    \"name2_2\":\"Kara\"\n  },\n  \"step2\": {\n    \"name3\": \"Margaret\",\n    \"name4\": \"Maria\",\n    \"name5\": \"Gordon\",\n    \"name6\":\"Alex\"\n  },\n\"step3\":{\n   \"name7\":\"Dana\",\n   \"name8\":\"Sarah\"\n\n}\n}]";
  
  JsonNode jsonFieldNode = mapper.readTree(apiSchemaFile);
  JsonNode jsonInputNode = mapper.readTree(apiResponse);
  // get the first element of the array and iterate trough the object's properties
  jsonInputNode.get(0).fields().forEachRemaining(groupNode -> {
    groupNode.getValue().fields().forEachRemaining(nameNode -> {
      // check each name property against the template
      JsonNode targetGroup = jsonFieldNode.path(groupNode.getKey());
      if(!targetGroup.isMissingNode() && targetGroup.has(nameNode.getKey())) {
        // if the template as the same property, fill it with the value from the response
        ((ObjectNode)targetGroup).set(nameNode.getKey(), nameNode.getValue());
      }
    });
  });

  System.out.println(jsonFieldNode.toPrettyString());
}

which will give you

{
  "step1" : {
    "name1" : "Will",
    "name2" : "Smith"
  },
  "step2" : {
    "name3" : "Margaret",
    "name4" : "Maria",
    "name5" : "Gordon"
  }
}

Library Josson & Jossons has set operations.

https://github.com/octomix/josson

Jossons jossons = new Jossons();
jossons.putDataset("schema", Josson.fromJsonString(
    "{" +
    "  \"step1\": {" +
    "    \"name1\": \"null\"," +
    "    \"name2\": \"null\"" +
    "  }," +
    "  \"step2\": {" +
    "    \"name3\": \"null\"," +
    "    \"name4\": \"null\"," +
    "    \"name5\": \"null\"" +
    "  }" +
    "}"));
jossons.putDataset("response", Josson.fromJsonString(
    "[{" +
    "  \"step1\": {" +
    "    \"name1\": \"Will\"," +
    "    \"name2\": \"Smith\"," +
    "    \"name2_2\": \"Kara\"" +
    "  }," +
    "  \"step2\": {" +
    "    \"name3\": \"Margaret\"," +
    "    \"name4\": \"Maria\"," +
    "    \"name5\": \"Gordon\"," +
    "    \"name6\": \"Alex\"" +
    "  }," +
    "  \"step3\":{" +
    "    \"name7\": \"Dana\"," +
    "    \"name8\": \"Sarah\"" +
    "  }" +
    "}]"));
JsonNode node = jossons.evaluateQuery("schema >+> response->[0] | >-> response->[0]");
System.out.println(node.toPrettyString());

First, concatenate schema into response[0] produce:

schema >+> response->[0]

{
  "step1" : {
    "name1" : "null",
    "name2" : "null",
    "name2_2" : "Kara"
  },
  "step2" : {
    "name3" : "null",
    "name4" : "null",
    "name5" : "null",
    "name6" : "Alex"
  },
  "step3" : {
    "name7" : "Dana",
    "name8" : "Sarah"
  }
}

Finally, subtract the above result from response[0] produce:

| >-> response->[0]

{
  "step1" : {
    "name1" : "Will",
    "name2" : "Smith"
  },
  "step2" : {
    "name3" : "Margaret",
    "name4" : "Maria",
    "name5" : "Gordon"
  }
}

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