I'm having a little trouble trying to convert a JSON string from a serialized HTML form to a Java class using Gson.
Here's the example JSON:
[
{ "name" : "ObjectClass", "value" : "Obama" },
{ "name" : "ObjectType", "value" : "Person" },
{ "name" : "Att_1_name", "value" : "Age" },
{ "name" : "Att_1_value", "value" : "52" },
{ "name" : "Att_2_name", "value" : "Race" },
{ "name" : "Att_2_name", "value" : "African American" }
]
As you can see, it passes an array, then each element of that array consists of a name and a value.
I'm somewhat lost on how to set up my Java class so that Gson can convert it. It should also be noted that the number of elements in the array is variable (there can be as many attributes as the user desires).
My (incorrect) attempt at the class was:
package com.test.objectclasses;
import java.util.ArrayList;
public class tempJSON {
ArrayList<innerJSON> inJSON;
public ArrayList<innerJSON> getInJSON() {
return inJSON;
}
public void setInJSON(ArrayList<innerJSON> inJSON) {
this.inJSON = inJSON;
}
public class innerJSON {
private String name;
private String value;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
}
}
Any idea how to approach this, or am I thinking about it all wrong? Thanks in advance.
First of all, follow Java naming conventions. Your class names should start with a capital letter. So upper camel case.
Get rid of your enclosing class, tempJSON and use a type token in the Gson#fromJson(..) to mark it as a List, since you have a JSON array.
List<innerJSON> innerJSONs = gson.fromJson(yourStream, new TypeToken<List<innerJSON>>(){}.getType());
Now the List will contain as many innerJSON objects as appear in your JSON.
Related
I need to create a model in Java to deseralize such JSON.
[
{
"yyy": {
"address": "y-a",
"acronym": "YYY"
},
"xxx": {
"address": "x-a",
"acronym": "XXX"
}
},
{
"vvv": {
"address": "v-a",
"acronym": "VVV"
}
}
]
It looks for me that a model in Java will look like here (i'm using Jackson)
public class Yyy{
public String address;
public String acronym;
}
public class Xxx{
public String address;
public String acronym;
}
public class Vvv{
public String address;
public String acronym;
}
public class Root{
public Yyy yyy;
public Xxx xxx;
public Vvv vvv;
}
It is not acceptable at all because I don't know which keys like xxx, yyy, vvv I will get -
They are not defined and can be random. What I need to do to convert this JSON to have something usefull? I mean to have an array of objects and in inside object a map where keys will be created from keys in JSON (vvv, yyy, xxx)
I have a Java list representation like below
List representation of data
[
{ "type" : "Error", "name" : "xyz" },
{ "type" : "Success", "name" : "abc" },
{ "type" : "none", "name" : "prq" },
{ "type" : "Success", "name" : "" },
{ "type" : "Success", "name" : "xyz" },
{ "type" : "Warning", "name" : "efc" }
.
.
.
]
(Partial representation here).
and an Object representation below
public Node {
List<String> errorNames;
List<String> SuccessNames;
List<String> WarningNames;
}
I want to use Java streams to separate the three type of names based on their type and add each name to the respective Lists.
What will be the best way (Stream.filter/Collect/Map anything else) to split the list such that at the end "Node's->(all the lists)" will have corresponding data?
Assuming your Node class actually looks something like this:
public class Node {
private String type;
private String name;
public Node(String type, String name) {
this.type = type;
this.name = name;
}
public String getType() {
return type;
}
public String getName() {
return name;
}
}
You can use Collectors#groupingBy in combination with Collectors#mapping to create a Map<String, List<String>> where they key is the type and the value are the List of name for every Node of that type:
var nodes = List.of(
new Node("Error", "xyz"), new Node("Success", "abc"),
new Node("none", "prq"), new Node("Success", ""),
new Node("Success", "xyz"), new Node("Warning", "efc")
);
var map = nodes.stream()
.collect(Collectors.groupingBy(Node::getType,
Collectors.mapping(Node::getName, Collectors.toList())));
System.out.println(map);
Output:
{Warning=[efc], Error=[xyz], none=[prq], Success=[abc, , xyz]}
I'm having trouble getting my objects to sort.
Some initial knowledge:
I'm using MongoDB to store my collection, I'm able to retrieve them and get everything back correctly.
I have a class that implements Comparable, with a compareTo function, but I also want to be able to sort on different properties, thus I've added static comparables for each property I want to sort on.
public class PlaceHolder implements Comparable<PlaceHolder>{
private String name;
private String icon;
private String originalLangcode;
//Getters and setters + constructors here, these work 100%.
#Override
public int compareTo(PlaceHolder ph) {
return this.getName().compareTo(ph.getName());
}
public static Comparator<PlaceHolder> nameComparator = new Comparator<PlaceHolder>() {
#Override
public int compare(PlaceHolder ph1, PlaceHolder ph2) {
return ph1.getName().compareTo(ph2.getName());
}
};
public static Comparator<PlaceHolder> iconComparator = new Comparator<PlaceHolder>() {
#Override
public int compare(PlaceHolder ph1, PlaceHolder ph2) {
return ph1.getIcon().compareTo(ph2.getIcon());
}
};
public static Comparator<PlaceHolder> nativeLangComparator = new Comparator<PlaceHolder>() {
#Override
public int compare(PlaceHolder ph1, PlaceHolder ph2) {
return ph1.getNativeLang().compareTo(ph2.getNativeLang());
}
};
}
I've then wrote a function that gets all placeholders from my mongodb, returning them in a list with PlaceHolder objects.
public List<PlaceHolder> getAllPlaceholders(String sortType) {
List<PlaceHolder> list = getPlaceholderList();
switch(sortType) {
case "name":
Collections.sort(list, PlaceHolder.nameComparator);
break;
case "icon":
Collections.sort(list, PlaceHolder.iconComparator);
break;
case "native":
Collections.sort(list, PlaceHolder.nativeLangComparator);
break;
default:
Collections.sort(list, PlaceHolder.nameComparator);
break;
}
return list;
}
I always get my data unsorted:
{ "_id" : { "$oid" : "56653f82972552a4024814a3"} , "name" : "testHolder" , "icon" : "archive" , "originalLangcode" : "ENG"}
{ "_id" : { "$oid" : "5665427a97253f798067c57b"} , "name" : "doItHolder" , "icon" : "car" , "originalLangcode" : "ENG"}
{ "_id" : { "$oid" : "566545dd9725050a53b4a5a8"} , "name" : "testableHolder" , "icon" : "adjust" , "originalLangcode" : "ENG"}
{ "_id" : { "$oid" : "5665479b972511264f55aae1"} , "name" : "dataHolder" , "icon" : "hdd-o" , "originalLangcode" : "ENG"}
I'm failing to see what goes wrong.
I've debugged the comparables, and they seem to work, returning negatives and positives. But the list just doesnt seem to get sorted.
I'm using getAllPlaceholders in my controller, passing it to my Page handler which in turn generates html for a table view.
public class PlaceHolderControllerF extends ControllerAbF {
#Autowired PlaceHolderRepo pr;
#RequestMapping(value = "placeholderlist", method = RequestMethod.GET)
#ResponseBody
public String editLanguage(HttpSession httpSession) {
if (getUser(httpSession) == null) {
return noPermission();
}
return Pages.getPlaceHolderList(pr.getAllPlaceholders("name"));
}
Pages just gets my index html, passes some variables to it that then runs through my templater which fills in the variables into the html.
Is there a standard or existing way to generate 'something' from an uncompiled java class based on its contents? So basically something like this:
#MakeJsonDocumentation
public class ExistingClass{
private name = "";
public ExistingClass(String name){
this.name = name;
}
#JsonField
public String getName(){
return this.name;
}
#JsonField
public void setName(String name){
this.name = name;
}
#JsonMethod
public void someMethod(String text){
System.out.println("someMethod " + text)
}
#JsonMethod
public void otherMethod(){
System.out.println("otherMethod")
}
}
into something like this
{
"ExistingClass": {
"Fields": {
"Name": "String"
},
"Methods": {
"someMethod": {
"Parameters": {
"Type": "String",
"Name": "text"
},
"Returns": "Nothing"
},
"otherMethod": {
"Parameters": "Nothing",
"Returns": {
"Type": "String"
}
}
}
}
}
And if there isn't, is it possible to do this with compile-time annotations because I'd like to automate the generation instead of having to write a parser and everytime I change something about a class throw it through the parser in order to get an up-to-date datasheet.
I'm kind of in the dark here, I only know what I want but no idea how to accomplish it, so at very least some search-keywords into the right direction would be very welcome :p
To achieve Json you posted above you can by:
use reflection to extract all fields names and methods
use JSONObject (json parser/builder)
from an uncompiled java class
However, reflection works with instances (or all fields/methods must be static)
How about this?
https://jersey.java.net/documentation/1.17/json.html
Here's an older post that might help as well: Json - Java Object to Json
Cheers
.t.
When the JSON is:
{
"result":200,
"data", "my data"
}
The definition of the class can be:
class HttpResult
{
#Key
public int result;
#Key
public String data;
}
When the JSON root is a array and has no Key:
[
{
"result:200",
"data":"data1"
},
{
"result":404,
"data":"data2"
}
]
Then the definition of the class is?
Same class definition, it's just a Collection of them instead of one.