33

How can I create a json array like the example below using jackson.

I tried using ObjectMapper, but this does not seem correct.

      try (DirectoryStream<Path> ds = Files.newDirectoryStream(path)) {
            for (Path file : ds) {
                System.out.println("name:"+file.getFileName()+
                        "\n"+
                        "mime:"+Files.probeContentType(file)+
                "\n"+
                "locked:"+!Files.isWritable(file));
            }
        } catch (IOException e) {
            System.err.println(e);
        }

Eventually I will be making a json that has the below values.

 * - (int)    size    file size in b. required
 * - (int)    ts      file modification time in unix time. required
 * - (string) mime    mimetype. required for folders, others - optionally
 * - (bool)   read    read permissions. required
 * - (bool)   write   write permissions. required
 * - (bool)   locked  is object locked. optionally
 * - (bool)   hidden  is object hidden. optionally
 * - (string) alias   for symlinks - link target path relative to root path. optionally
 * - (string) target  for symlinks - link target path. optionally

Here is an example json I was provided.

"files": [
    {
        "mime": "directory",
        "ts": 1334071677,
        "read": 1,
        "write": 0,
        "size": 0,
        "hash": "l1_Lw",
        "volumeid": "l1_",
        "name": "Demo",
        "locked": 1,
        "dirs": 1
    },
    {
        "mime": "directory",
        "ts": 1334071677,
        "read": 1,
        "write": 0,
        "size": 0,
        "hash": "l1_Lw",
        "volumeid": "l1_",
        "name": "Demo",
        "locked": 1,
        "dirs": 1
    },
    {
        "mime": "directory",
        "ts": 1340114567,
        "read": 0,
        "write": 0,
        "size": 0,
        "hash": "l1_QmFja3Vw",
        "name": "Backup",
        "phash": "l1_Lw",
        "locked": 1
    },
    {
        "mime": "directory",
        "ts": 1310252178,
        "read": 1,
        "write": 0,
        "size": 0,
        "hash": "l1_SW1hZ2Vz",
        "name": "Images",
        "phash": "l1_Lw",
        "locked": 1
    },
    {
        "mime": "application\/x-genesis-rom",
        "ts": 1310347586,
        "read": 1,
        "write": 0,
        "size": 3683,
        "hash": "l1_UkVBRE1FLm1k",
        "name": "README.md",
        "phash": "l1_Lw",
        "locked": 1
    }
]

EDIT 1

        Map<String, Object> filesMap = new HashMap<>();
        List<Object> files = new ArrayList<Object>();
        System.out.println("\nNo filter applied:");
        try (DirectoryStream<Path> ds = Files.newDirectoryStream(path)) {
            for (Path file : ds) {
                Map<String, Object> fileInfo = new HashMap<>();
                fileInfo.put("name", file.getFileName().toString());
//                Prints Files in Director
//                Files.getAttribute(file,"size");
                System.out.println("name:" + file.getFileName().toString() +
                        "\n" +
                        "mime:" + Files.probeContentType(file) +
                        "\n" +
                        "locked:" + !Files.isWritable(file));
                ObjectMapper mapper = new ObjectMapper();
                String json = mapper.writeValueAsString(fileInfo);
                files.add(json);
            }
        } catch (IOException e) {
            System.err.println(e);
        }
        files.toArray();
        filesMap.put("files", files);
        ObjectMapper mapper = new ObjectMapper();
        String jsonString;
        try {
            jsonString = mapper.writeValueAsString(filesMap);
        } catch (IOException e) {
            jsonString = "fail";  //To change body of catch statement use File | Settings | File Templates.
        }

Puts out the following json which is closer, but I can't figure out why the extra quotes before and after the {}.

{"files":["{\"name\":\"32C92124-EFCF-42C1-AFD2-8B741AE6854B.jpg\"}","{\"name\":\"58D5B83F-4065-4D6E-92BE-8181D99CB6CB.jpg\"}","{\"name\":\"7B1464A0-FBA1-429E-8A39-3DE5B539FBF8.jpg\"}","{\"name\":\"888159CF-45BE-475F-8C6A-64B3E1D97278.jpg\"}"]}

