1

I am trying to convert the below json into a java bean, and need your help

Sort.json

{
  "messages": [
    {
      "GG_RETAIL_BRANCH_SAVING_SELLER": [
        "hello jackson 1",
        "hello jackson 2",
        "hello jackson 3"
      ]
    },
    {
      "GG_RETAIL_CONNECT_SAVINGS_SELLER": [
        "hello jackson 4",
        "hello jackson 5",
        "hello jackson 6"
      ]
    }
  ]
}

My Bean looks like

import java.io.Serializable;
import java.util.List;
import java.util.Map;

public class Sort implements Serializable{

    /**
     * 
     */
    private static final long serialVersionUID = 8122222228160190915L;
    /*  private String name;
    private int age;*/
    private Map<String,List<String>> messages;

    @Override
    public String toString() {
        return "AdamSort [messages=" + messages + "]";
    }

    public Map<String, List<String>> getMessages() {
        return messages;
    }

    public void setMessages(Map<String, List<String>> messages) {
        this.messages = messages;
    }
}

And my test class is

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

import org.codehaus.jackson.JsonGenerationException;
import org.codehaus.jackson.map.JsonMappingException;
import org.codehaus.jackson.map.ObjectMapper;

public class JacksonExample {

    /**
     * @param args
     */
    public static void main(String[] args) {
        ObjectMapper mapper = new ObjectMapper();

        try {           
            Sort sort = mapper.readValue(new File("C:\\Sort.json"), Sort.class);
            System.out.println(sort);

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

The error I see is

org.codehaus.jackson.map.JsonMappingException: Can not deserialize instance of java.util.LinkedHashMap out of START_ARRAY token
 at [Source: C:\Sort.json; line: 2, column: 3] (through reference chain: com.test.Sort["messages"])
    at org.codehaus.jackson.map.JsonMappingException.from(JsonMappingException.java:163)
    at org.codehaus.jackson.map.deser.StdDeserializationContext.mappingException(StdDeserializationContext.java:219)
    at org.codehaus.jackson.map.deser.StdDeserializationContext.mappingException(StdDeserializationContext.java:212)
    at org.codehaus.jackson.map.deser.std.MapDeserializer.deserialize(MapDeserializer.java:246)
    at org.codehaus.jackson.map.deser.std.MapDeserializer.deserialize(MapDeserializer.java:33)
    at org.codehaus.jackson.map.deser.SettableBeanProperty.deserialize(SettableBeanProperty.java:299)
    at org.codehaus.jackson.map.deser.SettableBeanProperty$MethodProperty.deserializeAndSet(SettableBeanProperty.java:414)
    at org.codehaus.jackson.map.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:697)
    at org.codehaus.jackson.map.deser.BeanDeserializer.deserialize(BeanDeserializer.java:580)
    at org.codehaus.jackson.map.ObjectMapper._readMapAndClose(ObjectMapper.java:2732)
    at org.codehaus.jackson.map.ObjectMapper.readValue(ObjectMapper.java:1817)
    at com.test.util.JacksonExample.main(JacksonExample.java:28)

Please suggest:

Saurabh Jhunjhunwala
  • 2,832
  • 3
  • 29
  • 57
  • Possible duplicate of [Can not deserialize instance of java.util.HashMap out of START\_ARRAY token](https://stackoverflow.com/questions/36519974/can-not-deserialize-instance-of-java-util-hashmap-out-of-start-array-token) – PKey Jan 15 '18 at 13:29
  • They are only using a list, but I have a Map>, I can accept its similar, but that solution does not seem to work – Saurabh Jhunjhunwala Jan 15 '18 at 13:32
  • check onces `ObjectMapper mapper = new ObjectMapper();` `Map>> data = mapper.readValue(json, new TypeReference>>>(){});` – SF..MJ Jan 16 '18 at 07:10

4 Answers4

2

While Looking at JSON string , messages are the list of Map .

Replace Map<String,List<String>> with List<Map<String, List<String>>> in Sort.java and give a try .

Bharat DEVre
  • 539
  • 3
  • 13
0

Your JSON translates to something like:

public class Sort {
    private List<Message> messages;
}

public class Message {
    private List<String> GG_RETAIL_BRANCH_SAVING_SELLER;
}

So you can either use such classes, or write a custom deserializer for jackson.

UPDATE:

OK, try with a deserializer:

    ObjectMapper mapper = new ObjectMapper();

    try {
        SimpleModule module = new SimpleModule();
        module.addDeserializer(Sort.class, new SortDeserializer());
        mapper.registerModule(module);

Here's the class SortDeserializer:

public class SortDeserializer extends StdDeserializer<Sort> {
    public SortDeserializer() { 
        this(null); 
    } 

    public SortDeserializer(Class<?> vc) { 
        super(vc); 
    }

    @Override
    public Sort deserialize(JsonParser jp, DeserializationContext dc)
            throws IOException, JsonProcessingException {
        Map<String,List<String>> messages = new HashMap<>();
        JsonNode node = jp.getCodec().readTree(jp);
        ArrayNode msgs = (ArrayNode)node.get("messages");
        for (JsonNode parm: msgs) {
            for (Iterator<String> it = parm.fieldNames(); it.hasNext(); ) {
                String key = it.next();
                ArrayNode values = (ArrayNode)parm.get(key);
                List<String> list = new ArrayList<>();
                for (JsonNode vnode: values) {
                    list.add(vnode.asText());
                }
                messages.put(key, list);
            }
        }
        Sort resp = new Sort();
        resp.setMessages(messages);
        return resp;
    }   
}
Maurice Perry
  • 9,261
  • 2
  • 12
  • 24
  • If you look at my json, I have multiple keys, like "GG_RETAIL_BRANCH_SAVING_SELLER " & "GG_RETAIL_CONNECT_SAVINGS_SELLER".. If I only use " GG_RETAIL_BRANCH_SAVING_SELLER " that means I would also need one for "GG_RETAIL_CONNECT_SAVINGS_SELLER" and all sub-sequent , which is not quite optimal. – Saurabh Jhunjhunwala Jan 15 '18 at 14:01
  • @SaurabhJhunjhunwala OK, sorry, I have misread the JSON, so forget the `Message` class. – Maurice Perry Jan 16 '18 at 06:15
0

The java bean is incorrect in accordance with the json . It should be:

import java.util.ArrayList;
import java.util.Map;

public class Sort {

    ArrayList<Map<String,ArrayList<String>>> messages;

    public ArrayList<Map<String, ArrayList<String>>> getMessages() {
        return messages;
    }

    public void setMessages(ArrayList<Map<String, ArrayList<String>>> messages) {
        this.messages = messages;
    }
}
zealvault
  • 160
  • 10
-1

Modified the JSON a bit

{
  "messages": [
    {
      "group": "GG_RETAIL_BRANCH_SAVING_SELLER",
      "sortCode": [
        "hello jackson 1",
        "hello jackson 2",
        "hello jackson 3"
      ]
    },
    {
      "group": "GG_RETAIL_BRANCH_SAVING_SELLER",
      "sortCode": [
        "hello jackson 4",
        "hello jackson 5",
        "hello jackson 6"
      ]
    }
  ]
}

Added a new class :

import java.util.List;

public class Message {

    private String group;
    private List<String> sortCode;
    public String getGroup() {
        return group;
    }
    public void setGroup(String group) {
        this.group = group;
    }
    public List<String> getSortCode() {
        return sortCode;
    }
    public void setSortCode(List<String> sortCode) {
        this.sortCode = sortCode;
    }
    @Override
    public String toString() {
        return "{group:" + group + ", sortCode:" + sortCode + "}";
    }
}


import java.util.List;

public class Sort {

    private List<Message> messages;

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

    public List<Message> getMessages() {
        return messages;
    }

    public void setMessages(List<Message> messages) {
        this.messages = messages;
    }
}

And it seemed to work.

Saurabh Jhunjhunwala
  • 2,832
  • 3
  • 29
  • 57