runnerpaul
runnerpaul

Reputation: 7196

Trying to read values from array nested in JSON

I've been writing a Rest service using Jackson to extract the name and sizeFromStorage inside the response value.

I created the below classes in an attempt to do this:

import java.util.List;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;

@JsonIgnoreProperties(value = {"status", "header"})
public class Vaults {

private List<Object> response;

public Vaults(){

}

public Vaults(List<Object> response){
    this.response = response;
}

public List<Object> getResponse(){
    return response;
}

public void setResponse(List<Object> response) {
    this.response = response;
}

@Override
public String toString() {
    return "" + response;
}
}


import java.io.IOException;
import java.util.List;
import java.util.ArrayList;

import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.type.CollectionType;
import java.io.InputStream;

public class JacksonObjectModelTest {

public static void main(String[] args) throws IOException {
    String jsonFileName = "/JsonRead/json.json";
    List<Vaults> emps = new JacksonObjectModelTest().getVaultList(jsonFileName);
    System.out.println(emps.toString());
}

public ArrayList<Vaults> getVaultList(String jsonFileName) throws IOException {
    //read json file data to String
    InputStream inputStream = getClass().getResourceAsStream(jsonFileName);

    //create ObjectMapper instance
    ObjectMapper objectMapper = new ObjectMapper().enable(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY);

    //convert json string to object
    CollectionType collectionType = objectMapper.getTypeFactory().constructCollectionType(List.class, Vaults.class);
    ArrayList<Vaults> emps = objectMapper.readValue(inputStream, collectionType);
    return (ArrayList<Vaults>) emps;
}
}

{
  "status": "ok",
  "header": {
    "now": 1491545894581,
    "status": "ok",
    "requestId": "WOcvJsCoAmoAAESbkBYAAAB5"
  },
  "response": {
    "vault": [
      {
    "id": 20,
    "name": "Apple",
    "description": "",
    "sizeFromStorage": 95957225298,
    "storagePools": [
      {
        "storagePool": {
          "id": 1,
          "name": "storage-pool1",
          "sizeFromStorage": 95957225298,
          "generations": [
            {
              "generation": {
                "sequence": 0
              }
            }
          ]
        }
      }
    ]
  },
  {
    "id": 21,
    "name": "Banana",
    "description": "",
    "sizeFromStorage": 98957268244,
    "storagePools": [
      {
        "storagePool": {
          "id": 2,
          "name": "storage-pool1",
          "sizeFromStorage": 98957268244,
          "generations": [
            {
              "generation": {
                "sequence": 0
              }
            }
          ]
        }
      }
    ]
  },
]
  }
}

The output I get from this is:

[[{vaults=[{id=20, name=Apple, description=, sizeFromStorage=95957225298, storagePools=[{storagePool={id=1, name=storage-pool1, sizeFromStorage=5043, estimateUsableTotalLogicalSizeFromStorage=95957225298, generations=[{generation={sequence=0}}]}}]}, {id=20, name=Apple, description=, sizeFromStorage=95957225298, storagePools=[{storagePool={id=1, name=storage-pool1, sizeFromStorage=5043, estimateUsableTotalLogicalSizeFromStorage=95957225298, generations=[{generation={sequence=0}}]}}]}]]

However, what I want to do is the name and sizeFromStorage values. So far I've managed to strip out the first three values. Unfortunately I'm now stuck as I'm not very familiar with Rest services or reading JSON. Is there any way I can delve further into the JSON to get what I need or have I approached this in the wrong way?

Additional info: Since posting my original question I came up with this(based on something I saw on a different site):

package JsonRead;

import java.io.File;
import java.io.IOException;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;

public class JacksonTreeModel {
    public static void main(String[] args) {

        try{

            ObjectMapper mapper = new ObjectMapper();

            JsonNode root = mapper.readTree(new File("JsonRead/json.json"));

            JsonNode vaultsNode = root.path("response").path("vault");

            /*if(vaultsNode.isArray()){
                for(JsonNode node : vaultsNode){
                    String name = node.path("name").asText();
                    System.out.println("Array Name: " + name);
                }
            }*/

            for(JsonNode node : vaultsNode){
                String name = node.path("name").asText();
                String bytesUsed = node.path("sizeFromStorage").asText();
                System.out.println("Name: " + name + ", Bytes Used: " + bytesUsed);
            }

        } catch(IOException e){
                System.out.println("IO Exception " + e );
        }
    }
}

It works for what I want but is there a better way to do this?

Will, thanks for the response. I'll look into your suggestion.

Upvotes: 0

Views: 254

Answers (1)

Will Faulkner
Will Faulkner

Reputation: 236

Ok, so i just re-read your question.

Recommend creating yourself a VaultDAO object with a more meaningful custom object type to use for the response collections. Prvoided you use the same variable names (which it looks like are known to you) then it should deserialize for you

Upvotes: 1

Related Questions