Jackson: Cannot deserialize instance of object out of START_ARRAY - java

I'm getting this error when attempting to parse some JSON previously generated with Jackson. I generate the JSON like so
String ret = "";
ret = mapper.writeValueAsString(message.getPayload());
message.setPayload(ret);
Where message.getPayload() is a HashMap, in this instance containing two strings and a List of various objects. This creates the following malformed JSON
{
"user" : "john d example",
"items" : [ {
"val" : 99.5,
"id" : "phone",
"qty" : 1
}, {
"val" : 15.5,
"id" : "wine",
"qty" : 4
} ],
"address" : "123 example street"
}
Which throws an exception when examined thusly
Map<String, Object> ret = new HashMap<String, Object>();
String s = (String)message.getPayload();
ret = mapper.readValue(s, new TypeReference<Map<String, String>>(){});
How should I properly write this Map to JSON?

TypeReference<Map<String, String>> should be TypeReference<Map<String, Object>>. Jackson is attempting to parse the values as Strings rather than Lists because that is what it expects based on the TypeReference you passed in.

Related

Itterate through List of objects recieved in JSON

I have the following JSON data:
[
{
"id": 4,
"siteName": "site1",
"addressLine1": "address1",
"addressLine2": "address2",
"town": "town1",
"postcode": "postcode1",
"contactName": "name1",
"contactNumber": "number1",
"contactEmail": "email1"
},
{
"id": 5,
"siteName": "site2",
"addressLine1": "address1",
"addressLine2": "address2",
"town": "town1",
"postcode": "postcode1",
"contactName": "name1",
"contactNumber": "number1",
"contactEmail": "email1"
},
]
I'm parsing the data but it simply outputs one long string. I'd like to access each element within each object.
UPDATE: I'm outputting the individual elements, but for some reason the 'id' property is considered a double?
Map<String,Object> jsonArr = new JSONParser().parseJSON(new InputStreamReader(new ByteArrayInputStream(r.getResponseData()), "UTF-8"));
java.util.List<Map<String, Object>> content = (java.util.List<Map<String, Object>>)jsonArr.get("root");
for(Map<String, Object> obj : content) {
Log.p((int)obj.get("id"));
Log.p((String)obj.get("siteName"));
Log.p((String)obj.get("addressLine1"));
Log.p((String)obj.get("addressLine2"));
Log.p((String)obj.get("town"));
Log.p((String)obj.get("postcode"));
Log.p((String)obj.get("contactName"));
Log.p((String)obj.get("contactNumber"));
Log.p((String)obj.get("contactEmail"));
}
As you're using Codename One, parseJSON always returns a Map<String, Object>, but behaves differently when the root element is an array. In that case, the returned Map contains an object whose key is "root" which you then can iterate on to obtain the actual objects.
Map<String, Object> data = json.parseJSON(new InputStreamReader(
new ByteArrayInputStream(r.getResponseData()), "UTF-8"));
List<Map<String, Object>> content = (java.util.List<Map<String, Object>>)data.get("root");
for(Map<String, Object> obj : content) {
Log.p(obj.getValue().toString());
}
For further info see the documentation for the parseJSON method.
You are getting an array of objects as it stats with [ and ends with ]. You have to try like this.
JSONArray jsonArr = new JSONParser().parseJSON(new InputStreamReader(new ByteArrayInputStream(r.getResponseData()), "UTF-8"));
for (int i = 0; i < jsonArr.length(); i++) {
String siteName = jsonArr.getJSONObject(i).getString("siteName");
System.out.println(siteName);
}

Getting Json Titled json Array without using pojo , bean, or getter and setter

Hi I've just started to use Json.
My problem is I want json array in following form
[ { "id" : "1", "name" : "India" },{ "id" : "2", "name" : "Pakistan" },{ "id" : "3", "name" : "China" },{ "id" : "4", "name" : "Japan" },{ "id" : "5", "name" : "Russia" } ]
I want id and name title for every value.
Then biggest problem is when I am sending this json to ajax using servlet I am getting nothing (using this code)
List<stateList> sl = new ArrayList<stateList>();//ststeList is getters n setters obj
sl.add(new stateList("1","India"));
Gson js = new Gson();
js.toJson(sl);
response.setContentType("application/json");
response.setCharacterEncoding("UTF-8");
response.getWriter().write(js.toString());
but if I use string object I am getting the value but without titles i.e (id,name)
{"1":"India","2":"Pak","3":"China"}
Code is
Map<String,String> m = new HashMap<String, String>();
m.put("1", "India");
m.put("2", "Pak");
m.put("3", "China");
String js = new Gson().toJson(m);
So finally I want above most json to send to ajax.There is no proble with ajax code its working fine with this type
Use entrySet to get the keys. Just loop through the entries
Code :
JsonParser p = new JsonParser();
JsonObject result = p.parse(file).getAsJsonObject();
Set<Map.Entry<String, JsonElement>> entrySet = result.entrySet();
for(Map.Entry<String, JsonElement> entry : entrySet) {
System.out.println(entry.getKey()); //this gives you the keys.
}
I hope this helps you
Ok after lots of toiling I got the solution which is already hidden in the class I built previously.
class stateList
{
private String id;
private String StateName;
stateList s;
public stateList(String id, String StateName)
{
this.id = id;
this.StateName = StateName;
}
public String toString() {
return "id = " +id+ ", stateName = " +StateName; //solution
}
}
just call the stateList's toString();
//code 2 line 5
js = new Gson().toJson(sl.toString());

deserialize inner JSON object

