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]]
Related
I'm running the next program:
import com.fasterxml.jackson.databind.ObjectMapper;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
public class Test {
private static class Shape {
private String name;
private Set<String> colors;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Set<String> getColors() {
return colors;
}
public void setColors(Set<String> colors) {
this.colors = colors;
}
}
public static void main(String[] args) {
ObjectMapper objectMapper = new ObjectMapper();
Map<String, Object> attributes = new HashMap<>();
attributes.put("name", "table");
attributes.put("colors", "blue,green,red,black");
Shape shape = objectMapper.convertValue(attributes, Shape.class);
}
}
Here the dependencies in the pom.xml:
<dependencies>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.9.3</version>
</dependency>
</dependencies>
I got the next error:
Exception in thread "main" java.lang.IllegalArgumentException: Cannot deserialize instance of `java.util.HashSet` out of VALUE_STRING token
at [Source: UNKNOWN; line: -1, column: -1] (through reference chain: com.company.test.Test$Shape["colors"])
at com.fasterxml.jackson.databind.ObjectMapper._convert(ObjectMapper.java:3751)
at com.fasterxml.jackson.databind.ObjectMapper.convertValue(ObjectMapper.java:3669)
at com.company.test.Test.main(Test.java:36)
I have tried changing to:
attributes.put("colors", "[blue,green,red,black]");
AND
attributes.put("colors", "[\"blue\",\"green\",\"red\",\"black\"]");
But it does not work. A workaround can be the next:
...
Set<String> colors = new HashSet<>();
colors.add("blue");
colors.add("green");
colors.add("red");
colors.add("black");
attributes.put("colors", colors);
...
However, that solution is not allowed for the current implementation. Do you imagine how to implemented using a different approach?
You can use CsvMapper from jackson-dataformats-text library. Also, you need to deserialise first String into Set<String>, build a Map and convert it to Shape at the end:
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.dataformat.csv.CsvMapper;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
public class CsvApp {
public static void main(String[] args) throws JsonProcessingException {
CsvMapper mapper = new CsvMapper();
String array = "blue,green,red,black";
Map<String, Object> attributes = new HashMap<>();
attributes.put("name", "table");
attributes.put("colors", mapper.readValue(array, new TypeReference<Set<String>>() {}));
Shape shape = mapper.convertValue(attributes, Shape.class);
System.out.println(shape);
}
}
I have JSON response:
{
"part1.id": "1",
"part1.name": "Name1",
"part2.id": "2",
"part2.name": "Name2"
}
POJO / DTO class for 1 user:
public class User {
private String id;
private String name;
// set/get
}
And class for the whole response:
public class UsersResponse {
private List<User> users;
// set/get
}
I can retrieve values in Map and then parse/map in code manually like
Jackson JSON map key as property of contained object
Also there is #JsonAlias for multiple naming variations but it maps to one object.
Is there any other way to map/group JSON values to List for provided prefixes?
There is no already implemented annotations which allow to do it by configuration. You need to implement deserialiser. Simple version ot that deserialiser could look like below:
class UsersResponseDeserializer extends JsonDeserializer<UsersResponse> {
private Pattern propertyPattern = Pattern.compile("^part(\\d+)\\.(.+)$");
#Override
public UsersResponse deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
Integer lastIndex = null;
String lastName = null;
Map<Integer, Map<String, String>> users = new LinkedHashMap<>();
while (p.currentToken() != null) {
switch (p.currentToken()) {
case FIELD_NAME:
String name = p.getText();
Matcher matcher = propertyPattern.matcher(name);
if (matcher.matches()) {
lastIndex = Integer.parseInt(matcher.group(1));
lastName = matcher.group(2);
}
break;
case VALUE_STRING:
if (lastIndex != null && lastName != null) {
Map<String, String> user = users.computeIfAbsent(lastIndex, k -> new HashMap<>());
user.put(lastName, p.getValueAsString());
lastIndex = null;
lastName = null;
}
break;
default:
break;
}
p.nextToken();
}
UsersResponse response = new UsersResponse();
response.setUsers(users);
return response;
}
}
I changed a little bit UsersResponse and it looks like below:
#JsonDeserialize(using = UsersResponseDeserializer.class)
class UsersResponse {
private Map<Integer, Map<String, String>> users;
public Map<Integer, Map<String, String>> getUsers() {
return users;
}
public void setUsers(Map<Integer, Map<String, String>> users) {
this.users = users;
}
#Override
public String toString() {
return "UsersResponse{" +
"users=" + users +
'}';
}
}
Example usage:
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.type.CollectionLikeType;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class JsonApp {
public static void main(String[] args) throws Exception {
File jsonFile = new File("path to json").getAbsoluteFile();
ObjectMapper mapper = new ObjectMapper();
UsersResponse data = mapper.readValue(jsonFile, UsersResponse.class);
System.out.println(data);
CollectionLikeType usersListType = mapper.getTypeFactory().constructCollectionLikeType(List.class, User.class);
List<User> users = mapper.convertValue(data.getUsers().values(), usersListType);
System.out.println(users);
}
}
Abobe app for given JSON:
{
"part1.id": "1",
"part1.name": "Name1",
"part2.id": "2",
"part2.name": "Name2",
"part33.id": "33",
"part33.name": "Name33"
}
Prints:
UsersResponse{users={1={name=Name1, id=1}, 2={name=Name2, id=2}, 33={name=Name33, id=33}}}
[User{id='1', name='Name1'}, User{id='2', name='Name2'}, User{id='33', name='Name33'}]
In deserialiser I used Map<Integer, Map<String, String>> because I did not want to play with matching POJO properties and JSON keys.
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!
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"
}