I love how easy it is to map JSON data to a Java object with Jsonb, but I seem to have stumbled upon a not well-documented use-case...
Given this json data:
{
"id": "test",
"points": [
[
-24.787439346313477,
5.5551919937133789
],
[
-23.788913726806641,
6.7245755195617676
],
[
-22.257251739501953,
7.2461895942687988
]
]
}
What can be used as the object type to store the points-values?
import jakarta.json.bind.annotation.JsonbProperty;
public class Temp {
#JsonbProperty("id")
private String id;
#JsonbProperty("points")
private ??? points;
// Getters-Setters
}
So I can create the Temp-object with:
import jakarta.json.bind.Jsonb;
import jakarta.json.bind.JsonbBuilder;
Jsonb jsonb = JsonbBuilder.create();
Temp temp = jsonb.fromJson(jsonString, Temp.class);
So far I've tried the following:
List<Point> --> "Can't deserialize JSON array into: class java.awt.Point"
List<Point2D> --> "Can't deserialize JSON array into: class java.awt.Point2D"
Let's try it:
#Data
public class Temp {
#JsonbProperty("id")
private String id;
#JsonbProperty("points")
private List<List<BigDecimal>> points;
public static void main(String[] args) {
String jsonString = "{\n" +
" \"id\": \"test\",\n" +
" \"points\": [\n" +
" [\n" +
" -24.787439346313477,\n" +
" 5.5551919937133789\n" +
" ],\n" +
" [\n" +
" -23.788913726806641,\n" +
" 6.7245755195617676\n" +
" ],\n" +
" [\n" +
" -22.257251739501953,\n" +
" 7.2461895942687988\n" +
" ]\n" +
" ]\n" +
"}";
Jsonb jsonb = JsonbBuilder.create();
Temp temp = jsonb.fromJson(jsonString, Temp.class);
System.out.println(temp);
}
}
To figure out the default mapping, use a non-generic field and observe it with the debugger:
public class Test {
public static void main(String[] args) {
String json = "{\"id\":\"test\",\"points\":[[-24.787439346313477,5.555191993713379],[-23.78891372680664,6.724575519561768],[-22.257251739501953,7.246189594268799]]}";
Temp temp = JsonbBuilder.create().fromJson(json, Temp.class);
System.out.println(temp.points);
}
public static class Temp {
public String id = null;
public List points = null;
public Temp() {
}
}
}
Since I've already done it: Changing the json format would allow this:
public class Test {
public static void main(String[] args) {
String json = "{\"id\":\"test\",\"points\":[ {\"x\" : 1.0, \"y\" : 2.0 }, {\"x\" : 3.0, \"y\" : 4.0 } ] }";
Temp temp = JsonbBuilder.create().fromJson(json, Temp.class);
System.out.println(temp.points);
}
public static class Temp {
public String id = null;
public List<Point> points = null;
public Temp() { }
}
public static class Point {
public double x;
public double y;
public Point() { }
}
}
I have this JSON String and I need to get each docmanId and each dz so,I could loop through them and work with them.
I have tried using gson library to do that,but I dont seem to figure it out.
JSON Array :
[{"docmanId":1,"dz":"CR"},
{"docmanId":1,"dz":"EU"},
{"docmanId":1,"dz":"JD"},
{"docmanId":1,"dz":"LT"},
{"docmanId":10,"dz":"CR"},
{"docmanId":10,"dz":"EU"},
{"docmanId":10,"dz":"LT"},
{"docmanId":100,"dz":"CR"},
{"docmanId":100,"dz":"EU"},
{"docmanId":100,"dz":"JD"},
{"docmanId":100,"dz":"LT"},
{"docmanId":1000,"dz":"CR"},
{"docmanId":1000,"dz":"EU"},
{"docmanId":1000,"dz":"JD"},
{"docmanId":1000,"dz":"LT"},
{"docmanId":10000,"dz":"ES"},
{"docmanId":10000,"dz":"EU"},
{"docmanId":10000,"dz":"JD"},
{"docmanId":100000,"dz":"CR"},
{"docmanId":100000,"dz":"EU"},
{"docmanId":100000,"dz":"JD"},
{"docmanId":100000,"dz":"LT"},
{"docmanId":100001,"dz":"CR"},
{"docmanId":100001,"dz":"EU"},
{"docmanId":100001,"dz":"LT"},
{"docmanId":100002,"dz":"CR"},
{"docmanId":100002,"dz":"EU"},
{"docmanId":100002,"dz":"JD"},
{"docmanId":100003,"dz":"CR"},
{"docmanId":100003,"dz":"EU"},
{"docmanId":100003,"dz":"JD"},
{"docmanId":100003,"dz":"LT"},
{"docmanId":100004,"dz":"CR"},
{"docmanId":100004,"dz":"EU"},
{"docmanId":100004,"dz":"JD"},
{"docmanId":100005,"dz":"CR"},
{"docmanId":100005,"dz":"EU"},
{"docmanId":100005,"dz":"JD"},
{"docmanId":100005,"dz":"LT"},
{"docmanId":100006,"dz":"CR"},
{"docmanId":100006,"dz":"EU"},
{"docmanId":100006,"dz":"JD"},
{"docmanId":100006,"dz":"LT"},
{"docmanId":100007,"dz":"CR"},
{"docmanId":100007,"dz":"EU"},
{"docmanId":100007,"dz":"JD"}]
With org.json ,
JSONArray jSONArray = new JSONArray("your input array");
int length = jSONArray.length();
for (int i = 0; i < length; i++) {
JSONObject jSONObject= jSONArray.getJSONObject(i);
System.out.println(jSONObject.get("docmanId"));
System.out.println(jSONObject.get("dz"));
}
with jackson
String json = "[{\"docmanId\":1,\"dz\":\"CR\"},\n" +
"{\"docmanId\":1,\"dz\":\"EU\"},\n" +
"{\"docmanId\":1,\"dz\":\"JD\"},\n" +
"{\"docmanId\":1,\"dz\":\"LT\"},\n" +
"{\"docmanId\":10,\"dz\":\"CR\"},\n" +
"{\"docmanId\":10,\"dz\":\"EU\"},\n" +
"{\"docmanId\":10,\"dz\":\"LT\"},\n" +
"{\"docmanId\":100,\"dz\":\"CR\"},\n" +
"{\"docmanId\":100,\"dz\":\"EU\"},\n" +
"{\"docmanId\":100,\"dz\":\"JD\"},\n" +
"{\"docmanId\":100,\"dz\":\"LT\"},\n" +
"{\"docmanId\":1000,\"dz\":\"CR\"},\n" +
"{\"docmanId\":1000,\"dz\":\"EU\"},\n" +
"{\"docmanId\":1000,\"dz\":\"JD\"},\n" +
"{\"docmanId\":1000,\"dz\":\"LT\"},\n" +
"{\"docmanId\":10000,\"dz\":\"ES\"},\n" +
"{\"docmanId\":10000,\"dz\":\"EU\"},\n" +
"{\"docmanId\":10000,\"dz\":\"JD\"},\n" +
"{\"docmanId\":100000,\"dz\":\"CR\"},\n" +
"{\"docmanId\":100000,\"dz\":\"EU\"},\n" +
"{\"docmanId\":100000,\"dz\":\"JD\"},\n" +
"{\"docmanId\":100000,\"dz\":\"LT\"},\n" +
"{\"docmanId\":100001,\"dz\":\"CR\"},\n" +
"{\"docmanId\":100001,\"dz\":\"EU\"},\n" +
"{\"docmanId\":100001,\"dz\":\"LT\"},\n" +
"{\"docmanId\":100002,\"dz\":\"CR\"},\n" +
"{\"docmanId\":100002,\"dz\":\"EU\"},\n" +
"{\"docmanId\":100002,\"dz\":\"JD\"},\n" +
"{\"docmanId\":100003,\"dz\":\"CR\"},\n" +
"{\"docmanId\":100003,\"dz\":\"EU\"},\n" +
"{\"docmanId\":100003,\"dz\":\"JD\"},\n" +
"{\"docmanId\":100003,\"dz\":\"LT\"},\n" +
"{\"docmanId\":100004,\"dz\":\"CR\"},\n" +
"{\"docmanId\":100004,\"dz\":\"EU\"},\n" +
"{\"docmanId\":100004,\"dz\":\"JD\"},\n" +
"{\"docmanId\":100005,\"dz\":\"CR\"},\n" +
"{\"docmanId\":100005,\"dz\":\"EU\"},\n" +
"{\"docmanId\":100005,\"dz\":\"JD\"},\n" +
"{\"docmanId\":100005,\"dz\":\"LT\"},\n" +
"{\"docmanId\":100006,\"dz\":\"CR\"},\n" +
"{\"docmanId\":100006,\"dz\":\"EU\"},\n" +
"{\"docmanId\":100006,\"dz\":\"JD\"},\n" +
"{\"docmanId\":100006,\"dz\":\"LT\"},\n" +
"{\"docmanId\":100007,\"dz\":\"CR\"},\n" +
"{\"docmanId\":100007,\"dz\":\"EU\"},\n" +
"{\"docmanId\":100007,\"dz\":\"JD\"}]";
ObjectMapper objectMapper = new ObjectMapper();
DocmanList docmanList = objectMapper.readValue(json, DocmanList.class);
//logic below
}
public class Docman {
private long docmanId;
private String dz;
public long getDocmanId() {
return docmanId;
}
public void setDocmanId(long docmanId) {
this.docmanId = docmanId;
}
public String getDz() {
return dz;
}
public void setDz(String dz) {
this.dz = dz;
}
}
public class DocmanList extends ArrayList<Docman> {
}
you can do it by generating a class convert it in java object of list.
first generate a class
-----------------------------------com.example.Example.java-----------------------------------
package com.example;
import java.io.Serializable;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.lang.builder.HashCodeBuilder;
import org.apache.commons.lang.builder.ToStringBuilder;
public class Example implements Serializable
{
#SerializedName("docmanId")
#Expose
private long docmanId;
#SerializedName("dz")
#Expose
private String dz;
private final static long serialVersionUID = 3195470113916852896L;
/**
* No args constructor for use in serialization
*
*/
public Example() {
}
/**
*
* #param docmanId
* #param dz
*/
public Example(long docmanId, String dz) {
super();
this.docmanId = docmanId;
this.dz = dz;
}
public long getDocmanId() {
return docmanId;
}
public void setDocmanId(long docmanId) {
this.docmanId = docmanId;
}
public Example withDocmanId(long docmanId) {
this.docmanId = docmanId;
return this;
}
public String getDz() {
return dz;
}
public void setDz(String dz) {
this.dz = dz;
}
public Example withDz(String dz) {
this.dz = dz;
return this;
}
#Override
public String toString() {
return new ToStringBuilder(this).append("docmanId", docmanId).append("dz", dz).toString();
}
#Override
public int hashCode() {
return new HashCodeBuilder().append(docmanId).append(dz).toHashCode();
}
#Override
public boolean equals(Object other) {
if (other == this) {
return true;
}
if ((other instanceof Example) == false) {
return false;
}
Example rhs = ((Example) other);
return new EqualsBuilder().append(docmanId, rhs.docmanId).append(dz, rhs.dz).isEquals();
}
}
Now Tell it to parse a List (of Welcome) instead. Since List is generic you will typically use a **TypeReference**
List<Welcome> participantJsonList = mapper.readValue(jsonString, new TypeReference<List<Welcome>>(){});
use http://www.jsonschema2pojo.org/ to convert your json to java class.
You could parse it using JsonPath :
static String json = "...";
public static void main(String[] args) {
String pageName = JsonPath.read(json, "$.pageInfo.pageName");
System.out.println(pageName);
Integer posts = JsonPath.read(json, "$.posts.length()");
for(int i=0; i < posts; i++) {
String post_id = JsonPath.read(json, "$.posts[" + i + "].post_id");
System.out.println(post_id);
}
}
I have JSON something lie that:
String json = "{'zadanie' : { "+
"'lista' : {" +
"'img': 'something.jpg'," +
"'opis': 'Prawdziwy minionek'," +
"'cena': 117.00," +
"'ilosc': 12," +
"'baza': ['truskawka - wanilia', 'sernik - pomarańcza', 'jagoda - wanilia', 'żurawina - wanilia', 'czekolada - wanilia', 'czekolada - banan', 'czekolada - cappuccino', 'tiramisu']," +
"'czas': '2 dni'"+
"}"+
"',lista2' : {" +
"'img': 'something2.jpg'," +
"'opis': 'Prawdziwy minionek'," +
"'cena': 117.00," +
"'ilosc': 12," +
"'baza': ['truskawka - wanilia', 'sernik - pomarańcza', 'jagoda - wanilia', 'żurawina - wanilia', 'czekolada - wanilia', 'czekolada - banan', 'czekolada - cappuccino', 'tiramisu']," +
"'czas': '2 dni'"+
"}"+
"]}}";
And I would like to parse it to object in Java. I have classes:
class Lista2{
private List<Lista> lista2;
public List<Lista> getLista2() {
return lista2;
}
public void setLista2(List<Lista> lista2) {
this.lista2 = lista2;
}
#Override
public String toString() {
return "GroupList{" + "lista2=" + lista2 + '}';
}}
//=================================================
class Lista {
private Data lista;
public Data getLista() {
return lista;
}
public void setLista(Data lista) {
this.lista = lista;
}
#Override
public String toString() {
return "Lista{" + "lista=" + lista + '}';
}}
//=================================================
class Data {
private String img;
private String opis;
private Double cena;
private Integer ilosc;
private List<String> baza;
private String czas;
public String getImg() {
return img;
}
public void setImg(String img) {
this.img = img;
}
public String getOpis() {
return opis;
}
public void setOpis(String opis) {
this.opis = opis;
}
public Double getCena() {
return cena;
}
public void setCena(Double cena) {
this.cena = cena;
}
public Integer getIlosc() {
return ilosc;
}
public void setIlosc(Integer ilosc) {
this.ilosc = ilosc;
}
public List<String> getBaza() {
return baza;
}
public void setBaza(List<String> baza) {
this.baza = baza;
}
public String getCzas() {
return czas;
}
public void setCzas(String czas) {
this.czas = czas;
}
#Override
public String toString() {
return "Data{" + "img=" + img + ", opis=" + opis + ", cena=" + cena + ", ilosc=" + ilosc + ", baza=" + baza + ", czas=" + czas + '}';
} }
Something is wrong, because I have error: "StandardWrapperValve[Glowna]: Servlet.service() for servlet Glowna threw exception
com.google.gson.JsonSyntaxException: com.google.gson.stream.MalformedJsonException: Unterminated object at line 1 column 360
at com.google.gson.Gson.fromJson(Gson.java:809)"
For GSON parse:
Gson gson = new Gson();
JsonReader reader = new JsonReader(new StringReader(json));
reader.setLenient(true);
Lista2 userinfo1 = gson.fromJson(reader, Lista2.class);
I am trying to read JSON string using gson into a Java program. In the sample code below - the Java program has 3 object classes. The data in the json string will have a variable number of object instances of each class. I have tried to create a sample JSON - to parse .. but had problems parsing the various objects.
Is this the right way to consume a json string or can it be done in a different way.. How would you parse a json with variable objects of different classes. Thanks,
package newpackage;
import java.util.ArrayList;
import com.google.gson.Gson;
public class jsonsample {
public static void main(String[] args) {
String jsonstring = "{'TableA':[{'field_A1':'A_11'},{'field_A1':'A_12'}]}"
+ ",{'TableB':[{'field_B1':'B_11','field_B2':'B_12','field_B3':['abc','def','ghi']},"
+ "{'field_B1':'B_21','field_B2':'B_Field22','field_B3':['mno','pqr','xyz']}]"
+ ",{'TableC':[{'field_C1':'C_11','field_C2':'C_12','field_C3':'C_13'},"
+ "{'field_C1':'C_21','field_C2':'C_22','field_C3':'C_23'},{'field_C1':'C_31','field_C2':'C_32','field_C3':'C_33'}]}";
jsonstring = jsonstring.replace('\'', '"');
}
public class TableA {
String field_A1;
public TableA(String a){
this.field_A1 = a;
}
#Override
public String toString() {
return ("Table A" + " " + this.field_A1);
}
}
public class TableB {
String field_B1;
String field_B2;
ArrayList<String> field_B3 = new ArrayList<String>();
public TableB(String a, String b, ArrayList<String> c){
this.field_B1 = a;
this.field_B2 = b;
this.field_B3 = c;
}
#Override
public String toString() {
return ("Table B" + " " + this.field_B1+ " " + this.field_B2);
}
}
public class TableC {
String field_C1;
String field_C2;
String field_C3;
public TableC(String a, String b, String c){
this.field_C1 = a;
this.field_C2 = b;
this.field_C3 = c;
}
#Override
public String toString() {
return ("Table C" + " " + this.field_C1 + " " + this.field_C2 + " " + this.field_C3);
}
}
}
First of all you have to decide what is your base json structure ? Max identifiers, max values, max objects,max arrays...
Create your full json structure with texteditor or http://www.jsoneditoronline.org/ or http://jsonlint.com/ etc.
Let's think this is my full json structure:
{
"array": [
1,
2,
3
],
"boolean": true,
"null": null,
"number": 123,
"object": {
"a": "b",
"c": "d",
"e": "f"
},
"string": "Hello World"
}
Create your Java Classes as like as your json identifiers. You can use http://json2csharp.com/ convert to Java.
And these are my Java Classes:
public class Object
{
public string a { get; set; }
public string c { get; set; }
public string e { get; set; }
}
public class RootObject
{
public ArrayList<int> array { get; set; }
public Boolean boolean { get; set; }
public Object #null { get; set; }
public int number { get; set; }
public Object #object { get; set; }
public string #string { get; set; }
}
Create your DAO for convert these to structure to them.
For Java;
String data = "jsonString";
RootObject root = new GsonBuilder().create().fromJson(data, RootObject.class);
For Json;
Gson gson = new GsonBuilder().setDateFormat("dd/MM/yyyy").create();
String json = gson.toJson(obj);
Your JSON-string seems incorrect to me. Let me propose the following:
public static void main(String args[]) {
String jsonstring = "["
+ "{'TableA':[{'field_A1':'A_11'},{'field_A1':'A_12'}]}"
+ ",{'TableB':[{'field_B1':'B_11','field_B2':'B_12','field_B3':['abc','def','ghi']},"
+ "{'field_B1':'B_21','field_B2':'B_Field22','field_B3':['mno','pqr','xyz']}]}"
+ ",{'TableC':[{'field_C1':'C_11','field_C2':'C_12','field_C3':'C_13'},"
+ "{'field_C1':'C_21','field_C2':'C_22','field_C3':'C_23'},{'field_C1':'C_31','field_C2':'C_32','field_C3':'C_33'}]}"
+ "]";
jsonstring = jsonstring.replace('\'', '"');
Gson gson = new Gson();
JsonParser parser = new JsonParser();
JsonArray array = parser.parse(jsonstring).getAsJsonArray();
for (JsonElement jsonElement : array) {
JsonObject jsonObject = jsonElement.getAsJsonObject();
Map.Entry<String,JsonElement> table = jsonObject.entrySet().iterator().next();
String tableName = table.getKey();
JsonElement rows = table.getValue();
try {
Class<?> rowClass = Class.forName("[Lnewpackage." + tableName + ";"); // explanation see below this code snippet
// rowClass is an array class!
Object[] parsedRows = gson.fromJson(rows, rowClass);
// do something with parsedRows
for (Object x : parsedRows) {
System.out.println(x);
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
Assuming a "table definition" consists of a property named as the class ob the objects in the table, with the objects as array value of that property.
Explanation of Class.forName("[Lnewpackage." + tableName + ";")
This retrieves the Class instance for the array type of a class located in the package newpackage, e.g. newpackage.TableA[] (note the []). Class.forName("A") returns the instance representing the class A. Class.forName("[LA;") returns the instance representing the "class" of an array of As. Using it as a parameter for fromJson(...) it results in the parsing of a JSON array of A-objects.
This is the code - that works based on #hurricane suggestion.
package newpackage;
import java.util.List;
import com.google.gson.*;
public class jsonsample {
public static void main(String[] args) throws ClassNotFoundException {
String jsonstring = "{'TableA':["
+ "{'field_A1':'A_11'},"
+ "{'field_A1':'A_12'}"
+ "],"
+ "'TableB':["
+ "{'field_B1':'B_11','field_B2':'B_12','field_B3':['abc','def']},"
+ "{'field_B1':'B_21','field_B2':'B_22','field_B3':['mno','xyz']}"
+ "],"
+ "'TableC':["
+ "{'field_C1':'C_11','field_C2':'C_12','field_C3':'C_13'},"
+ "{'field_C1':'C_21','field_C2':'C_22','field_C3':'C_23'}"
+ "]}";
jsonstring = jsonstring.replace('\'', '"');
RootObject root = new GsonBuilder().create().fromJson(jsonstring, RootObject.class);
for (int i=0; i < root.TableA.size(); i++){
System.out.println(root.TableA.get(i));
}
for (int i=0; i < root.TableB.size(); i++){
System.out.println(root.TableB.get(i));
}
for (int i=0; i < root.TableC.size(); i++){
System.out.println(root.TableC.get(i));
}
}
public class TableA
{
public String field_A1;
#Override
public String toString() {
return ("Table A" + " " + this.field_A1);
}
}
public class TableB{
public String field_B1;
public String field_B2;
public List<String> field_B3;
#Override
public String toString() {
return ("Table B" + " " + this.field_B1 + " " + this.field_B2 + " " + this.field_B3);
}
}
public class TableC{
public String field_C1;
public String field_C2;
public String field_C3;
#Override
public String toString() {
return ("Table C" + " " + this.field_C1 + " " + this.field_C2 + " " + this.field_C3);
}
}
public class RootObject{
public List<TableA> TableA;
public List<TableB> TableB;
public List<TableC> TableC;
}
}
The output for the above is:
Table A A_11
Table A A_12
Table B B_11 B_12 [abc, def]
Table B B_21 B_22 [mno, xyz]
Table C C_11 C_12 C_13
Table C C_21 C_22 C_23
I'm having a little trouble working out an appropriate java object structure for the following JSON data:
"pages": {
"181382": {
"pageid": 181382,
"ns": 0,
"title": "Anonymity"
},
"7181837": {
"pageid": 7181837,
"ns": 0,
"title": "Anonymous"
}
}
The identifiers "181382" and "7181837" change depending on the data returned so these cannot be used as a member on an object. I tried to approach it using a Map<String, Object> approach but got a little stuck.
Edit:
This is what I've tried
public class PageData {
int pageid;
String ns;
String title;
public int getPageid() {
return pageid;
}
public String getNs() {
return ns;
}
public String getTitle() {
return title;
}
}
Map<String, PageData> pages = results.getPages().getData();
for (PageData data : pages.values()) {
System.out.println(data.getTitle());
}
Just create some wrapper for your Object. Here is working example:
Wrapper
public class Wrapper {
Map<String, PageData> pages = null;
public Map<String, PageData> getPages() {
return pages;
}
}
Launcher
public class Launcher {
public static void main(String[] args) {
String str = "{\"pages\": {\r\n" +
" \"181382\": {\r\n" +
" \"pageid\": 181382,\r\n" +
" \"ns\": 0,\r\n" +
" \"title\": \"Anonymity\"\r\n" +
" },\r\n" +
" \"7181837\": {\r\n" +
" \"pageid\": 7181837,\r\n" +
" \"ns\": 0,\r\n" +
" \"title\": \"Anonymous\"\r\n" +
" }\r\n" +
" }" +
"}";
Gson gson = new Gson();
Wrapper results = gson.fromJson(str, Wrapper.class);
Map<String, PageData> pages = results.getPages();
for (PageData data : pages.values()) {
System.out.println(data.getTitle());
}
}
}
PageData
public class PageData{/* the same */}
Output:
Anonymity
Anonymous