Unable to parse Json with Map,ObjectMapper - java

Now a days I'm having experience of Json parsing .Not have much practice with collection.I have a Json String
{
"time":1352113682,
"api_version":"1",
"firstname":"abc",
"lastname":"xyz",
"company":"Cool Apps",
"email":"abc#apps.com.au"
}
I made class
public class AuthenticateUser implements Serializable{
// Response when Successfully Login
public String time;
public String api_version;
public String firstname;
public String lastname;
public String company;
public String email;
}
And trying to parse it like this
Map<String, AuthenticateUser> map=null;
ObjectMapper mapper=new ObjectMapper();
try{
map=mapper.readValue(result,new TypeReference<Map<String, AuthenticateUser>>(){});
Set<String> keys=map.keySet();
for (String key : keys) {
System.out.println(map.get(key).time);
System.out.println(map.get(key).api_version);
System.out.println(map.get(key).firstname);
System.out.println(map.get(key).lastname);
System.out.println(map.get(key).company);
System.out.println(map.get(key).email);
}
}catch (Exception e) {
e.printStackTrace();
}
But gettin this error
com.fasterxml.jackson.databind.JsonMappingException: Can not instantiate value of type [simple type, class AuthenticateUser] from JSON integral number; no single-int-arg constructor/factory method
at com.fasterxml.jackson.databind.deser.std.StdValueInstantiator.createFromInt(StdValueInstantiator.java:316)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserializeFromNumber(BeanDeserializer.java:427)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:119)
at com.fasterxml.jackson.databind.deser.std.MapDeserializer._readAndBindStringMap(MapDeserializer.java:429)
at com.fasterxml.jackson.databind.deser.std.MapDeserializer.deserialize(MapDeserializer.java:310)
at com.fasterxml.jackson.databind.deser.std.MapDeserializer.deserialize(MapDeserializer.java:26)
at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:2577)
at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:1817)
at Driver$1.run(Driver.java:140)

The example you gave at the beginning is for a single AuthenticateUser object. Is that all that is being passed to this program as input? This absolutely will not parse properly.
A single AuthenticateUser is not a Map of type (String, AuthenticateUser)
I think maybe you're confused, why are you making a map? If you intended to parse only a single object, all you need is:
AuthenticateUser user =mapper.readValue(result, AuthenticateUser.class);
System.out.println(user.time);
How does that look? Are you passing a map in JSON?

Related

How would I use Jackson to flatten JSON with nested array?

I am using JackSon to parse the following JSON:
{
"AwardID": "1111111",
"AwardTitle": "Test Title",
"Effort":
"[
{
"PersonFirstName": "Jon",
"PersonLastName": "Snow"
}
]"
}
I would like to flatten this to be used in the following class:
public class Award {
private String awardId;
private String awardTitle;
private String personFirstName;
private String personLastName;
}
I have tried the following and have gotten the first two values, but I haven't been able to get the values from Effort trying to use JsonUnwrapped. I noted that it doesn't work with arrays, but I am trying the objectMapper.configure(DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS, true) configuration in the main method used to get the values.
public class Award {
#JsonProperty("AwardID")
private String awardId;
#JsonProperty("AwardTitle")
private String awardTitle;
#JsonUnwrapped
private Effort effort;
}
public class Effort {
private String personFirstName;
private String personLastName;
}
Note that I only expect one value in the Effort array from the API response at this time.
What is recommended to try next? Thank you!
The easiest way is having a List<Effort> if you have a JSON Array.
If there is always 1 item for Effort, the returning JSON should not have Effort as a JSON Array and instead should be a JSON Object.
But if you can only handle it codewise, you can have something like this (Note that there should always contain one item in Effort, otherwise it will throw Exception):
public class Award {
#JsonProperty("AwardID")
private String awardId;
#JsonProperty("AwardTitle")
private String awardTitle;
#JsonProperty("Effort")
private Effort effort;
}
public class Effort {
#JsonProperty("PersonFirstName")
private String personFirstName;
#JsonProperty("PersonLastName")
private String personLastName;
}
And your ObjectMapper needs to be enabled with DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS as well:
ObjectMapper mapper = new ObjectMapper();
mapper.enable(DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS);
Award award = mapper.readValue(rawJson, Award.class); // rawJson is your JSON String
And it should have the following output:
Award(awardId=1111111, awardTitle=Test Title, effort=Effort(personFirstName=Jon, personLastName=Snow))
Note that the annotation #JsonUnwrapped can only apply on JSON Object, not JSON Array:
Value is serialized as JSON Object (can not unwrap JSON arrays using this mechanism)

