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));
Related
I am trying to serialize a list of JSON blobs and put certain keys into a HashTable during the serialization. Here is an example of my JSON:
[
{
"name": "sally",
"id": 1,
"eye_color": "green"
},
{
"name": "jack",
"id": 2,
"eye_color": "blue"
},
{
"name": "jane",
"id": 3,
"eye_color": "brown"
}
]
What I am looking for specifically is a POJO (or set of POJOs) which can serialize the above JSON like so with Jackson assuming the above JSON is in a file called above_json.json:
MyPOJO pojo = objectMapper.readValue(new File("above_json.json"), MyPOJO.class);
I want the result of the serialization to give me a HashTable (or an Object which encapsulates the HashTable) where the HashTable key is the value of name and the Hashtable value is the value of the corresponding id above.
Assuming we serialized the above JSON in this fashion, I would want to access the HashTable like so:
myTable.get("jane")
result: 3
myTable.get("jack")
result: 2
myTable.get("Jill")
result: null
I know how to serialize basic JSON with Jackson. I have an example like below:
JSON Input:
"Parameter":{
"Name":"Parameter-Name",
"Value":"Parameter-Value"
}
POJO to serialize above simple JSON:
public class Parameter {
#JsonProperty("Name")
public String name;
#JsonProperty("Value")
public String value;
}
But obviously this type of setup does not put the results into a HashTable. I need a POJO like what I have in this example which will serialize JSON directly into a HashTable
I don't think that is possible.
You serialize this json into a list of pojos, and have a utility function to generate the hashtable in the way you desire from the list of pojos.
Create a POJO for holding the properties you are interested in.
#JsonIgnoreProperties(ignoreUnknown = true)
private static class MyPOJO {
#JsonProperty("name")
private String name;
#JsonProperty("id")
private Integer id;
public Integer getId() {
return id;
}
public String getName() {
return name;
}
}
Deserialize the contents of the file into List<MyPOJO>
List<MyPOJO> myPOJO = mapper.readValue(new File(".."), new TypeReference<List<MyPOJO>>(){});
Stream the contents of the map to construct a map whose key is the name and value is the id.
Map<String, Integer> map = myPOJO.stream()
.collect(Collectors.toMap(MyPOJO::getName, MyPOJO::getId));
First of all, you probably don't want to use a HashTable, as it's considered to be an obsolete type (see here).
Either use a HashMap or if you want thread safety, a ConcurrentHashMap or a thread-unsafe Map backed by Collections.synchronized[...] and referenced to within synchronized statements.
Secondly, you can use a TypeReference to de-serialize as your desired type.
Finally, your JSON's syntax is incorrect: it starts with a square bracket ([) and ends with a curly bracket (}), which is technically unparseable.
Assuming you want an array of Maps here (e.g. HashMap<String, String>[]), here is some suitable code, provided you replace the last curly bracket with a square one:
// the map array
Map<String, String>[] map = null;
map = om.readValue(yourFile, new TypeReference<HashMap<String, String>[]>() {});
// prints the de-serialized contents
System.out.println(Arrays.toString(map));
Edit
Since you have now edited your JSON to remove the first square bracket and replace it with a curly bracket, no you can't parse as a Map as is.
Edit 2
Since you have now re-edited your JSON to feature square brackets once again instead of curly brackets in the wrapping object, you can once again de-serialize as a Map[]. Until the next edit, I guess...
I've got a hash map like -
Map<Employee,Duty>
where Employee and Duty objects are like below -
class Employee
{
e_id; // will be used in equals() and hashcode()
e_DOB;
e_name;
}
class Duty
{
d_type;
d_timing;
}
Is there a way to convert this map into JSON so that JSON will be generated for all the fields of Employee and Duty objects ?
I'm not sure if this can be done in the same as for any hash map having a primitive class as key. i.e. Map<String,Employee>
Use eg JSON In Java
class Employee
{
public JSONObject toJSON(){
JSONObject resultJson = new JSONObject();
resultJson.put("e_id", e_id);
resultJson.put("e_DOB",e_DOB);
resultJson.put("e_name",e_name);
return resultJson
}
}
I believe Gson is the perfect solution for you.
Have a look at an example:
http://kodejava.org/how-do-i-convert-map-into-json/
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 have a list of categories coming back from a web request, in JSON format. An example might be:
"categories":[["Descriptive Cat 1 Name","cat1label"]]
How would that be represented in the object? I currently have an object called Category, and am using it like:
private List<Category> categories;
The Category object looks something like:
class Category {
private String descrName;
private String label;
.. getters and setters..
}
When attempting to decode with GSON I get this eror:
01-27 21:44:46.149: ERROR/AndroidRuntime(843): com.google.gson.JsonParseException: Expecting array but found object: Category#437d1ff8
Any suggestions? I would also be OK having those come back as a map, although instead of K,V in the JSON results they would be V,K, could it be mapped that way?
It does work if I ditch the Category object all together, and just map it as:
private List<List<String,String>> categories;
But is there a better way to represent that data?
Nick
As #Dante617 correctly pointed, your JSON representation is not correct. The correct representation is
{
"categories": [
{"descrName":"Descriptive Cat Name 1", "label": "cat1Label"},
{"descrName":"Descriptive Cat Name 2", "label": "cat2Label"}
]
}
Now, this can be thought of as a map of "categories" title and list of Category objects. So, the Java object, that maps it, will be Map<String, List<Category>>
If you somehow reformat your string correctly like the one above. Here is how you would parse.
String categories = "{\"Categories\":[{\"descrName\":\"Descriptive Cat 1 Name\",\"label\":\"cat1label\"}, {\"descrName\":\"Descriptive Cat 2 Name\",\"label\":\"cat2label\"}]}";
Gson gson = new Gson();
Type type = new TypeToken<Map<String, List<Category>>>() {}.getType();
Map<String, List<Category>> l = gson.fromJson(categories, type);
System.out.println("l: " + l);
If your Java object looks like this
public class Category {
private String descrName;
private String label;
//no need of getters and setters. Reflection, baby! :)
#Override
public String toString() {
return "<Name:"+descrName+", label:"+label+">";
}
}
The output will show like this
l: {Categories=[<Name:Descriptive Cat 1 Name, label:cat1label>, <Name:Descriptive Cat 2 Name, label:cat2label>]}
I'm not familiar with GSON, but I'm not sure how the application could map the strings to the fields in your object. It seems like you want a JSON structure more like:
"categories": [
{"descrName":"Descriptive Cat Name 1", "label": "cat1Label"},
{"descrName":"Descriptive Cat Name 2", "label": "cat2Label"}
]
That might help in being able to dynamically create the Java objects.
In contrary to what others think, that's not invalid JSON. The [[]] is just a two-dimensional array. In Java terms, it maps as follows:
String json = "{\"categories\":[[\"Descriptive Cat 1 Name\",\"cat1label\"]]}";
Map<String, String[][]> map = new Gson().fromJson(json, new TypeToken<Map<String, String[][]>>(){}.getType());
// ...
or
String json = "{\"categories\":[[\"Descriptive Cat 1 Name\",\"cat1label\"]]}";
Map<String, List<List<String>>> map = new Gson().fromJson(json, new TypeToken<Map<String, List<List<String>>>>(){}.getType());
// ...
Thanks for the input folks. Unfortunately this is a public web service I'm utilizing (the Yelp v2 API) and I can't change the format of the data they are returning. This is what I stuck with for now which is working fine:
private List<List<String>> categories;
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