Home > Blockchain >  Is there a way to fetch Json values within Json?
Is there a way to fetch Json values within Json?

Time:06-09

I've got a Scenario Entity in my Spring boot app

private Long id;

private String scenarioName;

private HashMap<Integer, Object> scenarioAttributes;

Let's say we create a Scenario entity with following Json:

{
"scenarioName":"scenario1",
"scenarioAttributes":{
    "1" : {
        "goToURL":"https://google.com/"
    },
    "2" : {
        "assertCurrentUrl":"https://google.com/"
    }
}
}

In my ExecutorService, I've got following code:

public List<Object> getStepsFromScenarioAttributesValues(Long scenarioId){
        List<Object> response = new ArrayList<>();

        Scenario scenario = scenarioService.getScenario(scenarioId);
        HashMap<Integer, Object> steps = scenario.getScenarioAttributes();
        for (Map.Entry<Integer, Object> set : steps.entrySet()){
            response.add(set.getValue());
            System.out.println(response);

            // prints out 
            //[{goToURL=https://google.com/}, {assertCurrentUrl=https://google.com/}]
 

        }
        return response;


}


public void executeSteps(List<Object> response){
        
        for (Object obj : response){
            JsonObject jsonObj = (JsonObject) obj;

            if (jsonObj.has("goToUrl")) {
                //goes to url
                driverService.goToUrl(String.valueOf(jsonObj.get("goToUrl")));
                return;
            } else if (jsonObj.has("assertCurrentUrl")) {
                //asserts cur url with value
                driverService.assertCurrentUrl(String.valueOf(jsonObj.get("assertCurrentUrl")));
                return;
            }
        }
    }

public String executeScenario(Long scenarioId){
        executeSteps(getStepsFromScenarioAttributesValues(scenarioId));
        return "Scenario"   scenarioId   " has been executed successfully";
    }

I've got a GetMapping for single scenario as follows:

@GetMapping("/scenarios/{id}/execute")
    public List<Object> executeScenario(@PathVariable Long id){
        return executorService.getStepsFromScenarioAttributesValues(id);
    }

Which, upon sending one sample scenario and entering a site, provides us with, you guessed it, a List containing an Object, which is a Json.

Unfortunately, if I want to call executeSteps() function which has a list of Objects, I cannot do it since an Object is not a JsonObject.

I thought simple JsonObject jsonObj = (JsonObject) obj; would do a trick, but I'm greeted with class java.util.LinkedHashMap cannot be cast to class com.google.gson.JsonObject (java.util.LinkedHashMap is in module java.base of loader 'bootstrap'; com.google.gson.JsonObject is in unnamed module of loader 'app')

How can I approach fetching values from scenarioAttributes Jsons to further interpret them? Are there unnecessary lines of code that I could get rid of?

Feel free to point out my wrongdoings, just starting my journey with Spring

CodePudding user response:

public class Scenario {
    private String scenarioName;
    private HashMap<Integer, Object> scenarioAttributes;
}

Use object mapper to print class object to JSON:

ObjectMapper objectMapper = new ObjectMapper();
Scenario scenario = objectMapper.readValue(response, Scenario.class);

CodePudding user response:

When you say Object, which is a Json what do you mean by "Json"? Json is not a class. I assume that your Object is an instance of class String that contains text in Json format. Your exception though points out that it could be a Map. I would still assume that it is a String that holds Json. In your code you attempt to work with class JSONObject which is part of json-simple library. While it is a nice training library I would suggest that you don't use it. BTW great site about JSON with the list of most libraries for most languages is: https://www.json.org/json-en.html. Best options are (IMHO) are Jackson-Json (also known as Faster XML) or Gson (by Google) (Here is their user guide site). To parse your Json text to a class instance you can use ObjectMapper class which is part of Jackson-Json library. For example

public <T> T readValue(String content,
              TypeReference valueTypeRef)
            throws IOException,
                   JsonParseException,
                   JsonMappingException

See Javadoc. But I also may suggest a very simplified JsonUtils class which is a thin wrapper over Jackson-Json library. This class is part of Open-source library called MgntUtils written and maintained by me. Your code may be as simple as follows:

Scenario scenario;    
try {   
        scenario = JsonUtils.readObjectFromJsonString(response, Scenario.class);
     } catch(IOException ioe) {
       ....
     }

Here is JsonUtils javadoc. MgntUtils library can be obtained as Maven artifact here or on Github (including source code and Javadoc)

  • Related