Trouble with converting Json in Java - java

I'm trying to read in a somewhat complex json string and I'm having problems with nested items and how to retrieve them.
My java code looks like the following
String longJson = "{'Patient': {'Name': {'Given': 'FirstName','Family': 'LastName'},'Gender': 'Female','DOB': '1980-07-04T00:00:00.0000000','AgeInYears': 36,'MartialStatus': 'Single', 'Race': 'Race','Ethnicity': 'Ethnicity','Class': 'Inpatient','Address': {'StreetAddress': 'StreetAddress','City': 'City','State': 'State','ZipCode': 'ZipCode', 'Country': 'Country'}}}";
Gson gson = new Gson();
PrescriptionReq sample = null;
sample = gson.fromJson(longJson, PrescriptionReq.class);
String firstName = sample.getPatient().getName().getGiven();
//String firstName = sample.patient.name.getGiven();
System.out.println("Testing: "+ firstName);
When I run either approach I get a null point exception
Here is the Json in a more readable view
{
"Patient": {
"Name": {
"Given": "FirstName",
"Family": "LastName"
},
"Gender": "Female",
"DOB": "1980-07-04T00:00:00.0000000",
"AgeInYears": 36,
"MartialStatus": "Single",
"Race": "Race",
"Ethnicity": "Ethnicity",
"Class": "Inpatient",
"Address": {
"StreetAddress": "StreetAddress",
"City": "City",
"State": "State",
"ZipCode": "ZipCode",
"Country": "Country"
}
}
}
Here are my classes:
public class PrescriptionReq {
private Patient patient;
public Patient getPatient(){
return patient;
}
public class Patient {
Name name;
Address address;
public Name getName(){
return name;
}
//Other variables
}
public class Name {
private String Given;
private String Family;
public String getGiven() {
return Given;
}
public String getFamily() {
return Family;
}
}
}
I'm not sure if I am storing the json wrong or retrieving it wrong. Any help is much appreciated!