Final Answer

    Map<String, Object> filesMap = new HashMap<>();
    List<Object> files = new ArrayList<Object>();
    System.out.println("\nNo filter applied:");
    try (DirectoryStream<Path> ds = Files.newDirectoryStream(path)) {
        for (Path file : ds) {
            Map<String, Object> fileInfo = new HashMap<>();
            fileInfo.put("name", file.getFileName().toString());
            System.out.println("name:" + file.getFileName().toString() +
                    "\n" +
                    "mime:" + Files.probeContentType(file) +
                    "\n" +
                    "locked:" + !Files.isWritable(file));
            files.add(fileInfo);
        }
    } catch (IOException e) {
        System.err.println(e);
    }
    files.toArray();
    filesMap.put("files", files);
    ObjectMapper mapper = new ObjectMapper();
    String jsonString;
    try {
        jsonString = mapper.writeValueAsString(filesMap);
    } catch (IOException e) {
        jsonString = "fail"; 
    }
zmanc
  • 5,201
  • 12
  • 45
  • 90
  • 1
    Your question seems to be missing an actual question. – Aurand Jun 07 '13 at 00:39
  • Sorry, with the plethora of internet issues I am having tonight I think I forgot to add that. :P Does it make more sense now? – zmanc Jun 07 '13 at 00:49
  • I am pretty confused. There is no apparent use of `ObjectMapper` here. Are you trying to convert something to use `ObjectMapper` or what? – nicholas.hauschild Jun 07 '13 at 00:51
  • You've shown your desired input and output, but nothing of what you have actually attempted re: actual conversion code. Have you read through the [Jackson in Five Minutes tutorial](http://wiki.fasterxml.com/JacksonInFiveMinutes)? – Perception Jun 07 '13 at 00:55
  • I went through the tutorial and it is helping, not quite there yet, but getting close. – zmanc Jun 07 '13 at 11:24

4 Answers4

56

You need a JsonNodeFactory:

final JsonNodeFactory factory = JsonNodeFactory.instance;

This class has methods to create ArrayNodes, ObjectNodes, IntNodes, DecimalNodes, TextNodes and whatnot. ArrayNodes and ObjectNodes have convenience mutation methods for adding directly most JSON primitive (non container) values without having to go through the factory (well, internally, they reference this factory, that is why).

As to an ObjectMapper, note that it is both a serializer (ObjectWriter) and deserializer (ObjectReader).

arjabbar
  • 6,044
  • 4
  • 30
  • 46
fge
  • 119,121
  • 33
  • 254
  • 329
  • Actually going to bump this to be the answer since the other answer caused unforseen issues when I gave it credit. This is the final answer that I used :) – zmanc Jun 09 '13 at 00:05
16

You can write an object to a json string. So I hope you have your data in an object of a class defined as per your need. Here is how you can convert that object into a json string:

//1. Convert Java object to JSON format
ObjectMapper mapper = new ObjectMapper();

String jsonString = mapper.writeValueAsString(yourObject);

See here for the full jackson-databind javadoc.

fge
  • 119,121
  • 33
  • 254
  • 329
Juned Ahsan
  • 67,789
  • 12
  • 98
  • 136
  • This got me pretty close, but for some reason I have extra quotes around the child objects. I added what I have currently above. – zmanc Jun 07 '13 at 15:08
  • @DirkLachowski Yep :) I put it at the bottom of the description under the EDIT 1 – zmanc Jun 07 '13 at 16:25
  • The extra quotes was because I was using ObjectMapper twice. After removing the inner writeValueAsString I was able to get the result expected. Thank you for your help. – zmanc Jun 07 '13 at 18:17
14

initializing JSON object as singleton instance, and building it:

ObjectNode node = JsonNodeFactory.instance.objectNode(); // initializing
node.put("x", x); // building

PS: to println use node.toString().

Peter Krauss
  • 13,174
  • 24
  • 167
  • 304
11

You can do this without creating POJO and converting it into JSON. I assume your data in the Record object.

        JsonNode rootNode = mapper.createObjectNode();
        ArrayNode childNodes = mapper.createArrayNode();
        for (Record record : records) {
            JsonNode element = mapper.createObjectNode();
            ((ObjectNode) element).put("mime": record.getDirectory());
                  //fill rest of fields which are needed similar to this.
                  //Also here record.getDirectory() method will should return "directory"
                  //according to your json file.
            childNodes.add(element);
        }
        ((ObjectNode) rootNode).put("files", childNodes);
Jeremy
  • 1,894
  • 2
  • 13
  • 22
GPrathap
  • 7,336
  • 7
  • 65
  • 83