Home > front end >  How can I read two JSON files with different data at the same time?
How can I read two JSON files with different data at the same time?

Time:02-06

My part of the task is:


I need to collect productId-s into list from two JSON files with different data and pass it into the custom method with directory of JSON files.

I have two JSON files with different data as the following:

  1. JSON №1
  2. JSON №2

And my code is in the next format:

public class Main {
    public static void main(String[] args) throws IOException, ParseException {
        JSONParser parser = new JSONParser();
        InputStream isOne = JSONParser.class.getResourceAsStream("/test/java/resources/json/file/product_0001690510.json");
        InputStream isTwo = JSONParser.class.getResourceAsStream("/test/java/resources/json/file/product_0001694109.json");

        // ... need to use somehow InpuStream for reading two JSON files with different structure inside

        JSONArray arr = obj.getJSONArray("products"); // notice that `"products": [...]` 
        String productId = null;
        for (int i = 0; i < arr.length(); i  ) {
            productId = arr.getJSONObject(i).getString("productID");
        }

        List<String> productIds = new ArrayList<>(Collections.singleton(productId));

        for (var file : obj.keySet()) {
            System.out.println(getAllExportsWithProductIds(file, productIds));
        }
    }

    public static List<String> getAllExportsWithProductIds(String directory, List<String> productIds) throws IOException {
        var matchingObjects = new ArrayList<String>();
        try (var fileStream = Files.walk(Path.of(directory))) {
            for (var file : fileStream.toList()) {
                var json = Json.readString(Files.readString(file));
                var objects = JsonDecoder.array(json);

                for (var object : objects) {
                    var objectProductIDs = JsonDecoder.field(
                            object, "products",
                            JsonDecoder.array(JsonDecoder.field("productID", JsonDecoder::string))
                    );
                    for (var productId : objectProductIDs) {
                        if (productIds.contains(productId)) {
                            matchingObjects.add(Json.writeString(object));
                            break;
                        }
                    }
                }
            }
        }
        return matchingObjects;
    }
}

Full code

Based on it my question is:

Can I read all provided JSON files at the same time to collect productId-s into list? If yes, how can I do that if I have the different data of two JSON files.

To clarify a bit:

"By different data, I mean, in general, the number of these fields (for example, productId fields in both of JSON-s: №1 and №2 accordingly), their order. That is, how an array object differs from another.

If these JSON-s have the same data, it'd be easier to parse, but in this specific usecase I need to find the way how to handle both of them in different way as their data is not in the same format of representation."

My detailed explanation how I see it in abstract way:

How I see it abstractly in the lifecycle of developing.

I've already read different articles and checked libraries as:

  1. java-jq
  2. Jackson object mapper tutorial

and so on,

but I'm still struggling with understanding how to apply it correctly, for this reason, I'm looking for a concrete solution.

Thank you in advance for any smart and helpful ideas. If you need some additional details, I'm ready to provide without any problem.


UPD:

There's I have another version of code, which is collecting productID-s, I need just to find the way how to combine with the first version of code and that's it:

public class ProductIdImporter {
    public ProductIdImporter() {
// TODO Auto-generated constructor stub
    }

    public void importJson() {
        List<Path> paths = Arrays.asList(Paths.get("C:\\Users\\pc\\IdeaProjects\\jsonapi\\src\\test\\java\\resources\\json\\product_0001690510.json"),
                                         Paths.get("C:\\Users\\pc\\IdeaProjects\\jsonapi\\src\\test\\java\\resources\\json\\product_0001694109.json"));
        ObjectMapper jsonMapper = new ObjectMapper().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        Set<String> productIds = paths.stream().map(path -> {
                    try {
                        return jsonMapper.readValue(Files.newInputStream(path), ExportList[].class);
                    } catch (Exception e) {
                        throw new RuntimeException(e);
                    }
                }).map(Arrays::asList)
                .flatMap(List::stream)
                .map(ExportList::productList)
                .flatMap(List::stream)
                .map(Product::getId)
                .collect(Collectors.toSet());
        productIds.forEach(System.out::println);
    }

    public static void main(String[] args) {
        ProductIdImporter importer = new ProductIdImporter();
        importer.importJson();
    }

    static class ExportList {
        public List<Product> products;

        public ExportList() {
        }

        public List<Product> productList() {
            return products;
        }
    }

    static class Product {
        public String productID;

        public Product() {
        }

        public String getId() {
            return productID;
        }
    }
}

CodePudding user response:

Taking the JSON №1 you have included in your post basically it is an array of json objects with the same format like below (I have included just the first one element and deleted all the properties you are not interested to parse):

[{
    "products": [
      {
        "colorWayID": "IMP5002620012114",
        "productID": "0001755256"
      },
      {
        "colorWayID": "IMP8473190012114",
        "productID": "0001690510"
      },
      {
        "colorWayID": "IMP9100570012114",
        "productID": "0001700877"
      }
    ],
    ...other properties excluded from parsing
}]
    

To iterate over this array you can read your json file into a ArrayNode and iterate over every element:

ArrayNode arrayNode = (ArrayNode) mapper.readTree(json);
for (int i = 0; i < arrayNode.size();   i) {/*inspecting products property*/}

The products property is an array of JsonNode containing the productID property you want to extract, you can use the JsonNode#get method to extract both the products and productID properties:

List<String> productIds = new ArrayList<>();
ArrayNode arrayNode = (ArrayNode) mapper.readTree(json);
for (int i = 0; i < arrayNode.size();   i) {
    //products property is also an array
    ArrayNode products =(ArrayNode) arrayNode.get(i).get("products");
    for (int j = 0; j < products.size();   j) {
        //adding productId to your list
        productIds.add(products.get(j).get("productID").asText());
    }  
}

This process can be repeated for other json files with variations depending from the json structure contained in them, but substantially it remains the same.

  • Related