Your field names aren't matching your JSON, and hence you're getting back a PrescriptionReq object with a null patient field.
Off the top of my head, I can think of a couple ways to fix this:
Change the name of the variable to match the JSON field
public class PrescriptionReq {
// have to rename Patient class to avoid name collision
private PRPatient Patient;
...
Add a #SerializedName annotation to tell Gson what the "real" field name is
public class PrescriptionReq {
#SerializedName("Patient")
private Patient patient;
...
Of course you'll also need to do this for the name field in the Patient class, as well as anything in Address you're having problems with.

Related

Using JAVA Reflection how to create custom JSON object mapping

I have a json Object in the below format, I need to assign the values from Json to java object, But the label name in JSON and class is different.
{
FirstName: "Sample",
LastName: "LName",
Address: [
{
type: "Temp",
street: "test stree",
},
{
type: "Perm",
street: "test stree",
}
]
}
Class Parent{
private String Name1;
private String Nama2;
private List<Address> address;}
Class Address{
Private String type;
private String data;
}
I wanted to implement the custom object mapper using Java reflection. the mapping is as below, But I am not getting idea to implement this, Any valuable suggestion or usage of external api would help me to achieve the scenario.
Json Object name Jave Class object Name
FirstName ---------- Name1
LastName ---------- Name2
Address.type ------- Address class type
Address.street ----- Address class data
You would need reflexion if you receive json data with same structure with properties names changing, for example :
{
FirstName1: "Sample",
LastName1: "LName",
Address1: [
{
type1: "Temp",
street1: "test stree",
},
{
type1: "Perm",
street1: "test stree",
}
]
}
{
FirstName2: "Sample",
LastName2: "LName",
Address1: [
{
type2: "Temp",
street2: "test stree",
},
{
type2: "Perm",
street2: "test stree",
}
]
}
In your case, it rather look like a property name matching issue, you can annotate your java pojo like that :
public class Parent{
#JsonProperty("FirstName")
private String Name1;
#JsonProperty("LastName")
private String Nama2;
private List<Address> address;
}
public class Address{
private String type;
#JsonPRoperty("street")
private String data;
}
Finally you can deserialize your json object using standard Jackson library :
new ObjectMapper().readValue(json, Parent.class);

How to deserialize complex JSON to java object

I need to deserialize JSON to java class.
I have JSON like the following:
{
"data": {
"text": "John"
},
"fields":[
{
"id": "testId",
"name": "fieldName",
"options": {
"color": "#000000",
"required": true
}
},
{
"id": "testId",
"name": "fieldName1",
"options": {
"color": "#000000",
"required": false
}
}
]
}
and I need to deserialize this JSON (only "fields" section) to java class like the following:
public class Field {
public final String id;
public final String name;
public final String color;
public final boolean required;
}
and I need to get something like the following:
// The key is the id from field object (it can be the same in the multiple objects.)
Map<String, List<Field>> fields = objectMapper.readValue(json, Map<String, List<Field>>);
How can I do it using Jackson?
As long as jackson doesn't support #JsonWrapped, you have to use the following work around.
First you need to create a custom class which contains the fields:
public class Fields {
public List<Field> fields;
}
Depending on your ObjectMapper configuration you have to add #JsonIgnoreProperties(ignoreUnknown = true) to the Fields class, to ignore any other properties.
Next is that you have to define the nested Options class which is solely used temporarily:
public class Options {
public String color;
public boolean required;
}
And at last add this constructor to your Field class:
#JsonCreator
public Field(#JsonProperty("id") String id, #JsonProperty("name") String name, #JsonProperty("options") Options options){
this.id = id;
this.name = name;
this.color = options.color;
this.required = options.required;
}
The #JsonCreator annotation indicates to jackson that this constructor needs to be used for the deserialization. Also the #JsonProperty annotations are required as arguments to constructors and methods are not preserved in the bytecode
Then you can deserialize your json just like this:
List<Field> fields = objectMapper.readValue(json, Fields.class).fields;

how to deserialize with the GSON library a Json with nested objects and show them in a TextView

I want to deserialize a Json with nested objects using the Gson library. I'm trying to get the data from the api of clash royale.
I've got the first Gson data printed on a TextView, but I'm finding it impossible to do the same with nested objects. Let me give you an example:
[
{
"tag": "Whatever",
"name": "Whatever",
"trophies": 5262,
"rank": 99,
"arena": {
"name": "Whatever",
"arena": "Whatever",
"arenaID": 14,
"trophyLimit": 4700
},
"clan": {
"tag": "Whatever",
"name": "Whatever",
"role": "Whatever",
"donations": 23,
"donationsReceived": 44,
"donationsDelta": -20,
"badge": {
"name": "Whatever",
"category": "Whatever",
"id": 16003333,
"image": "https://royaleapi.github.io/cr-api-assets/badges/Whatever.png"
}
I can show the tag, the name and the trophies, but I am unable to access the data inside the clan object.
to print this data in TextView I simply declare a class where I host them, for example like this:
public class ClashData implements Serializable {
public String tag;
public String name;
public int trophies;
}
Then I connect it to TextView by placing a TextView in the corresponding layout and putting the following lines of code:
public ClashData data;
Afterwards, inside the onCreate
data =(ClashData)getIntent().getSerializableExtra("data");
And finally
nameUser.setText("Name ", data.name);
tagUser.setText("Tag " + data.tag);
trophiesUser.setText("Trophies " + data.trophies);
I've tried everything to extract data from nested objects, but I don't know how to do it, can you help me?
You can modify Clan POJO as shown below:
public class Clan {
#SerializedName("tag")
#Expose
public String tag;
#SerializedName("name")
#Expose
public String name;
#SerializedName("role")
#Expose
public int role;
#SerializedName("donation")
#Expose
public int donations;
/*Create getter and setter methods for all the instance variables.*/
}
Now add the above class to your ClashData as shown below:
public class ClashData {
#SerializedName("tag")
#Expose
public String tag;
#SerializedName("name")
#Expose
public String name;
#SerializedName("trophies")
#Expose
public int trophies;
#SerializedName("clan")
#Expose
public Clan clanData; // add this line to your code
/*Create getter and setter methods for all the instance variables.*/
}
Now you can use Gson library as shown below:
Gson gson = new Gson();
ClashData data = gson.fromJson(jsonData,ClashData.class);
Clan clanData = data.getClanData();
Have referred to this while answering the question.

How to use Jackson ObjectMapper to parse json response to java objects

Here is my Json response
"postedevent": [
{
"status": "true",
"event_id": "800",
"num_of_image_event": "0",
"title": "Testy",
"photo": "http://54.200.110.49/checkplanner/img/upload/21310059819profile_image_1409303464798.png",
"event_date": "2014-08-29",
"fullDate": "Friday - August 29, 2014",
"event_from": "12:00AM",
"event_to": "12:15AM",
"city": "Ahm",
"state": "CA",
"member_id": "471",
"username": "Krishna Mohan",
"pencil": "yes",
"attend": "yes",
"company": "Development"
}
]
this is java class to get java objs from json response
public class PostedEvent {
String status;
int event_id;
int num_of_image_event;
String title;
String photo;
String event_date;
String fullDate;
String event_from;
String event_to;
String city;
String state;
String member_id;
String username;
String pencil;
String attend;
String company;
}
public class PostedEvnetsList
{
ArrayList<PostedEvent> postedevent;
}
And I am parsing in this way
InputStream is = WebResponse.getResponse(url);
ObjectMapper mapper = new ObjectMapper();
PostedEvnetsList mList = null;
mList = mapper.readValue(is,PostedEvnetsList.class);
eventList = mList.postedevent;
I am getting following parse exception
jackson.map.exc.UnrecognizedPropertyException: Unrecognized field "status" (Class com.example.jsonproforexam.PostedEvent), not marked as ignorable
I have declared same fields as in json response then why I am geting this exception
Please help
Your fields of PostedEvent and the PostedEvent field of PostedEventsList are not accessible.
You must set them as public (not recommended) or provide public getters and setters for them POJO-style.
Then Jackson will be able to de-serialize and the error will go away.
You can use the JsonProperty annotation to specify the json key
Ex:
public class PostedEvent {
#JsonProperty("status")
String status;
#JsonProperty("event_id")
String eventId;
....
....
If you have missed some fields from json in your entity class, you can use #JsonIgnoreProperties annotation to ignore the unknown fields.
#JsonIgnoreProperties(ignoreUnknown = true)
public class PostedEvent {
...

How to represent sub-documents in JSON array as Java Collection using Jackson?

I would appreciate any help to know the best way to deserialize the following JSON response which we receive from Salesforce into a Java object using Jackson Annotations.
"records": [
{
"attributes": {
"type": "Lead",
"url": "/services/data/v30.0/sobjects/Lead/00Qi000000Jr44XEAR"
},
"Id": "00Qi000000Jr44XEAR",
"Name": "Kristen Akin",
"Address": {
"city": null,
"country": "USA",
"state": "CA",
"stateCode": null,
"street": null
},
"Phone": "(434) 369-3100",
},
{
"attributes": {
"type": "Lead",
"url": "/services/data/v30.0/sobjects/Lead/00Qi000000Jugv2EAB"
},
"Id": "00Qi000000Jugv2EAB",
"Name": "Sarah Jones",
"Address": {
"city": null,
"country": null,
"state": "CA",
"stateCode": null,
"street": null
},
"Phone": "(408) 338-6066",
}
]}
The above JSON response is an array which contains 2 elements. I would like to represent this JSON structure as a Java Collection using Jackson, something like:
#JsonProperty("records")
ArrayList<LinkedHashMap<?, ?>> recordList
The above object representation deserializes the JSON response and represent as a Key-Value pair in HashMap but issue is representing "attributes" and "Address" subdocuments. In the above HashMap their value is being represented as the respective JSON subdocument whereas I would prefer to have Attributes subdocument gets mapped to an Attribute object and similarly Address subdocument mapped to an Address object in the HashMap, something like:
Key Value
attributes <Attributes> object
Id 00Qi000000Jr44XEAR
.....
Address <Address> object
Phone (434) 369-3100
After doing some Google search, I figured I might have to use #JsonTypeInfo and #JsonSubTypes attributes as mentioned in this link.
However, I could not figure how to use these annotations in this specific scenario. Appreciate any help on this.
If the structure of your JSON input is completely dynamic, you can read it as JsonNode or even as Map. Refer to this link for more info.
If you want to map your JSON to java classes but you don't know all the attributes in compile type, you can leverage the #JsonAnyGetter/#JsonAnySetter annotations. Here is an example based on your JSON that stores the unknown attributes for the Address class in the internal map.
public class JacksonMapping {
public static final String JSON = "...";
public static class Attributes {
public String type;
public URI url;
}
public static class Address {
public String city;
public String country;
public String state;
public Integer stateCode;
public String street;
private final Map<String, Object> otherAttributes = new HashMap<>();
#JsonAnySetter
public void setProperty(String name, Object value) {
otherAttributes.put(name, value);
}
#JsonAnyGetter
public Map<String, Object> getOtherAttributes() {
return otherAttributes;
}
}
public static class Record {
#JsonProperty("Id")
public String id;
#JsonProperty("Name")
public String name;
public Attributes attributes;
#JsonProperty("Address")
public Address address;
#JsonProperty("Phone")
public String phone;
}
public static class RecordList {
public List<Record> records;
}
public static void main(String[] args) throws IOException {
ObjectMapper mapper = new ObjectMapper();
RecordList recordList = mapper.readValue(JSON, RecordList.class);
System.out.println(mapper.writerWithDefaultPrettyPrinter()
.writeValueAsString(recordList));
}
}
I can also try to generate java objects from your JSON with a help from a tool. For example this one: http://www.jsonschema2pojo.org

Categories

Resources