Response required
{
"data" : [[1234, 55],[1264,45],[1334, 56]]
}
Model
Class Timeseries{
private List<List<Integer>> data;
}
I don't feel List of List is appropriate to achive the json response required.. But I am unable to replace it with List, where CustomObject will contain 2 integer member variables. As it will change the format of the response and send the response as data containing list of objects of type CustomObject instead of list of list..
Please suggest an alternate approch
The easiest way to reach your needed output is
class data extends ArrayList<List<Integer>> {
}
and use this code for serilization with Jackson JSON
data ts = new data();
ts.addAll(Arrays.asList(Arrays.asList(1234, 55), Arrays.asList(1264, 45), Arrays.asList(1334, 56)));
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.enable(SerializationFeature.WRAP_ROOT_VALUE);
String result = objectMapper.writeValueAsString(ts);
System.out.println(result);
The output string will be as you need {"data":[[1234,55],[1264,45],[1334,56]]}
But, seriously, the right way here is to implement for
class Timeseries {
private List<List<Integer>> data;
}
your own com.fasterxml.jackson.databind.ser.std.StdSerializer<T> successor for Timeseries class.
UPDATE:
Just find out the easiest way to reach your needed string for class
class Timeseries {
public List<List<Integer>> data;
}
Note data field has to be either public or have a getter.
And then code
Timeseries ts = new Timeseries();
ts.data = Arrays.asList(Arrays.asList(1234, 55), Arrays.asList(1264, 45), Arrays.asList(1334, 56));
ObjectMapper objectMapper = new ObjectMapper();
String result = objectMapper.writeValueAsString(ts);
System.out.println(result);
will print {"data":[[1234,55],[1264,45],[1334,56]]}
You can try like this,
class CustomObject {
private int data1;
private int data2;
// getters & setters
}
Then you can modify your Timeseries as below,
private List<CustomObject> data;
You can use a list of Arrays of size 2.
Related
My json file looks like this [actually it has more, I am just putting 2 blocks for example]
[{
"answerValue": "2021-02-01",
"parentId": "Policy",
"instance": 1,
"fieldId": "PolicyEffectiveDate"
},
{
"answerValue": "2012",
"parentId": "Insured",
"instance": 1,
"fieldId": "DateBusinessStarted"
}
]
I want to store them in a HashMap and print them.
public void MapCheck() {
Map<String, Object> dataMap = new HashMap<>();
List<Map> lstMap = new ArrayList<>();
dataMap.put("answerValue:", "2021-02-01");
dataMap.put("parentId:", "Policy");
dataMap.put("instance:", 1);
dataMap.put("fieldId:", "PolicyEffectiveDate");
lstMap.add(dataMap);
dataMap.put("answerValue:", "Assurestart LLC");
dataMap.put("parentId:", "Insured");
dataMap.put("instance:", 1);
dataMap.put("fieldId:", "Business_Name");
lstMap.add(dataMap);
System.out.println(lstMap);
}
public static void main(String[] args) {
Test t = new Test();
t.MapCheck();
}
}
Expected: I wanted it to print
[{parentId:=Policy, fieldId:=PolicyEffectiveDate, answerValue:=2021-02-01, instance:=1}, {parentId:=Insured, fieldId:=Business_Name, answerValue:=Assurestart LLC, instance:=1}]
Actual: It is printing, the last value twice.
[{parentId:=Insured, fieldId:=Business_Name, answerValue:=Assurestart LLC, instance:=1}, {parentId:=Insured, fieldId:=Business_Name, answerValue:=Assurestart LLC, instance:=1}]
How can I make it print 2 different values? Thanks in advance for your time and ideas.
You should create a new map for the second entry instead of overwriting the first entry’s values. Add
dataMap = new HashMap<>();
After adding the first entry to the list.
You should create a new map for the second map in the list:
Map<String, Object> dataMap = new HashMap<>();
List<Map<String, Object>> lstMap = new ArrayList<>();
dataMap.put("answerValue:", "2021-02-01");
dataMap.put("parentId:", "Policy");
dataMap.put("instance:", 1);
dataMap.put("fieldId:", "PolicyEffectiveDate");
lstMap.add(dataMap);
dataMap = new HashMap<>(); // create a new map!
dataMap.put("answerValue:", "Assurestart LLC");
dataMap.put("parentId:", "Insured");
dataMap.put("instance:", 1);
dataMap.put("fieldId:", "Business_Name");
lstMap.add(dataMap);
That said, if you actually want to generate JSON, or read a JSON file, I recommend using a JSON serialisation/deserialisation library, such as GSON. That way, you can represent your data not as hash maps, but a class like this:
class MyObject {
private String answerValue;
private String parentId;
private int instance;
private String fieldId;
// getters & setters...
}
HashMap as you know is a data structure that works based on unique key and value pair property.
In the example above when you perform dataMap.put("answerValue:", "2021-02-01"); it saves the value for this key in the HashMap. However when you perform, dataMap.put("answerValue:", "Assurestart LLC"); the second time, it will override the value of "answerValue:" key as it already exists there.
A better approach is to create a new class that can contain all this data in it and then you can decide on a unique key to store this data in. Thus your values will be an object that contains this entire block of data.
For example,
public class MyData {
private String answerValue;
private String parentId;
private Integer instance;
private String fieldId;
//Setters and getters
...
}
I want make json
records":[ {"MON_PRIORITY":"","MON_ICR_ACCNO":"100000010010","MON_REPORT_DATE":"","MON_STATUS":"",
But my json is
{"MON_PRIORITY":"","MON_ICR_ACCNO":"100000010010","MON_REPORT_DATE":"","MON_STATUS":"",
My jsp code is
HashMap jsonRecordval = (HashMap) hshValues.get("jsonRecord");
String json="";
json = new Gson().toJson(jsonRecordval );
Thanks..
What you're getting is the JSON produced by a Hashmap. e.g. {"key":"value"}. Breaking it down piece by what, your desired json is a representation of an object { with a records field "records" that contains an array [ of the contents of your hashmap {"key":"value"}
To do that, it's easiest to create an object with instance variables corresponding to the fields to expected output. Something like
public class JsonRecords {
private final List<HashMap> records = new ArrayList<>;
public JsonRecords(HashMap recordsVal) {
records.add(recordsVal);
}
//Getters and setters
}
Then use it to build your JSON
HashMap jsonRecordval = (HashMap) hshValues.get("jsonRecord");
String json = new Gson().toJson(new JsonRecords(jsonRecordval));
I need to create constant json string or a json sorted on keys. What do I mean by constant json string? Please look into following code sample, which I created.
My Code 1:
public class GsonTest
{
class DataObject {
private int data1 = 100;
private String data2 = "hello";
}
public static void main(String[] args)
{
GsonTest obj=new GsonTest();
DataObject obj2 = obj.new DataObject();
Gson gson = new Gson();
String json = gson.toJson(obj2);
System.out.println(json);
}
}
Output 1:
{"data1":100,"data2":"hello"}
My Code 2:
public class GsonTest
{
class DataObject {
private String data2 = "hello";
private int data1 = 100;
}
public static void main(String[] args)
{
GsonTest obj=new GsonTest();
DataObject obj2 = obj.new DataObject();
Gson gson = new Gson();
String json = gson.toJson(obj2);
System.out.println(json);
}
}
Output 2:
{"data2":"hello","data1":100}
If you see, if I switch variables (data1 & data2 in DataObject class), I get different json. My objective to get same json, even if somebody changes position of the class variables. I get it when somebody adds new variables, json would change. But json shouldn't change when variables are moved around. So, my objective is to get standard json, possibly in sorted keys order for same class. If there is nested json, then it should be sorted in the nested structure.
Expected output on run of both the codes:
{"data1":100,"data2":"hello"} //sorted on keys!! Here keys are data1 & data2
I understand, I need to change something in String json = gson.toJson(obj2); line, but what do I have to do?
Why I need them to be order?
I need to encode the json string and then pass it to another function. If I change the order of keys, even though value remain intact, the encoded value will change. I want to avoid that.
First of all, the keys of a json object are unordered by definition, see http://json.org/.
If you merely want a json string with ordered keys, you can try deserializing your json into a sorted map, and then serialize the map in order to get the sorted-by-key json string.
GsonTest obj=new GsonTest();
DataObject obj2 = new DataObject();
Gson gson = new Gson();
String json = gson.toJson(obj2);
TreeMap<String, Object> map = gson.fromJson(json, TreeMap.class);
String sortedJson = gson.toJson(map);
Like others have mentioned that by design JSON is not supposed to have sorted keys in itself. You can also come up with a recursive solution to do it. I won't say my solution is very efficient but it does the intended job. Please have a look at the following piece of code.
private static JsonObject sortAndGet(JsonObject jsonObject) {
List<String> keySet = jsonObject.keySet().stream().sorted().collect(Collectors.toList());
JsonObject temp = new JsonObject();
for (String key : keySet) {
JsonElement ele = jsonObject.get(key);
if (ele.isJsonObject()) {
ele = sortAndGet(ele.getAsJsonObject());
temp.add(key, ele);
} else if (ele.isJsonArray()) {
temp.add(key, ele.getAsJsonArray());
} else
temp.add(key, ele.getAsJsonPrimitive());
}
return temp;
}
Input:
{"c":"dhoni","a":"mahendra","b":"singh","d":{"c":"tendulkar","b":"ramesh","a":"sachin"}}
Output:
{"a":"mahendra","b":"singh","c":"dhoni","d":{"a":"sachin","b":"ramesh","c":"tendulkar"}}
Perhaps a work around is for your class wrap a TreeMap which maintains sort order of the keys. You can add getters and setters for convenience. When you gson the TreeMap, you'll get ordered keys.
I want to create an inline list in XML. Something like this:
<numbers>
<phone>1234</phone>
<phone>5678</phone>
<phone>3456</phone>
</numbers>
The tutorial here highlights how it can be done.
Now, I have no idea about how to deal with
public Order(#Attribute(name="name") String name,
#Element(name="product") String product)
or
public OrderManager(#ElementList(name="orders") List<Order> orders) {
this.orders = orders;
}
I have never worked with lists in Java.
My case:
A database, upon querying, will fill up an array phone_numbers[x]. How am I supposed to generate the XML file like above using the values in the array and Constructor Injection?
Suppose you had a class PhoneNumbers like so:
#Root
public class PhoneNumbers {
#ElementArray(name="numbers", entry = "phone")
private String[] phones;
public PhoneNumbers(String[] phones) {
this.phones = phones;
}
}
There is no need in this case to convert to a List.
String[] phone_numbers= new String[] { "1234", "5678" }; // populate from DB instead
PhoneNumbers numbers = new PhoneNumbers(phone_numbers);
// to serialize
Serializer serializer = new Persister();
serializer.write(numbers, System.out);
This will print out the following XML:
<phoneNumbers>
<numbers length="2">
<phone>1234</phone>
<phone>5678</phone>
</numbers>
</phoneNumbers>
There is no way for the Simple framework to NOT print a root element. So you could String strip the root element if you absolutely need to just serialize the numbers element.
That's it!
Here is my json string, that I am acessing in java:
json =
[
{"id":"123456","Data":"skill2","dmlcrud":false},
{"id":"123456","Data":"skill3","dmlcrud":true},
{"id":"123456","Data":"skill14","dmlcrud":true},
{"id":"123321","Data":"skill1","dmlcrud":false},
{"id":"123321","Data":"skill14","dmlcrud":false}
]
I now want to put it in a collection so ideally/theoretically I would want to do:
List<Person> personList = new Gson().fromJson(json, Person.class);
and personList.size() would = 5. I would then loop through personList and preform my relevant actions.
However, my understanding is that I would need to create a container class, which itself contains the person list ? So instead of (public getters/setters removed for brevity, probably syntax errror in there aswell).
Class Person {
private integer id;
private String Data;
private Boolean dmlCrud ;
}
I would actually need something like ?
Class container{
List<Person> personList;
static class Person {
private integer id;
private String Data;
private Boolean dmlCrud ;
}
}
However I would then need to alter the javascript json to be somethign different aswell ? Which seems rather problematic as am I creating the json string from a javascript array, using JSON.stringifier.
Any help gratefully received.
EDIT
the solution I used was to add
public List<Person> personList;
to the person class
and alter the json object so that it was
{ "personList" :
[
{"id":"123456","Data":"skill2","dmlcrud":false},
{"id":"123456","Data":"skill3","dmlcrud":true},
{"id":"123456","Data":"skill14","dmlcrud":true},
{"id":"123321","Data":"skill1","dmlcrud":false},
{"id":"123321","Data":"skill14","dmlcrud":false}
]
}
the gson call can then be
Person person = new Gson().fromJson(json, Person.class);
and the data accessed in a list like so
List<Person> personList = person.getPersonList();
EDIT 2
A second, better, solution is to use this json array
[
{"id":"123456","Data":"skill2","dmlcrud":false},
{"id":"123456","Data":"skill3","dmlcrud":true},
{"id":"123456","Data":"skill14","dmlcrud":true},
{"id":"123321","Data":"skill1","dmlcrud":false},
{"id":"123321","Data":"skill14","dmlcrud":false}
]
and then use
Type listType = new TypeToken<List<SkillsGsonTO>>() {}.getType();
List<Person> personList = new Gson().fromJson(json,listType);
Person person1 = personList.get(0);
where the original class is used
Class Person {
private integer id;
private String Data;
private Boolean dmlCrud ;
}
You could use a Container class but this only makes sense if you need to ship additional properties on the person list. If this is not the case, you could convert to a java.util.List as well. I think you need to specify the "name" of the list property as a root element in your JSON string. So for instance if you're domain object is a List of Person objects, than your JSON root element is: "persons" or "personList". So you're JSON could look something like:
"persons" : {[
{"id":"123456","Data":"skill2","dmlcrud":false},
{"id":"123456","Data":"skill3","dmlcrud":true},
{"id":"123456","Data":"skill14","dmlcrud":true},
{"id":"123321","Data":"skill1","dmlcrud":false},
{"id":"123321","Data":"skill14","dmlcrud":false}
]}
I could be a little bit off with the syntax, but it should be something similar to this. So to summarize:
In your case you can leave you're Person class untouched and gson should be able to create the List persons for you from the JSON string I suggested.
From the Gson API docs:
If the object that your are deserializing is a ParameterizedType (i.e. contains at least one type parameter and may be an array) then you must use the fromJson(String, Type) method. Here is an example for deserialing a ParameterizedType:
Type listType = new TypeToken<List<String>>() {}.getType();
Gson gson = new Gson();
List<String> target2 = gson.fromJson(json, listType);
So in your case it would be:
Type listType = new TypeToken<List<Person>>() {}.getType();
List<Person> persons = new Gson().fromJson(json, listType);
where json is your json string obviously