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:
4 Answers 4
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 .
1 Comment
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
Message class.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
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.
ObjectMapper mapper = new ObjectMapper();Map<String,List<Map<String, Object>>> data = mapper.readValue(json, new TypeReference<Map<String,List<Map<String, Object>>>>(){});