Questions
JSON serialization of Map<String, String> property (excerpt):
{
"attributes": {
"entry": [
{
"key": "operating system",
"value": "GNU/Linux"
},
{
"key": "allergies",
"value": "weed"
}
]
}
}
POJO for deserialization:
class Contact implements Comparable<Contact>, Serializable {
@JsonProperty("attributes")
private Map<String, String> attributes;
...
}
Causes this exception:
Thread-4889 An exception occurred during request network execution :Could not read JSON: Can not deserialize instance of java.lang.String out of START_ARRAY token
at [Source: libcore.net.http.FixedLengthInputStream@43822760; line: 1, column: 17] (through reference chain: com.example.model.Contact["attributes"]); nested exception is com.fasterxml.jackson.databind.JsonMappingException: Can not deserialize instance of java.lang.String out of START_ARRAY token
at [Source: libcore.net.http.FixedLengthInputStream@43822760; line: 1, column: 17] (through reference chain: com.example.model.Contact["attributes"])
org.springframework.http.converter.HttpMessageNotReadableException: Could not read JSON: Can not deserialize instance of java.lang.String out of START_ARRAY token
at [Source: libcore.net.http.FixedLengthInputStream@43822760; line: 1, column: 17] (through reference chain: com.example.model.Contact["attributes"]); nested exception is com.fasterxml.jackson.databind.JsonMappingException: Can not deserialize instance of java.lang.String out of START_ARRAY token
at [Source: libcore.net.http.FixedLengthInputStream@43822760; line: 1, column: 17] (through reference chain: com.example.model.Contact["attributes"])
at org.springframework.http.converter.json.MappingJackson2HttpMessageConverter.readInternal(MappingJackson2HttpMessageConverter.java:126)
at org.springframework.http.converter.AbstractHttpMessageConverter.read(AbstractHttpMessageConverter.java:147)
at org.springframework.web.client.HttpMessageConverterExtractor.extractData(HttpMessageConverterExtractor.java:76)
at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:484)
at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:439)
at org.springframework.web.client.RestTemplate.getForObject(RestTemplate.java:237)
at com.example.providers.Query$1.loadDataFromNetwork(Query.java:99)
at com.octo.android.robospice.request.CachedSpiceRequest.loadDataFromNetwork(CachedSpiceRequest.java:45)
at com.octo.android.robospice.request.RequestRunner.processRequest(RequestRunner.java:130)
at com.octo.android.robospice.request.RequestRunner$1.run(RequestRunner.java:197)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:390)
at java.util.concurrent.FutureTask.run(FutureTask.java:234)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1080)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:573)
at java.lang.Thread.run(Thread.java:841)
Caused by: com.fasterxml.jackson.databind.JsonMappingException: Can not deserialize instance of java.lang.String out of START_ARRAY token
at [Source: libcore.net.http.FixedLengthInputStream@43822760; line: 1, column: 17] (through reference chain: com.example.model.Contact["attributes"])
at com.fasterxml.jackson.databind.DeserializationContext.mappingException(DeserializationContext.java:691)
at com.fasterxml.jackson.databind.deser.std.StringDeserializer.deserialize(StringDeserializer.java:46)
at com.fasterxml.jackson.databind.deser.std.StringDeserializer.deserialize(StringDeserializer.java:11)
at com.fasterxml.jackson.databind.deser.std.MapDeserializer._readAndBindStringMap(MapDeserializer.java:430)
at com.fasterxml.jackson.databind.deser.std.MapDeserializer.deserialize(MapDeserializer.java:312)
at com.fasterxml.jackson.databind.deser.std.MapDeserializer.deserialize(MapDeserializer.java:26)
at com.fasterxml.jackson.databind.deser.SettableBeanProperty.deserialize(SettableBeanProperty.java:525)
at com.fasterxml.jackson.databind.deser.impl.FieldProperty.deserializeAndSet(FieldProperty.java:106)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.vanillaDeserialize(BeanDeserializer.java:242)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:118)
at com.fasterxml.jackson.databind.deser.std.CollectionDeserializer.deserialize(CollectionDeserializer.java:227)
at com.fasterxml.jackson.databind.deser.std.CollectionDeserializer.des
The attributes Object when inspected in debugger after deserialization:
Further inspection after changing to:
@JsonProperty("attributes")
private Map<String, List<Map<String, String>>> attributes;
Dependencies:
Hashmap: A HashMap stores items in key/value pairs, and we can access them by an index of another type (such as a string). Now to serialize anything, you have to implement the java. io. Serializable interface and HashMap also implements the Serializable interface.
Just like Java objects, we can serialize and deserialize Java Map by using Jackson. We can easily serialize and deserialize Map<Object, Object>, Map<Object, String>, and Map<String, String> to or from JSON-formatted strings by using Jackson.
Mapper instances are fully thread-safe provided that ALL configuration of the instance occurs before ANY read or write calls.
Serialization converts a Java object into a stream of bytes, which can be persisted or shared as needed. Java Maps are collections that map a key Object to a value Object, and are often the least intuitive objects to serialize.
If we will convert Map
to json:
Map<String, String> map = new HashMap<String, String>();
map.put("operating system", "GNU/Linux");
map.put("allergies", "weed");
The output will be:
{"operating system":"GNU/Linux","allergies":"weed"}
As we can see there is no key/value
.
WrapperObject
@JsonIgnoreProperties(ignoreUnknown = true)
public class WrapperObject { // we can give any name to class, its only external {}
private Attributes attributes;
public WrapperObject() {}
public Attributes getAttributes() {
return attributes;
}
}
Attributes
@JsonIgnoreProperties(ignoreUnknown = true)
public class Attributes {
public Attributes() {}
private ArrayList<Entry> entry;
public ArrayList<Entry> getEntry() {
return entry;
}
}
Entry
@JsonIgnoreProperties(ignoreUnknown = true)
public class Entry {
private String key;
private String value;
public Entry() {}
public String getKey() {
return key;
}
public String getValue() {
return value;
}
}
Launcher
public static void main(String[] args) throws JsonParseException, JsonMappingException, IOException {
String str = "{" +
" \"attributes\": {" +
" \"entry\": [" +
" {" +
" \"key\": \"operating system\"," +
" \"value\": \"GNU/Linux\"" +
" }," +
" {" +
" \"key\": \"allergies\"," +
" \"value\": \"weed\"" +
" }" +
" ]" +
" }" +
"}";
ObjectMapper mapper = new ObjectMapper();
WrapperObject mj = mapper.readValue(str, WrapperObject.class);
if(mj == null){
System.err.println("null");
}
// dummy check
System.out.println(mj.getAttributes().getEntry().get(0).getKey());
}
Output:
operating system
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With