I have created a class Game that looks like this:
public class Game{
private String name;
private String location;
private int participants;
public Game(String name, String location, int participants){
this.name = name;
this.location = location;
this. participants = participatns;
}
//getters and setters of all properties
And I have a ArrayList that looks like this:
ArrayList<Game>gameList = new ArrayList<Game>();
This ArrayList contains 5 games. I want to send those games to a php script so I figured that the smartest way to do this is to create a JSON array of objects and send those to the php script because those games could also be a 100 or more at some point.
My question is, how do I create a JSON array of Game objects?
Use Gson: https://sites.google.com/site/gson/gson-user-guide#TOC-Using-Gson
Game game = new Game();
Gson gson = new Gson();
String json = gson.toJson(game);
The best thing to do is get into GSON. GSON web site,
public class ExampleObject {
public static final String API_KEY = "get_response";
private static final String OFFSETS = "offsets";
#SerializedName(OFFSETS)
private List<Integer> mOffsets;
public ExampleObject() {
super();
}
public String getAPIKey() {
return API_KEY;
}
public List<Integer> getOffsets() {
return mOffsets;
}
}
Related
This question already has answers here:
Serialize object using GSON
(2 answers)
Closed 3 years ago.
Code:
public class Crate {
private final MapPosition cratePosition;
private final int tierId;
#Expose(serialize = false, deserialize = false)
private final Inventory inventory;
public Crate(MapPosition cratePosition, int tierId) {
this.cratePosition = cratePosition;
this.tierId = tierId;
this.inventory = Bukkit.createInventory(null, 9*3, "Supply Crate");
}
public void replenishCrates(CrateConfig config) {
List<CrateContent> contents = config.getContentByTier(tierId);
//TODO:
}
public Inventory getInventory() {
return inventory;
}
public Location toLocation(World world) {
return cratePosition.toLocation(world);
}
public MapPosition getCratePosition() {
return cratePosition;
}
public int getTierId() {
return tierId;
}}
The #Expose is being ignored and returning a null pointer exception when trying to deserialize and serialize the class contents. I have made sure to also include the correct GsonBuilder modifications, as stated in Gson's documentation.
The problem you are having is not because #Expose is being ignored but rather because #Expose is missing on the other attributes.
The GsonBuilder's modification you are refering to is the following:
This annotation has no effect unless you build Gson with a GsonBuilder and invoke GsonBuilder.excludeFieldsWithoutExposeAnnotation() method.
But thank God the authors have correctly named the method and it will do just what it is expressing: it will exclude every field that is not marked with the #Expose annotation.
Here is an illustration based on your code (a little bit different because you did not share a completely reproductible sample)
public class Crate {
private final String cratePosition;
private final int tierId;
#Expose(serialize = false, deserialize = false)
private final Inventory inventory;
public Crate(String cratePosition, int tierId) {
this.cratePosition = cratePosition;
this.tierId = tierId;
this.inventory = new Inventory("IV-ID-111000", 10200);
}
public Inventory getInventory() {
return inventory;
}
public int getTierId() {
return tierId;
}
public String getCratePosition() {
return cratePosition;
}
}
And the following test:
public static void main(String[] args) {
Gson gson = new GsonBuilder().excludeFieldsWithoutExposeAnnotation().create();
Crate crate = new Crate("484:125.52", 1250);
String jsonString = gson.toJson(crate);
System.out.println(jsonString);
String json = "{\"cratePosition\":\"4894:125.52\",\"tierId\":2350}";
Crate deserialized = gson.fromJson(json, Crate.class);
System.out.println(deserialized.getCratePosition() + ":" + deserialized.getTierId());
}
In the current case I have no #Expose annotation on cratePosition and tierId fields, so they are excluded from the serialization and deserialization. Therefore my test returns:
{}
null:0
Now let's add the #Expose annotation on the cratePosition and tierId fields in the Crate class:
#Expose()
private final String cratePosition;
#Expose()
private final int tierId;
By default the serialize and deserialize parameters of the #Expose annotation are both set to true. You can play with it and change the values to see the differences it produces.
If I run the test again I have:
{"cratePosition":"484:125.52","tierId":1250}
4894:125.52:2350
I have some data in the form of JSON, and was using the GSON library to parse it into a Java object to be used in later portions of the code. The JSON has nested objects, which don't seem to be getting parsed properly, and I can't figure out why, as the outer object is being converted as desired. Here is an example of the JSON data I'm looking at:
{
"title":"Emergency Services Headquarters",
"description":"",
"cid":"C70856",
"building_id":"4714",
"building_number":"3542",
"campus_code":"20",
"campus_name":"Busch",
"location":{
"name":"Emergency Services Headquarters",
"street":"129 DAVIDSON ROAD",
"additional":"",
"city":"Piscataway",
"state":"New Jersey",
"state_abbr":"NJ",
"postal_code":"08854-8064",
"country":"United States",
"country_abbr":"US",
"latitude":"40.526306",
"longitude":"-74.461470"
},
"offices":[
"Emergency Services"
]
}
I used codebeautify to create the Java object classes required for the JSON (everything is within Building.java):
public class Building {
private String title;
private String description;
private String cid;
private String building_id;
private String building_number;
private String campus_code;
private String campus_name;
Location LocationObject;
ArrayList < Object > offices = new ArrayList < Object > ();
//Setters and getters have been omitted
}
class Location {
private String name;
private String street;
private String additional;
private String city;
private String state;
private String state_abbr;
private String postal_code;
private String country;
private String country_abbr;
private String latitude;
private String longitude;
//Setters and getters have been omitted
}
Here is the code I'm using to parse the JSON, where the variable json is an input parameter for the method:
Gson obj = new Gson();
JsonArray buildingsArray = new JsonArray();
JsonParser parser = new JsonParser();
JsonElement jsonElement = parser.parse(json);
buildingsArray = jsonElement.getAsJsonArray();
for (int i = 0; i < buildingsArray.size(); i++)
Building building = obj.fromJson(buildingsArray.get(i), Building.class);
When I call methods such as building.getTitle() or building.getCid(), I get the appropriate values, however when I do building.getLocation() (where Location is a separate object), the code returns null. I have not been able to figure it out, is it an issue with the way GSON works? Or am I doing something wrong in my code?
First of all, change:
Location LocationObject;
to:
private Location location;
And, you can deserialise JSON much easier:
Gson gson = new GsonBuilder().create();
Building building = gson.fromJson(json, Building.class);
Json property name should match your POJO class properties, it should be location not LocationObject
public class Building {
private String title;
private String description;
private String cid;
private String building_id;
private String building_number;
private String campus_code;
private String campus_name;
Location location;
ArrayList < Object > offices = new ArrayList < Object > ();
//Setters and getters have been omitted
}
It seems that you have a bad naming. Your location object in Building class is called LocationObject when your object inside JSON is called location.
I have this class:
public class Campaign
{
String Campaign_ID;
String Campaign_Description;
String startQuestion;
ArrayList Question_Array;
ArrayList workflow;
public Campaign(String ID, String description, String start, ArrayList quesArray, ArrayList workflow)
{
this.Campaign_ID = ID;
this.Campaign_Description = description;
this.startQuestion = start;
this.Question_Array = quesArray;
this.workflow = workflow;
}
public String getID() {return this.Campaign_ID;}
public String getDescription() {return this.Campaign_Description;}
public String getStartQuestion() {return this.startQuestion;}
public ArrayList getQuestionArray() {return this.Question_Array;}
public ArrayList getWorkflow() {return this.workflow;}
public Base_Question getQuestionByID(String ID){
Base_Question result = null;
for (int i=0;i<Question_Array.size();i++)
{
if ( ((Base_Question) Question_Array.get(i)).getQuestionID().equals(ID) )
result = (Base_Question) Question_Array.get(i);
}
return result;
}
}
The ArrayList Question_Array contains a list of instances from other classes.
Then I initialize an instance of Campaign:
Campaign campaign = new Campaign("Cam999","description blabla","Q001",list, workflow);
Then I serialize this instance into text:
Gson gson = new Gson();
String text = gson.toJson(campaign);
To get back the instance of Campaign class, I use:
Campaign campaign2 = gson.fromJson(text, Campaign.class);
I can print things from campaign2 correctly, like campaign2.getID() returns Cam999. But the problem is the ArrayList inside campaign2.
campaign2.getQuestionArray().get(index).getClass() prints com.google.gson.internal.LinkedTreeMap, not my custom class.
My whole source code is here https://github.com/khoiboo/Class_Hierarchy
How to solve this problem. I appreciate your help so much
How can I use gson to convert my object into json.I have two array lists in my object.I know the convertion if there is a single array list in the object by giving the type at gson.toJson(Object.class,).
Here my problem is I have two array lists which are related to two different objects.
Here is my object:
public class Profile
{
private String doctor_id;
private String name;
private String location;
private String phone;
private String minimum_amount;
private String minimum_slot;
private List<specialties> specialties;
private List<education> education;
}
public class specialties {
private String specialty_id;
private String specialization;
private List<super_specialties> super_specialties;
}
public class super_specialties {
private String super_specialty_id;
private String super_specialization;
}
public class education {
private String qualification;
private String yearOfCompletion;
}
Please guid me how to use gson to convert this object into json.
Thanks,
Chaitanya.K
Have you tried this.
Hope it help. Worked for me.
Gson gson = new Gson();
String obj = gson.toJson(ProfileClassObject);
System.out.println(obj);
This obj variable has the Json which you want.
What design-pattern, if any, would be most appropriate in this situation.
public class PersonFromDB1 {
private String firstName;
private String lastName;
private String Car;
}
public class PersonFromDB2 {
private String first_name;
private String last_name;
private String boat;
}
Out of these two person types, the only data I would like to work on is fist name and last name regardless of how it field name is name inside the different DBs. firstName and first_name represents the same - name of a person/customer - so does lastName and last-name. The car and boat fields are, in my example, completely irrelevant and should therefore be ignored.
Using, maybe polymorphism or the adapter pattern (?), I would like to create a list of objects that includes persons from DB1 and DB2 under the same type - of PersonInOurDB.
In the end, my goal is to be able to call GSON serialization/desarialization on myClass alone.
public class PersonInOurDB {
private String firstname;
private String lastname;
}
A simple selection based on the type is all you really need. This could be considered a builder pattern because it just initializes a new instance of myClass.
Note, this is rough pseudo code.
FunctionName(SomeType instance)
{
string aPostfix = "_1";
string bPostfix = "_2";
string selectedPostFix;
// This is your strategy selector
switch(typeof(SomeType.Name)
{
case "TypeA":
selectedPostFix = aPostFix;
case "TypeB":
selectedPostFix = bPostFix;
}
return new myClass()
{
A = instance.GetProperty("A" + selectedPostfix).Value,
B = instance.GetProperty("B" + selectedPostfix).Value,
...
}
}
If you want a common access api in java for both objects, then introduce an interface and let both implement it.
If you only want both objects (PersonFromDB1 and PersonFromDB2) to be serialized in the same way by json you can either:
use annotations - the #SerializedName annotation in combination with #Expose.
use the FieldNamingStratgy and ExclusionStrategy
Use annotations to control the serialization
public class PersonFromDB1 {
#Expose
#SerializedName("firstName")
private String firstName;
#Expose
#SerializedName("lastName")
private String lastName;
private String car;
}
public class PersonFromDB2 {
#Expose
#SerializedName("firstName")
private String first_Name;
#Expose
#SerializedName("lastName")
private String last_Name;
private String boat;
}
Then you can use the GsonBuilder
Gson gson = new GsonBuilder().excludeFieldsWithoutExposeAnnotation().create();
PersonFromDB1 person1 = ...; // get the object
PersonFromDB2 person2 = ...; // get the object
System.out.println(gson.toJson(person1));
System.out.println(gson.toJson(person2));
Use FieldNamingStratgy and ExclusionStrategy to control the serialization
If you don't want to modify the db objects (you can't or you don't want to add annotations) than there is another way. You can use a FieldNamingStratgy and ExclusionStrategy.
class PersonFromDBNamingStrategy implements FieldNamingStrategy {
Map<String, String> fieldMapping = new HashMap<String, String>();
public PersonFromDBNamingStrategy() {
fieldMapping.put("first_Name", "firstName");
fieldMapping.put("last_Name", "lastName");
}
#Override
public String translateName(Field f) {
String name = f.getName();
if(fieldMapping.contains(name)){
return fieldMapping.get(name);
}
return name;
}
}
and the ExclusionStrategy
class PersonFromDExclusionStrategy implements ExclusionStrategy {
List<String> validNames = Arrays.asList("car", "boat");
#Override
public boolean shouldSkipField(FieldAttributes f) {
String name = f.getName();
return !validNames.contains(name);
}
#Override
public boolean shouldSkipClass(Class<?> clazz) {
return false;
}
}
after that just create Gson like this:
GsonBuilder gsonBuilder = new GsonBuilder();
sonBuilder.addSerializationExclusionStrategy(new PersonFromDExclusionStrategy());
gsonBuilder.setFieldNamingStrategy(new PersonFromDBNamingStrategy());
Gson gson = gsonBuilder.create();
PersonFromDB1 person1 = ...; // get the object
PersonFromDB2 person2 = ...; // get the object
System.out.println(gson.toJson(person1));
System.out.println(gson.toJson(person2));