reeeeeeeeeeee
reeeeeeeeeeee

Reputation: 139

How to append to JSON with Java and Jackson

I'm trying a simple test where the code appends a few json entries, however it is getting overwritten each time (the json file will only have 1 entry in it after running). I know I need to somehow create an array in JSON using '[]', but how would I go about doing that? Also, is there a better way to be doing this? I've been searching around and every library seems clunky with lots of user written code. Thanks

public class REEEE {

private static Staff createStaff() {

    Staff staff = new Staff();

    staff.setName("mkyong");
    staff.setAge(38);
    staff.setPosition(new String[] { "Founder", "CTO", "Writer" });
    Map<String, Double> salary = new HashMap() {
        {
            put("2010", 10000.69);
        }
    };
    staff.setSalary(salary);
    staff.setSkills(Arrays.asList("java", "python", "node", "kotlin"));

    return staff;
}

public static void main(String[] args) throws IOException {
    ObjectMapper mapper = new ObjectMapper();

    File file = new File("src//j.json");        
    for(int i = 0; i < 4; i++) {
        Staff staff = createStaff();

        try {
            // Java objects to JSON file
            mapper.writeValue(file, staff);

            // Java objects to JSON string - compact-print
            String jsonString = mapper.writeValueAsString(staff);

        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    }
}

Upvotes: 2

Views: 4503

Answers (2)

Michał Ziober
Michał Ziober

Reputation: 38655

Jackson was implemented to parse and generate JSON payloads. All extra logic related with adding new element to array and writing back to file you need to implement yourself. It should not be hard to do:

class JsonFileAppender {
    private final ObjectMapper jsonMapper;

    public JsonFileAppender() {
        this.jsonMapper = JsonMapper.builder().build();
    }

    public void appendToArray(File jsonFile, Object value) throws IOException {
        Objects.requireNonNull(jsonFile);
        Objects.requireNonNull(value);
        if (jsonFile.isDirectory()) {
            throw new IllegalArgumentException("File can not be a directory!");
        }

        JsonNode node = readArrayOrCreateNew(jsonFile);
        if (node.isArray()) {
            ArrayNode array = (ArrayNode) node;
            array.addPOJO(value);
        } else {
            ArrayNode rootArray = jsonMapper.createArrayNode();
            rootArray.add(node);
            rootArray.addPOJO(value);
            node = rootArray;
        }
        jsonMapper.writeValue(jsonFile, node);
    }

    private JsonNode readArrayOrCreateNew(File jsonFile) throws IOException {
        if (jsonFile.exists() && jsonFile.length() > 0) {
            return jsonMapper.readTree(jsonFile);
        }

        return jsonMapper.createArrayNode();
    }
}

Example usage with some usecases:

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.json.JsonMapper;
import com.fasterxml.jackson.databind.node.ArrayNode;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;

public class JsonPathApp {

    public static void main(String[] args) throws Exception {
        Path jsonTmpFile = Files.createTempFile("json", "array");
        JsonFileAppender jfa = new JsonFileAppender();

        // Add POJO
        jfa.appendToArray(jsonTmpFile.toFile(), createStaff());
        printContent(jsonTmpFile); //1

        // Add primitive
        jfa.appendToArray(jsonTmpFile.toFile(), "Jackson");
        printContent(jsonTmpFile); //2

        // Add another array
        jfa.appendToArray(jsonTmpFile.toFile(), Arrays.asList("Version: ", 2, 10, 0));
        printContent(jsonTmpFile); //3

        // Add another object
        jfa.appendToArray(jsonTmpFile.toFile(), Collections.singletonMap("simple", "object"));
        printContent(jsonTmpFile); //4
    }

    private static Staff createStaff() {
        Staff staff = new Staff();

        staff.setName("mkyong");
        staff.setAge(38);
        staff.setPosition(new String[]{"Founder", "CTO", "Writer"});
        Map<String, Double> salary = new HashMap<>();
        salary.put("2010", 10000.69);

        staff.setSalary(salary);
        staff.setSkills(Arrays.asList("java", "python", "node", "kotlin"));

        return staff;
    }

    private static void printContent(Path path) throws IOException {
        List<String> lines = Files.readAllLines(path);
        System.out.println(String.join("", lines));
    }
}

Above code prints 4 lines:
1

[{"name":"mkyong","age":38,"position":["Founder","CTO","Writer"],"salary":{"2010":10000.69},"skills":["java","python","node","kotlin"]}]

2

[{"name":"mkyong","age":38,"position":["Founder","CTO","Writer"],"salary":{"2010":10000.69},"skills":["java","python","node","kotlin"]},"Jackson"]

3

[{"name":"mkyong","age":38,"position":["Founder","CTO","Writer"],"salary":{"2010":10000.69},"skills":["java","python","node","kotlin"]},"Jackson",["Version: ",2,10,0]]

4

[{"name":"mkyong","age":38,"position":["Founder","CTO","Writer"],"salary":{"2010":10000.69},"skills":["java","python","node","kotlin"]},"Jackson",["Version: ",2,10,0],{"simple":"object"}]

Upvotes: 0

Vikas
Vikas

Reputation: 7165

You can add staff in List and then write the list to file as below,

List<Staff> staffList = new LinkedList<>()
for(int i = 0; i < 4; i++) {
    Staff staff = createStaff();
    staffList.add(staff);
}
mapper.writeValue(file, staffList);

Hope it helps.

Upvotes: 1

Related Questions