So I have the following code:
Team team = new Team();
team.setLeader(player.getUniqueId().toString());
team.setTeamName(args[1]);
team.setSerilizedInventory(InventoryStringDeSerializer.InventoryToString(inventory));
List<String> mods = new ArrayList<String>();
team.setMods(mods);
team.setMembers(members);
Teams teams = new Teams();
teams.setTeam(team);
try{
Gson gson = new GsonBuilder().setPrettyPrinting().create();
Writer writer = new FileWriter(instance.getFile());
gson.toJson(team, writer);
writer.close();
}catch(IOException e){
e.printStackTrace();
}
I am attempting to create a json file that contains all my team values, but I am not sure how to make it in nested object forum.
I am wanting to follow this json structer.
{
"teams",{
"teamname",{
"members":["069dcc56-cc5b-3867-a4cd-8c00ca516344"],
"leader": "RenegadeEagle",
"serilizedInventory": "54;",
"mods":[],
leader: "069dcc56-cc5b-3867-a4cd-8c00ca516344",
}
}
}
That may not even be proper Json but you get the idea. So how would I write this using gson to a file?
Thanks.
Please check this solution, you need to have reference in multiple levels
For writing file to the Android file system refer this link for solution
Error: Could not find or load main class com.example.pdfone.MainActivity
However i strongly recommend you to store this JSON in a SQL Lite Table.
Team.java
import java.util.List;
public class Team {
private String leader;
private String serilizedInventory;
private List members;
private List mods;
public String getLeader() {
return leader;
}
public void setLeader(String leader) {
this.leader = leader;
}
public String getSerilizedInventory() {
return serilizedInventory;
}
public void setSerilizedInventory(String serilizedInventory) {
this.serilizedInventory = serilizedInventory;
}
public List getMembers() {
return members;
}
public void setMembers(List members) {
this.members = members;
}
public List getMods() {
return mods;
}
public void setMods(List mods) {
this.mods = mods;
}
}
TeamsWrapper.java
import java.util.List;
public class TeamsWrapper {
private List<Team> team;
private String teamName;
public List<Team> getTeam() {
return team;
}
public void setTeam(List<Team> team) {
this.team = team;
}
public String getTeamName() {
return teamName;
}
public void setTeamName(String teamName) {
this.teamName = teamName;
}
}
Test.java --> Main Program
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
public class Test {
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
Team team = new Team();
team.setLeader("RenegadeEagle");
team.setSerilizedInventory("54;");
team.setMods(new ArrayList());
List members = new ArrayList();
members.add("069dcc56-cc5b-3867-a4cd-8c00ca516344");
team.setMembers(members);
TeamsWrapper tw = new TeamsWrapper();
List ls1 = new ArrayList();
ls1.add(team);
ls1.add(team);
tw.setTeam(ls1);
tw.setTeamName("teamname");
Gson gson = new GsonBuilder().create();
System.out.println(gson.toJson(tw));
}
}
Final Output from the program
{
"team" : [{
"leader" : "RenegadeEagle",
"serilizedInventory" : "54;",
"members" : ["069dcc56-cc5b-3867-a4cd-8c00ca516344"],
"mods" : []
}, {
"leader" : "RenegadeEagle",
"serilizedInventory" : "54;",
"members" : ["069dcc56-cc5b-3867-a4cd-8c00ca516344"],
"mods" : []
}
],
"teamName" : "teamname"
}
Related
Here is the code I want to create with my Java code. I'm not doing anything elaborate. Just trying to refresh myself with parsing json from java.
[{"county":"Jefferson",
"houses":\[
{"squareFeet":1100,
"bedrooms":2,
"bathrooms":2,
"internet":"y",
"location":"Country"
},
{"squareFeet":750,
"bedrooms":1,
"bathrooms":1,
"internet":"n",
"location":"Town"
}
\]
}]
At the moment my Java code looks like this.
With this code below I am close to having it, with the exception of the first Object, and also the title to the array of houses.
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import java.io.FileWriter;
import java.io.IOException;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.Formatter;
import java.util.List;
public class HousesToJSON {
/**
* #param args
* #throws IOException
*/
public static void main(String[] args) throws IOException {
Gson gson = new GsonBuilder().setPrettyPrinting().create();
JSONArray houses = new JSONArray();
House houseOne = createHouseObjectOne();
House houseTwo = createHouseObjectTwo();
houses.add(houseOne);
houses.add(houseTwo);
try (FileWriter writer = new FileWriter("houses.json")) {
gson.toJson(houses, writer);
} catch (IOException e) {
e.printStackTrace();
}
}
private static House createHouseObjectOne() {
House house = new House();
house.setSquareFeet(1100);
house.setBedrooms(2);
house.setBathrooms(2);
house.setInternet('y');
house.setLocation("Country");
return house;
}
private static House createHouseObjectTwo() {
House house = new House();
house.setSquareFeet(750);
house.setBedrooms(2);
house.setBathrooms(1);
house.setInternet('y');
house.setLocation("Town");
return house;
}
}
This create the file below.
[
{
"squareFeet": 1100,
"bedrooms": 2,
"bathrooms": 2,
"internet": "y",
"location": "Country"
},
{
"squareFeet": 750,
"bedrooms": 2,
"bathrooms": 1,
"internet": "y",
"location": "Town"
}
]
I am still pretty new at this, and any help would be much appreciated.
Something along the lines of this should provide you with the neccesary objects for your JSON example:
package com.example;
import java.util.List;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
public class CountyContainer {
#SerializedName("county")
#Expose
private String county;
#SerializedName("houses")
#Expose
private List<House> houses = null;
public String getCounty() {
return county;
}
public void setCounty(String county) {
this.county = county;
}
public List<House> getHouses() {
return houses;
}
public void setHouses(List<House> houses) {
this.houses = houses;
}
}
package com.example;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
public class House {
#SerializedName("squareFeet")
#Expose
private Integer squareFeet;
#SerializedName("bedrooms")
#Expose
private Integer bedrooms;
#SerializedName("bathrooms")
#Expose
private Integer bathrooms;
#SerializedName("internet")
#Expose
private String internet;
#SerializedName("location")
#Expose
private String location;
public Integer getSquareFeet() {
return squareFeet;
}
public void setSquareFeet(Integer squareFeet) {
this.squareFeet = squareFeet;
}
public Integer getBedrooms() {
return bedrooms;
}
public void setBedrooms(Integer bedrooms) {
this.bedrooms = bedrooms;
}
public Integer getBathrooms() {
return bathrooms;
}
public void setBathrooms(Integer bathrooms) {
this.bathrooms = bathrooms;
}
public String getInternet() {
return internet;
}
public void setInternet(String internet) {
this.internet = internet;
}
public String getLocation() {
return location;
}
public void setLocation(String location) {
this.location = location;
}
}
You can generate these yourself using this online service and selecting the GSON annotation style:
http://www.jsonschema2pojo.org/
When you've created your objects, you can write those objects to a JSON file using:
final Gson gson = new Gson();
try (final FileWriter writer = new FileWriter("houses.json")) {
gson.toJson(houses, writer); // houses refers to your object containing the List of House objects and the country
} catch (final IOException e) {
// Handle exceptions here
}
Alternatively, you can also use place the JSON data into a String:
String json = gson.toJson(houses);
For more information regarding GSON functionality, please take a look at the official documentation:
https://www.javadoc.io/doc/com.google.code.gson/gson/latest/com.google.gson/module-summary.html
There is no House class provided, but I guess we can skip it. You are moving in the right direction. Just add another class:
public class County {
private String county;
private List<House> houses;
// getters, setters, whatever :)
}
And create instance of this class. Set name (county field) and houses and serialize to JSON :)
I would probably rename json array to JSONArray counties = new JSONArray(); and what you need to add to this array is some county with name "Jefferson" and list of houses that you have now.
County county = new County();
county.setCounty("Jefferson");
List<House> houses = new ArrayList<>();
houses.add(houseOne);
houses.add(houseTwo);
county.setHouses(houses);
counties.add(county);
This might not be 100% working code, but hope the idea is clear :)
Eclipse gave option to auto generate the toString method for every class.
Further leverage this facility, I am creating String Format Template to give as Json format when eclipse generate toString Method.
I used following String Format Template:
{ ${member.name()}:"${member.value}", ${otherMembers}}
now i generated toString method as following POJO but When i run this program i got result as and not a VALID JSON.
{ name:"null", reportees:"[1, 2, 3]", department:"[retail, banking, finance]", owns:"null", supplimentary:"null}
Code
public class TestPojo {
private String name;
private List<String> reportees;
private String[] department;
private Machine owns;
private List<Machine> supplimentary;
public static void main(String arg[]) {
TestPojo aTestPojo = new TestPojo();
aTestPojo.department = new String[] { "retail", "banking", "finance" };
aTestPojo.reportees = new ArrayList<String>() {
{
add("1");
add("2");
add("3");
}
};
System.out.print(aTestPojo);
}
public static class Machine {
private String machineName;
private String duties;
public String getMachineName() {
return machineName;
}
public void setMachineName(String machineName) {
this.machineName = machineName;
}
public String getDuties() {
return duties;
}
public void setDuties(String duties) {
this.duties = duties;
}
#Override
public String toString() {
StringBuilder builder = new StringBuilder();
builder.append("{ machineName:\"").append(machineName).append("\", duties:\"").append(duties).append("}");
return builder.toString();
}
}
#Override
public String toString() {
StringBuilder builder = new StringBuilder();
builder.append("{ name:\"").append(name).append("\", reportees:\"").append(reportees).append("\", department:\"").append(Arrays.toString(department)).append("\", owns:\"").append(owns).append("\", supplimentary:\"").append(supplimentary).append("}");
return builder.toString();
}
}
With the help of #dvlcube idea. I built a "Eclipse Custom toString() builder" to generate toString method code to return a JSON formatted string of current object.
Follow the github for this solution Click [Eclipse toString_Builder for JSON](https://github.com/djaganathan/EclipseToStringBuilderForJson/blob/master/src/main/java/com/github/djaganathan/opensource/eclipse/util/JsonToStringBuilder.java,"Custom Eclipse toString() Builder")
Sample Testing Code
import com.google.common.collect.Maps;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import org.apache.commons.lang3.time.StopWatch;
import org.elasticsearch.common.collect.Lists;
public class TestPojo {
private String name;
private List<String> reportees;
private String[] department;
private Machine owns;
private List<Machine> supplimentary;
private int i = 10;
private Map<String, Machine> machineList = Maps.newConcurrentMap();
public static void main(String arg[]) {
TestPojo aTestPojo = new TestPojo();
aTestPojo.department = new String[] { "retail", "banking", "finance"};
aTestPojo.reportees = new ArrayList<String>() {
{
add("1");
add("2");
add("3");
}
};
Machine aMachine = new Machine("Train", "travel");
Machine aMachine1 = new Machine("Lorry", "Carrier");
aTestPojo.supplimentary = Lists.newArrayList(aMachine, aMachine1);
aTestPojo.machineList.put("Train", aMachine);
aTestPojo.machineList.put("Lorry", aMachine1);
System.out.print(aTestPojo);
}
public static class Machine {
private String machineName;
private String duties;
public Machine(String machineName, String duties) {
super();
this.machineName = machineName;
this.duties = duties;
}
public String getMachineName() {
return machineName;
}
public void setMachineName(String machineName) {
this.machineName = machineName;
}
public String getDuties() {
return duties;
}
public void setDuties(String duties) {
this.duties = duties;
}
#Override
public String toString() {
JsonToStringBuilder builder = new JsonToStringBuilder(this);
builder.append("machineName", machineName);
builder.append("duties", duties);
return builder.build();
}
}
#Override
public String toString() {
JsonToStringBuilder builder = new JsonToStringBuilder(this);
builder.append("name", name);
builder.append("reportees", reportees);
builder.append("department", department);
builder.append("owns", owns);
builder.append("supplimentary", supplimentary);
builder.append("i", i);
builder.append("machineList", machineList);
String value = builder.build();
return value;
}
}
While running this program i got the following JSON output
{"name": null,"reportees": ["1","2","3"],"department": ["retail","banking","finance"],"owns": null,"supplimentary": [{"machineName": "Train","duties": "travel"},{"machineName": "Lorry","duties": "Carrier"}],"i": 10,"machineList": {"Lorry": {"machineName": "Lorry","duties": "Carrier"},"Train": {"machineName": "Train","duties": "travel"}}}
It's not valid JSON because of the way arrays and collections are being printed ("[1,2,3]" instead of ["1","2","3"]).
Also, it wouldn't pass strict JSON validation because the field names should be quoted as well.
Eclipse's String Format Template can be very useful, but for full control it's better to create a builder class.
Here's a gist for doing just that. You can expand on it, and it works for your example class out of the box.
You can use this class to generate the toString() methods in Eclipse.
Recommended only for String values. Below expression gives you as a JSON toString generation.
{"${member.name()}":"${member.value}", "${otherMembers}"}
I have a simple problem, but I cannot find a solution by myself.
I need serialize two maps. One has Object as key and Integer as value. Another One has similar properties but key-object contains a list.
Here are my models.
Detail
package Model;
/**
* Created by kh0ma on 01.11.16.
*/
public class Detail {
private String name;
public Detail() {
}
public Detail(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
#Override
public String toString() {
return "Detail{" +
"name='" + name + '\'' +
'}';
}
}
Mechanism
package Model;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonNaming;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import java.util.ArrayList;
import java.util.List;
/**
* Created by kh0ma on 01.11.16.
*/
public class Mechanism {
private String name;
private List<Detail> details;
public Mechanism(String name) {
this.name = name;
this.details = new ArrayList<Detail>();
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List<Detail> getDetails() {
return details;
}
public void setDetails(List<Detail> details) {
this.details = details;
}
#Override
public String toString() {
return "Mechanism{" +
"name='" + name + '\'' +
", details=" + details +
'}';
}
}
Then I pull data in maps by another class.
PullData
package PullData;
import Model.Detail;
import Model.Mechanism;
import java.util.HashMap;
import java.util.Map;
/**
* Created by kh0ma on 01.11.16.
*/
public class PullData {
public static Map<Detail,Integer> DETAILS = new HashMap<Detail, Integer>();
public static Map<Mechanism,Integer> MECHANISMS = new HashMap<Mechanism, Integer>();
private static Detail detail1 = new Detail("Wheel");
private static Detail detail2 = new Detail("Frame");
private static Detail detail3 = new Detail("Seat");
private static Detail detail4 = new Detail("Engine");
private static Detail detail5 = new Detail("Headlight");
public static void pullDetails()
{
DETAILS.put(detail1,6);
DETAILS.put(detail2,2);
DETAILS.put(detail3,5);
DETAILS.put(detail4,1);
DETAILS.put(detail5,2);
}
public static void pullMechanisms()
{
Mechanism car = new Mechanism("Car");
car.getDetails().add(detail1);
car.getDetails().add(detail2);
car.getDetails().add(detail3);
car.getDetails().add(detail4);
car.getDetails().add(detail5);
Mechanism bicycle = new Mechanism("Bicycle");
bicycle.getDetails().add(detail1);
bicycle.getDetails().add(detail2);
MECHANISMS.put(car,1);
MECHANISMS.put(bicycle,1);
}
}
Than I try to serialize and deserialize maps in main method.
TestJSON
package TestJSON;
import Model.Detail;
import Model.Mechanism;
import PullData.PullData;
import com.fasterxml.jackson.core.JsonGenerationException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.type.MapType;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
/**
* Created by kh0ma on 01.11.16.
*/
public class TestJSON {
public static void main(String[] args) {
PullData.pullDetails();
PullData.pullMechanisms();
System.out.println("=+=+=+=BEFORE JSON SERIALISATION=+=+=+=");
System.out.println("-=-=-=-=-=Before changes=-=-=-=-=-=-");
PullData.DETAILS.forEach((k, v) -> System.out.println(k));
PullData.MECHANISMS.forEach((k, v) -> System.out.println(k));
System.out.println("-=-=-=-=-=After changes=-=-=-=-=-=-");
PullData.MECHANISMS.forEach((k, v) -> {
if (k.getName().equals("Bicycle")) k.getDetails()
.forEach((detail -> detail.setName(detail.getName() + "FirstChanges")));
});
PullData.DETAILS.forEach((k, v) -> System.out.println(k));
PullData.MECHANISMS.forEach((k, v) -> System.out.println(k));
System.out.println("=+=+=+=JSON Print=+=+=+=");
ObjectMapper objectMapper = new ObjectMapper();
File jsonFileDetails = new File("src/main/resources/json/jsonDetails.txt");
File jsonFileMechanisms = new File("src/main/resources/json/jsonMechanisms.txt");
try {
objectMapper.writerWithDefaultPrettyPrinter().writeValue(jsonFileDetails, PullData.DETAILS);
objectMapper.writerWithDefaultPrettyPrinter().writeValue(jsonFileMechanisms, PullData.MECHANISMS);
} catch (JsonGenerationException e) {
e.printStackTrace();
} catch (JsonMappingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
System.out.println("=+=+=+=AFTER JSON SERIALISATION=+=+=+=");
System.out.println("-=-=-=-=-=Before changes=-=-=-=-=-=-");
ObjectMapper mapper = new ObjectMapper();
MapType mapType = mapper.getTypeFactory().constructMapType(HashMap.class, Mechanism.class, Integer.class);
Map<Detail, Integer> detailesAfterJson = new HashMap<Detail, Integer>();
Map<Mechanism, Integer> mechanismsAfterJson = new HashMap<Mechanism, Integer>();
try {
detailesAfterJson = mapper.readValue(jsonFileDetails, new TypeReference<HashMap<Detail, Integer>>() {});
mechanismsAfterJson = mapper.readValue(jsonFileMechanisms, new TypeReference<Map<Mechanism, Integer>>() {});
} catch (JsonGenerationException e) {
e.printStackTrace();
} catch (JsonMappingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
detailesAfterJson.forEach((k, v) -> System.out.println(k));
mechanismsAfterJson.forEach((k, v) -> System.out.println(k));
}
}
First map serializes like this.
jsonDetails.txt
{
"Detail{name='WheelFirstChanges'}" : 6,
"Detail{name='FrameFirstChanges'}" : 2,
"Detail{name='Seat'}" : 5,
"Detail{name='Engine'}" : 1,
"Detail{name='Headlight'}" : 2
}
And another one like this.
jsonMechanisms.txt
{
"Mechanism{name='Car', details=[Detail{name='WheelFirstChanges'}, Detail{name='FrameFirstChanges'}, Detail{name='Seat'}, Detail{name='Engine'}, Detail{name='Headlight'}]}" : 1,
"Mechanism{name='Bicycle', details=[Detail{name='WheelFirstChanges'}, Detail{name='FrameFirstChanges'}]}" : 1
}
In java console I have this output.
console_output
/usr/lib/jvm/jdk1.8.0_102/bin/java -Didea.launcher.port=7544 -Didea.launcher.bin.path=/home/kh0ma/idea-IU-162.1121.32/bin -Dfile.encoding=UTF-8 -classpath "/usr/lib/jvm/jdk1.8.0_102/jre/lib/charsets.jar:/usr/lib/jvm/jdk1.8.0_102/jre/lib/deploy.jar:/usr/lib/jvm/jdk1.8.0_102/jre/lib/ext/cldrdata.jar:/usr/lib/jvm/jdk1.8.0_102/jre/lib/ext/dnsns.jar:/usr/lib/jvm/jdk1.8.0_102/jre/lib/ext/jaccess.jar:/usr/lib/jvm/jdk1.8.0_102/jre/lib/ext/jfxrt.jar:/usr/lib/jvm/jdk1.8.0_102/jre/lib/ext/localedata.jar:/usr/lib/jvm/jdk1.8.0_102/jre/lib/ext/nashorn.jar:/usr/lib/jvm/jdk1.8.0_102/jre/lib/ext/sunec.jar:/usr/lib/jvm/jdk1.8.0_102/jre/lib/ext/sunjce_provider.jar:/usr/lib/jvm/jdk1.8.0_102/jre/lib/ext/sunpkcs11.jar:/usr/lib/jvm/jdk1.8.0_102/jre/lib/ext/zipfs.jar:/usr/lib/jvm/jdk1.8.0_102/jre/lib/javaws.jar:/usr/lib/jvm/jdk1.8.0_102/jre/lib/jce.jar:/usr/lib/jvm/jdk1.8.0_102/jre/lib/jfr.jar:/usr/lib/jvm/jdk1.8.0_102/jre/lib/jfxswt.jar:/usr/lib/jvm/jdk1.8.0_102/jre/lib/jsse.jar:/usr/lib/jvm/jdk1.8.0_102/jre/lib/management-agent.jar:/usr/lib/jvm/jdk1.8.0_102/jre/lib/plugin.jar:/usr/lib/jvm/jdk1.8.0_102/jre/lib/resources.jar:/usr/lib/jvm/jdk1.8.0_102/jre/lib/rt.jar:/home/kh0ma/Dropbox/JavaStuding/JavaRush/JavaRushHomeWork/Test JSON for ANTONIOPRIME/target/classes:/home/kh0ma/Dropbox/JavaStuding/JavaRush/JavaRushHomeWork/Test JSON for ANTONIOPRIME/lib/gson-2.7.jar:/home/kh0ma/.m2/repository/com/fasterxml/jackson/core/jackson-databind/2.2.3/jackson-databind-2.2.3.jar:/home/kh0ma/.m2/repository/com/fasterxml/jackson/core/jackson-annotations/2.2.3/jackson-annotations-2.2.3.jar:/home/kh0ma/.m2/repository/com/fasterxml/jackson/core/jackson-core/2.2.3/jackson-core-2.2.3.jar:/home/kh0ma/idea-IU-162.1121.32/lib/idea_rt.jar" com.intellij.rt.execution.application.AppMain TestJSON.TestJSON
=+=+=+=BEFORE JSON SERIALISATION=+=+=+=
-=-=-=-=-=Before changes=-=-=-=-=-=-
Detail{name='Wheel'}
Detail{name='Frame'}
Detail{name='Seat'}
Detail{name='Engine'}
Detail{name='Headlight'}
Mechanism{name='Car', details=[Detail{name='Wheel'}, Detail{name='Frame'}, Detail{name='Seat'}, Detail{name='Engine'}, Detail{name='Headlight'}]}
Mechanism{name='Bicycle', details=[Detail{name='Wheel'}, Detail{name='Frame'}]}
-=-=-=-=-=After changes=-=-=-=-=-=-
Detail{name='WheelFirstChanges'}
Detail{name='FrameFirstChanges'}
Detail{name='Seat'}
Detail{name='Engine'}
Detail{name='Headlight'}
Mechanism{name='Car', details=[Detail{name='WheelFirstChanges'}, Detail{name='FrameFirstChanges'}, Detail{name='Seat'}, Detail{name='Engine'}, Detail{name='Headlight'}]}
Mechanism{name='Bicycle', details=[Detail{name='WheelFirstChanges'}, Detail{name='FrameFirstChanges'}]}
=+=+=+=JSON Print=+=+=+=
=+=+=+=AFTER JSON SERIALISATION=+=+=+=
-=-=-=-=-=Before changes=-=-=-=-=-=-
Detail{name='Detail{name='Engine'}'}
Detail{name='Detail{name='Seat'}'}
Detail{name='Detail{name='Headlight'}'}
Detail{name='Detail{name='WheelFirstChanges'}'}
Detail{name='Detail{name='FrameFirstChanges'}'}
Mechanism{name='Mechanism{name='Bicycle', details=[Detail{name='WheelFirstChanges'}, Detail{name='FrameFirstChanges'}]}', details=[]}
Mechanism{name='Mechanism{name='Car', details=[Detail{name='WheelFirstChanges'}, Detail{name='FrameFirstChanges'}, Detail{name='Seat'}, Detail{name='Engine'}, Detail{name='Headlight'}]}', details=[]}
Process finished with exit code 0
As you can see the maps before and after have differences, but I need absolutely identical maps.
Can you suggest me the solution?
I downloaded clases into GitHub repository.
JSON_TEST
Thanks for your answers.
In JSON, keys must be strings. Your implementation uses the toString methods of Detail and Mechanism as keys. Since these methods return different strings, the JSON keys will be different.
I recommend to not use anything else than strings as map keys if you want to serialize to JSON.
I need a Java data structure for some JSON data passed to me by the Datatables Editor. The format of the data received is this:
{
"action":"edit",
"data": {
"1009558":{
"weekNumber":"2"
... (more properties)
}
}
}
Here's the full documentation: https://editor.datatables.net/manual/server
Edit: The documentation shows the data sent as form params. I am stringifying the data and sending it as JSON. An example is above.
"1009558" is the row ID. If there are multiple rows sent by the editor, there would be multiple array entries (each with an ID).
Can anyone offer some advice on how to make a Java data structure for deserialization (by Spring MVC)? I can map "action" easy enough, but I'm getting stuck on the "data" element.
I'd rather suggest you to use jackson.
Here's an example, that you're asking for:
package com.github.xsavikx.jackson;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.util.HashMap;
import java.util.Map;
public class JacksonTest {
public static void main(String[] args) throws JsonProcessingException {
ObjectMapper objectMapper = new ObjectMapper();
Map<String, DatabaseRow> data = new HashMap<>();
DatabaseRow row = new DatabaseRow(2, "someData");
data.put("1009558", row);
String action = "action";
DatabaseEntry dbEntry = new DatabaseEntry();
dbEntry.setAction(action);
dbEntry.setData(data);
System.out.println(objectMapper.writeValueAsString(dbEntry));
}
}
And the result:
{"action":"action","data":{"1009558":{"weekNumber":2,"someData":"someData"}}}
Models:
package com.github.xsavikx.jackson;
import java.util.Map;
public class DatabaseEntry {
private String action;
private Map<String, DatabaseRow> data;
public DatabaseEntry() {
}
public DatabaseEntry(String action, Map<String, DatabaseRow> data) {
this.action = action;
this.data = data;
}
public Map<String, DatabaseRow> getData() {
return data;
}
public void setData(Map<String, DatabaseRow> data) {
this.data = data;
}
public String getAction() {
return action;
}
public void setAction(String action) {
this.action = action;
}
}
package com.github.xsavikx.jackson;
public class DatabaseRow {
private int weekNumber;
private String someData;
public DatabaseRow(){
}
public DatabaseRow(int weekNumber, String someData) {
this.weekNumber = weekNumber;
this.someData = someData;
}
public int getWeekNumber() {
return weekNumber;
}
public void setWeekNumber(int weekNumber) {
this.weekNumber = weekNumber;
}
public String getSomeData() {
return someData;
}
public void setSomeData(String someData) {
this.someData = someData;
}
}
Update:
more generic solution with Map of maps:
package com.github.xsavikx.jackson;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
public class JacksonTest {
public static void main(String[] args) throws IOException {
serializeTest();
deserializeTest();
}
private static void deserializeTest() throws IOException {
ObjectMapper objectMapper = new ObjectMapper();
DatabaseEntry databaseEntry = objectMapper.readValue("{\"action\":\"action\",\"data\":{\"1009558\":{\"weekNumber\":2,\"someData\":\"someData\"}}}", DatabaseEntry.class);
System.out.println(databaseEntry);
}
private static void serializeTest() throws JsonProcessingException {
ObjectMapper objectMapper = new ObjectMapper();
Map<String,Map<String,String>> data = new HashMap<>();
Map<String,String> values = new HashMap<>();
values.put("weekDay","2");
values.put("unpredictableValue","value");
data.put("1009558", values);
String action = "action";
DatabaseEntry dbEntry = new DatabaseEntry();
dbEntry.setAction(action);
dbEntry.setData(data);
System.out.println(objectMapper.writeValueAsString(dbEntry));
}
}
Model:
package com.github.xsavikx.jackson;
import java.util.Map;
public class DatabaseEntry {
private String action;
private Map<String, Map<String,String>> data;
public DatabaseEntry() {
}
public String getAction() {
return action;
}
public void setAction(String action) {
this.action = action;
}
public Map<String, Map<String, String>> getData() {
return data;
}
public void setData(Map<String, Map<String, String>> data) {
this.data = data;
}
}
I'm a huge fan of Joe Littlejohn's JSON tool. Provide it with a sample JSON file and it can generate POJOs for you.
Here's a sample of what it generated, based on a snipped of JSON from the site you posted.
JSON:
{
"data": [
{
"DT_RowId": "row_29",
"first_name": "Fiona",
"last_name": "Green",
"position": "Chief Operating Officer (COO)",
"office": "San Francisco",
"extn": "2947",
"salary": "850000",
"start_date": "2010-03-11"
}
]
}
JAVA:
#Generated("org.jsonschema2pojo")
public class Datum {
public String dTRowId;
public String firstName;
public String lastName;
public String position;
public String office;
public String extn;
public String salary;
public String startDate;
}
#Generated("org.jsonschema2pojo")
public class Example {
public List<Datum> data = new ArrayList<Datum>();
}
Update:
It looks like this is what the form submit actually sends:
action:edit
data[row_1][first_name]:Tiger23
data[row_1][last_name]:Nixon
data[row_1][position]:System Architect
data[row_1][office]:Edinburgh
data[row_1][extn]:5421
data[row_1][start_date]:2011-04-25
data[row_1][salary]:320800
I don't think this is Json, and I dunno if I would try to treat it as such. If you need to submit form data with Java, you might be better of using the Apache HttpComponents. You can reuse the Java "data" object above as a domain object, and then populate the POST content with Strings of the format:
data[ \DT_RowId\ ][\PropertyName\]: \PropertyValue\
With Spring Boot the json conversion between server and client is automatic (https://stackoverflow.com/a/44842806/3793165).
This way is working for me:
Controller
#PostMapping(value="/nuevoVideo")
#ResponseBody
public RespuestaCreateVideo crearNuevoVideo(#RequestBody PeticionVideos datos) {
RespuestaCreateVideo respuesta = new RespuestaCreateVideo();
respuesta.setData("datos");
//respuesta.setError("error"); // implement the logic for error and return the message to show to the user.
return respuesta;
}
where PeticionVideos (RequestVideos) is the create structure Datatables editor sends (with setters, getters...):
public class PeticionVideos {
private Map<String, Video> data;
private String action;
}
The response from the server to the client datatable is waiting for has a particular format (check at https://editor.datatables.net/manual/server).
I often use this:
public class RespuestaCreateVideo { //ResponseCreateVideo
private String data;
private String error;
}
After two days trying this is working perfect now!
I have a JSON structure similar to this:
"teams": {
"team1Id": "team1Name",
"team2Id": "team2Name"
}
and I would like to deserialize it to these Java classes:
class Teams {
Team team1;
Team team2;
}
class Team {
String id;
String name;
}
As you can see team1Id and team2Id, which are JSON keys, should be converted into values of Java fields. Additionally, the first teamId/teamName pair should be attributed to the object stored in team1, while the second pair is stored in the team2 field.
Are there any native JACKSON mappers to do this, or will I need to create my own custom deserializer for this?
You can implement custom deserializer for this class, but, I think, much simpler solution will be using #JsonAnySetter annotation.
class Teams {
Team team1 = new Team();
Team team2 = new Team();
#JsonAnySetter
public void anySetter(String key, String value) {
if (key.startsWith("team1")) {
team1.setId(key);
team1.setName(value);
} else if (key.startsWith("team2")) {
team2.setId(key);
team2.setName(value);
}
}
//getters, setterr, toString()
}
Example usage:
import java.io.File;
import java.io.IOException;
import com.fasterxml.jackson.annotation.JsonAnySetter;
import com.fasterxml.jackson.databind.ObjectMapper;
public class JacksonProgram {
public static void main(String[] args) throws IOException {
ObjectMapper mapper = new ObjectMapper();
Wrapper wrapper = mapper.readValue(new File("X:/json"), Wrapper.class);
System.out.println(wrapper.getTeams());
}
}
class Wrapper {
private Teams teams;
public Teams getTeams() {
return teams;
}
public void setTeams(Teams teams) {
this.teams = teams;
}
}
Above program prints:
Teams [team1=Team [id=team1Id, name=team1Name], team2=Team [id=team2Id, name=team2Name]]
for this JSON:
{
"teams": {
"team1Id": "team1Name",
"team2Id": "team2Name"
}
}
### EDIT 1 ###
If your JSON looks like that:
{
"teams": {
"12345": "Chelsea",
"67890": "Tottenham"
}
}
I propose to deserialize it to LinkedHashMap<String, String> and after that convert it to Teams object. Example program:
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map.Entry;
import com.fasterxml.jackson.databind.ObjectMapper;
public class JacksonProgram {
public static void main(String[] args) throws IOException {
ObjectMapper mapper = new ObjectMapper();
Wrapper wrapper = mapper.readValue(new File("X:/json"), Wrapper.class);
System.out.println(wrapper.toTeams());
}
}
class Wrapper {
private LinkedHashMap<String, String> teams;
public LinkedHashMap<String, String> getTeams() {
return teams;
}
public void setTeams(LinkedHashMap<String, String> teams) {
this.teams = teams;
}
public Teams toTeams() {
List<Team> teamList = toTeamList();
Teams result = new Teams();
result.setTeam1(teamList.get(0));
result.setTeam2(teamList.get(1));
return result;
}
private List<Team> toTeamList() {
List<Team> teamList = new ArrayList<Team>(teams.size());
for (Entry<String, String> entry : teams.entrySet()) {
Team team = new Team();
team.setId(entry.getKey());
team.setName(entry.getValue());
teamList.add(team);
}
return teamList;
}
}
Above program prints:
Teams [team1=Team [id=12345, name=Chelsea], team2=Team [id=67890, name=Tottenham]]