Home > Software design >  I want to add a response from an api call to a json schema -- java
I want to add a response from an api call to a json schema -- java

Time:08-26

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"
  }
}

CodePudding user response:

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"
  }
}

CodePudding user response:

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"
  }
}
  • Related