I have a class POJO
Class Pojo {
String id;
String name;
//getter and setter
}
I have a json like
{
"response" : [
{
"id" : "1a",
"name" : "foo"
},
{
"id" : "1b",
"name" : "bar"
}
]
}
I am using Jackson ObjectMapper for deserialization. How can I get List<Pojo> without creating any other parent class?
If it is not possible, is it possible to get Pojo object which holds just first element of json string i.e. in this case id="1a" and name="foo"?
You'll first need to get the array
String jsonStr = "{\"response\" : [ { \"id\" : \"1a\", \"name\" : \"foo\"},{ \"id\" : \"1b\",\"name\" : \"bar\" } ]}";
ObjectMapper mapper = new ObjectMapper();
JsonNode node = mapper.readTree(jsonStr);
ArrayNode arrayNode = (ArrayNode) node.get("response");
System.out.println(arrayNode);
List<Pojo> pojos = mapper.readValue(arrayNode.toString(), new TypeReference<List<Pojo>>() {});
System.out.println(pojos);
prints (with a toString())
[{"id":"1a","name":"foo"},{"id":"1b","name":"bar"}] // the json array
[id = 1a, name = foo, id = 1b, name = bar] // the list contents
You can use the generic readTree with JsonNode:
ObjectMapper mapper = new ObjectMapper();
JsonNode root = mapper.readTree(json);
JsonNode response = root.get("response");
List<Pojo> list = mapper.readValue(response, new TypeReference<List<Pojo>>() {});
Pojo pojo;
json = {
"response" : [
{
"id" : "1a",
"name" : "foo"
},
{
"id" : "1b",
"name" : "bar"
}
]
}
ObjectMapper mapper = new ObjectMapper();
JsonNode root = objectMapper.readTree(json);
pojo = objectMapper.readValue(root.path("response").toString(),new TypeReference<List<Pojo>>() {});
First, you have to create a JSON node with your JSON file. Now you have a JSON node. You can go to the desired location using path function of JSON node like what I did
root.path("response")
However this will return a JSON tree. To make a String, I have used the toString method.
Now, you have a String like below
"
[
{
"id" : "1a",
"name" : "foo"
},
{
"id" : "1b",
"name" : "bar"
}
] "
You can map this String with JSON array as following
String desiredString = root.path("response").toString();
pojos = objectMapper.readValue(desiredString ,new TypeReference<List<Pojo>>() {});

De-serialize List of POJOs rather than a single one at a time

So I came across this tutorial for serializing a POJO to json and then de-serialize the json file back to the POJO. http://www.mkyong.com/java/how-to-convert-java-object-to-from-json-jackson/
he uses these helpful methods which worked for me but only for a single POJO in the file:
//1. Convert Java object to JSON format
ObjectMapper mapper = new ObjectMapper();
mapper.writeValue(new File("c:\\user.json"), user);
//2. Convert JSON to Java object
ObjectMapper mapper = new ObjectMapper();
User user = mapper.readValue(new File("c:\\user.json"), User.class);
How can I de-serialize a list of POJOs? My serialized file looks like the below:
[ {
"name" : {
"first" : "Wonder",
"last" : "Woman"
},
"ssn" : "123-456-7890",
"gender" : "FEMALE",
"verified" : false
}, {
"name" : {
"first" : "Bat",
"last" : "Man"
},
"ssn" : "321-456-0987",
"gender" : "FEMALE",
"verified" : true
}, {
"name" : {
"first" : "Super",
"last" : "Man"
},
"ssn" : "321-654-1111",
"gender" : "FEMALE",
"verified" : true
} ]
One option (probably the easiest) is to define a class that contains a list of Users:
public class Users
{
public User[] users;
}
Then performing
ObjectMapper mapper = new ObjectMapper();
Users users = mapper.readValue(new File("c:\\user.json"), Users.class);
Another option would be to iterate over the json array, and capture each element of the array of users, then use ObjectMapper.readValue(String content, Class<T> valueType), like so:
ObjectMapper mapper = new ObjectMapper();
InputStream stream = new FileInputStream("c:\\user.json");
User user;
JsonNode json = mapper.readTree(stream);
//NOTE: calling json.isArray() should return true.
for (JsonNode userJson : json)
{
user = mapper.readValue(userJson, User.class);
// use the constructed user...
}
Note: I haven't tested the above, so let me know if it works or not.
Hmmh? Have you tried:
User[] users = mapper.readValue(new File("c:\\user.json"), User[].class);
In your top level class, you have an array of people. something like this
class People {
public List<Person> persons;
}

Gson - how to parse dynamic JSON string with nested JSON?

I have JSON string with dynamic elements, till now I parse it into Map:
Map map = new Gson().fromJson(jsonString,
new TypeToken<HashMap<String, String>>() {}.getType());
Now I need to solve thsi situation - one of these dynamic variables could be another JSON string.
Do you have some advice ho to solve it? Thanks in advance.
EDIT: JSON string example added (formatted):
{
"key1": "val1",
"key2": "val2",
"key3": {
"subkey1": [
"subvalue1",
"subvalue1"
],
"subkey‌​2": [
"subvalue2"
]
},
"key4": "val3"
}
What you call another JSON string is just a json object. Change the Map value type to Object from String: TypeToken>
String jsonString = "{\"key1\":\"val1\",\"key2\":\"val2\",\"key3\": {\"subkey1\":\"subvalue1\",\"subkey2\":\"subvalue2\"},\"key4\":\"val3\"}";
Map<String, Object> map = new Gson().fromJson(jsonString, new TypeToken<Map<String, Object>>() {
}.getType());
The above example works with GSON 2.2.2. And sysout(map) produces
{key1=val1, key2=val2, key3={subkey1=subvalue1, subkey2=subvalue2}, key4=val3}
As a small improvement I'd suggest that you explicitly specify map type parameters, and use Map instead of HashMap for the TypeToken.

Categories

Resources