Error : Could not write JSON: Class java.util.ArrayList not subtype of map - Serialiation to JSON in Spring Application

I'm getting an error while sending List<List<LinkedHashMap<String, MyDTO>>> , it throws JSON parse exception. I've seen the same question in StackOverflow but there is no proper answer or maybe bcz the question wasn't detailed enough.
Error : Could not write JSON: Class java.util.ArrayList not subtype of [map type; class java.util.LinkedHashMap, [simple type, class java.lang.String] -> [simple type, class com.MyDTO]];
Basically, what I want is to convert LinkedHashMap to JSON, but the order is getting changed (tried with both HashMap & LinkedHashMap - JSON treats both as Map and so order issue still persists). To fix it what I'm trying now is to store each map entry into a separate List (List<LinkedHashMap<String, MyDTO>) and then storing these lists inside a single list i.e. List<List<LinkedHashMap<String, MyDTO>>.
Screenshot -
Screenshot of java data which is not converting to JSON
Here, the key is a String object & value is a DTO file.
From the java side, everything is OK but facing issue in serialization using Jackson in the spring application
(response converted by #RestController) it throws the error.
I'm using a RESTful web service using Spring Framework where everything is fine except this part.
Pls, tell me how do I fix it and don't mention any links to some other questions that are unanswered or to learn the whole topic as I've searched everywhere for similar questions and still confused?
You should be using TypeReference to resolve this issue like this:
ObjectMapper m = new ObjectMapper();
List<List<LinkedHashMap<String, MyDTO>>> obj = new ArrayList<>();
LinkedHashMap<String, MyDTO> map = new LinkedHashMap<String, MyDTO>();
MyDTO myd = new MyDTO("abc");
map.put("a1", myd);
map.put("a2", new MyDTO("def"));
List<LinkedHashMap<String, MyDTO>> list = Arrays.asList(map);
obj.add(list);
// serialization succeeded
String json = m.writerWithDefaultPrettyPrinter().writeValueAsString(obj);
System.out.println(json);
// deserialization succeeded
ArrayList<ArrayList<LinkedHashMap<String, MyDTO>>> o = m.readValue(json, new TypeReference<ArrayList<ArrayList<LinkedHashMap<String, MyDTO>>>>(){});
System.out.println(o);
// output
[ [ {
"a1" : {
"name" : "abc"
},
"a2" : {
"name" : "def"
}
} ] ]
[[{a1=MyDTO [name=abc], a2=MyDTO [name=def]}]]
Sample DTO class:
public class MyDTO {
private String name;
public MyDTO() {}
public MyDTO(String name) {
super();
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
#Override
public String toString() {
return "MyDTO [name=" + name + "]";
}
}

gson JSON to Java -- json property has . or - in it

What steps will reproduce the problem?
1.I have a json reponse as
String Content =
"{
"region":{
"state.code":"TX",
"country-code":"USA"
}
}";
2.I want to convert this Json Object into Java Object.I have this Java class to convert
public class Region{
private String stateCode;
private String countryCode;
public String getStateCode ()
{
return stateCode;
}
public void setStateCode (String stateCode)
{
this.stateCode = stateCode;
}
public String getCountryCode ()
{
return countryCode;
}
public void setCountryCode (String countryCode)
{
this.countryCode = countryCode;
}
}
3.My problem is Java doesnt allow . or - in variable name.Which doesnt allow json string to map to Region java class object giving null .
gson.fromJson(Content, Region.class);
What is the expected output? What do you see instead?
Can anybody please help me in this?
I have tried #SerializedName annotations but it is not working.
What version of the product are you using? On what operating system?
Please provide any additional information below.
You're trying to map this JSON
{
"region":{
"state.code":"TX",
"country-code":"USA"
}
}
to an instance of type Region. That JSON is a JSON Object which contains a pair with name region and a value which is a JSON Object. That JSON Object has two pairs, one with name state.code and JSON String value TX and one with name country-code and JSON String value USA.
You can't map that to a Region object. You have to bypass the root's pair named region.
Create a encapsulating type
class RegionContainer {
private Region region;
// the rest
}
and map that
gson.fromJson(Content, RegionContainer.class);
#SerializedName will work for your fields.
#SerializedName("state.code")
private String stateCode;

JSON string serialization ( to camel case ) and deserialization (from snake case )using Jackson

I am trying to deserialize a json string to POJO and then serialize it back to json string using Jackson, but in this process I want resultant json string to have changed key values.
e.g. input json string:
{"some_key":"value"}
here is what my POJO looks like
public class Sample {
#JsonProperty("some_key")
private String someKey;
public String getSomeKey(){
return someKey ;
};
}
When I serialize it again I want json string to be something like this
{"someKey":"value"} .
Is there any way I can achieve this?
I was able to do deserialization by renaming setter functions according to what is the input json string .
class Test{
private String someKey;
// for deserializing from field "some_key"
public void setSome_key( String someKey) {
this.someKey = someKey;
}
public String getSomeKey(){
return someKey;
}
}
You should be able to pull this off by defining a creator for deserialization and then let Jackson do its default behavior for serialization.
public class Sample {
private final String someKey;
#JsonCreator
public Sample(#JsonProperty("some_key") String someKey) {
this.someKey = someKey;
}
// Should serialize as "someKey" by default
public String getSomeKey(){
return someKey;
}
}
You may need to disable MapperFeature.AUTO_DETECT_CREATORS on your ObjectMapper for this to work.

"Dotting" in JSON using Gson on Android

I'm trying to parse a JSON feed using Gson in Android. I know the JSON is valid. I suspect that it is because the format is like this:
"Info":[
{
"Id":"",
"Name":"",
"Description":"",
"Date":""
}
In order to parse this I need to "dot" in. Ex: Info.Name
How can I do this in a serialized DTO?
#SerializedName("Name")
public String name;
#SerializedName("Description")
public String desc;
#SerializedName("Date")
public String date;
I tried to put "Info." in front of each serializedName but that didn't work either. I also know my JSON parsing method works properly, because it's used somewhere else with a different DTO. But in that parsing, I don't have to "dotting" issue.
Can anyone help?
EDIT: I have tried everything you guys posted, and nothing works. The error says:
The JsonDeserializer failed to deserialize json object {"Info":[{".......
SECOND EDIT:
I was able to get rid of the error, but now it returns null. Haha, getting pretty damn frustrated right about now!
I am assuming that the actual JSON you are intaking is valid because the example you provided is not. In your JSON example, you have "Info":[ but there is no outer object containing the "Info" property, which is a must. The valid JSON would be:
{
"Info": [
{
"Id":"",
"Name":"",
"Description":"",
"Date":"",
}
]
}
This is a JSON object that has a property "Info" which has a value that is a list of objects. This list of objects contains one object that has the properties "Id", "Name", "Description", and "Date", all of which have empty-string values.
Here is a quick tutorial on how to use GSON to parse a JSON feed such as the above JSON:
You will need a class to represent the items in the list:
public class InfoItem {
public String Id;
public String Name;
public String Description;
public String Date;
public InfoItem() {}
}
And one to represent the list of Items:
public class InfoItemList extends LinkedList<InfoItem> {
public InfoItemList() { super() };
}
This added complexity is because GSON cannot otherwise get the type of a generic collection from the class data.
And one to represent the overall JSON message:
public class InfoMessage {
public InfoItemList Info;
public InfoMessage() {};
}
And then just:
gson.fromJson(jsonString, InfoMessage.getClass());
If just de-serializing a collection:
Type listType = new TypeToken<List<InfoItem>>() {}.getType();
gson.fromJson(jsonString2, listType);
The Info object is a list because of the []. You have to use the following code to deserialze it:
EDIT:
public class Info {
// as in your question
public String name;
...
}
public class Data {
#SerializedName("Info")
public List<Info> info;
}
Then just use the data class to deserialize your json.

Categories