Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Loop to generate JSON

Tags:

java

json

spring

I'm implementing Java SpringBoot to make RestAPI application. I stuck with the loop below. The problem seems with the sub1_arr.add(subResult1);

I have run few test:

  1. Print the SubResult1 for each iteration: The println show correct element but when add to sub1_arr it's become duplicate.

  2. Test 1 (as shows in code) : This is suppose the initial code I wrote. Output is incorrect with duplicate output

  3. Test 2 (as show in code) : having correct output but in string form.

    while(rs.next())
    {
        if(rs.getString("status").equals("FAILED")) {
            obj.put("result", "failed"); 
            obj.put("msg", rs.getString("msg"));
        } 
        else {

            //mainResult - ignore for a while
            mainResult.put("layer1_id", rs.getString("layer1_id"));
            mainResult.put("layer1_name", rs.getString("layer1_name"));

            //subResult - layer2
            subResult1.put("layer2_id", rs.getString("layer2_id"));
            subResult1.put("layer2_name", rs.getString("layer2_name"));

            //test 1 - having incorrect output with all the element become duplicate
            sub1_arr.add(subResult1);

            //test 2 - having correct output but the output become string with \"xxx\"
            sub1_arr.add(subResult1.toString());
        }

    }

    //adding sub array to main result
    mainResult.set("layer2", sub1_arr);

Get output (unexpected)

{"layer2":[
   {"layer2_id" : "3", "layer2_name" : "name_3"},
   {"layer2_id" : "3", "layer2_name" : "name_3"},
   {"layer2_id" : "3", "layer2_name" : "name_3"} 
]}

Expected output

{"layer2":[
   {"layer2_id" : "1", "layer2_name" : "name_1"},
   {"layer2_id" : "2", "layer2_name" : "name_2"},
   {"layer2_id" : "3", "layer2_name" : "name_3"} 
]}
like image 660
Fairudin Avatar asked Aug 04 '26 17:08

Fairudin


1 Answers

This is because subResult1 object is of type Map, and the values is being overridden in each loop, as the key - being same - is being overridden. As all the elements of sub1_arr is pointing to that same object, all of them will show you the same result.

Instead, you might want to try something like that(a better way to get a json output - don't re-invent the wheel):

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;

ObjectMapper mapper = new ObjectMapper();
JsonNode rootNode = mapper.createObjectNode();
ArrayNode arrayNode = mapper.createArrayNode();

while(rs.next()) {
    ObjectNode layer = mapper.createObjectNode();   
    layer.put("layer2_id", rs.getString("layer2_id"));
    layer.put("layer2_name", rs.getString("layer2_name"));
    arrayNode.add(layer);
}

((ObjectNode) rootNode).set("layer2", arrayNode);
String jsonString = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(rootNode);
System.out.println(jsonString);

This is my test:

package com.example;

import java.util.Arrays;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;

public class Main {

    public static void main(String[] args) throws JsonProcessingException {
        ObjectMapper mapper = new ObjectMapper();
        JsonNode rootNode = mapper.createObjectNode();

        ObjectNode layer1 = mapper.createObjectNode();
        layer1.put("layer2_id", "1");
        layer1.put("layer2_name", "name_1");

        ObjectNode layer2 = mapper.createObjectNode();
        layer2.put("layer2_id2", "2");
        layer2.put("layer2_name2", "name_2");

        ObjectNode layer3 = mapper.createObjectNode();
        layer3.put("layer2_id2", "3");
        layer3.put("layer2_name2", "name_3");

        ArrayNode arrayNode = mapper.createArrayNode();
        arrayNode.addAll(Arrays.asList(layer1, layer2, layer3));

        ((ObjectNode) rootNode).set("layer2", arrayNode);

        String jsonString = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(rootNode);
        System.out.println(jsonString);
    }
}

Output:
{"layer2":[
{"layer2_id" : "1", "layer2_name" : "name_1"},
{"layer2_id" : "2", "layer2_name" : "name_2"},
{"layer2_id" : "3", "layer2_name" : "name_3"}
]}

like image 140
jumping_monkey Avatar answered Aug 06 '26 08:08

jumping_monkey



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!