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:

3
  • Possible duplicate of Can not deserialize instance of java.util.HashMap out of START_ARRAY token Commented Jan 15, 2018 at 13:29
  • They are only using a list, but I have a Map<String,List<String>>, I can accept its similar, but that solution does not seem to work Commented Jan 15, 2018 at 13:32
  • check onces ObjectMapper mapper = new ObjectMapper(); Map<String,List<Map<String, Object>>> data = mapper.readValue(json, new TypeReference<Map<String,List<Map<String, Object>>>>(){}); Commented Jan 16, 2018 at 7:10

4 Answers 4

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 .

Sign up to request clarification or add additional context in comments.

1 Comment

I think I have a simpler solution. The complex the data-structure, the complex it is for Jackson to map.
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;
    }   
}

2 Comments

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.
@SaurabhJhunjhunwala OK, sorry, I have misread the JSON, so forget the Message class.
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;
    }
}

Comments

-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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.