Creating Map or Set using GSON - java

I am using Google's GSON library and want to create a JSON which looks something like this:
{
"teamSet":[],
"classificationMap" : {}
}
Notice that [] and {} are empty Set and Map respectively and are not surrounded with double quotes.
I want to create this Json using the GSON add/addproperty method and not by converting a Java class into JSON using the Gson.toJson() method. The business use-case restricts me from creating specific Java classes as the JSON structure may change overtime. So I cannot use a class like this as this would rigidly tie a JSON structure with a concrete class
class Linkage{
private Set<String> teamSet;
private Map<String, String> classificationMap;
// getter, setter methods follow
...
}
When I use the GSON.addproperty(genericObject, type), it is appending double quotes around [] and {}. I am using couchbase for my DB requirements and the double quotes around [] and {} makes couchbase treat them as string and not as Set/Map. This renders my Map-Reduce views useless and buggy :(
Please let me know if its possible to create such a JSON without having to tie it up with a concrete JAVA class. Thanks !
My current code looks like this:
// create types
Type setType = new TypeToken<Set<String>>() {}.getType();
Type mapType = new TypeToken<Map<String, String>>() {}.getType();
Gson GSON = new Gson();
Set<String> teams = new HashSet<String>();
Map<String, String> classificationMap = new HashMap<String, String>();
JsonObject linkageJson = new JsonObject();
linkageJson.addProperty("teamSet", GSON.toJson(teams, setType));
linkageJson.addProperty("classificationMap", GSON.toJson(classificationMap, mapType));

In the 2.x line of the couchbase java sdk, there is the JsonObject class that could have fit your need.
It is perfect to create Json "by hand" and still have a simple generic object representation, and is the official way of putting json into the database via the sdk.
It would go like this :
JsonObject obj = JsonObject.create();
obj.put("teamSet", JsonArray.from(new ArrayList(teams)))
.put("classificationMap", JsonObject.from(classificationMap));
Granted this is a little bit contrived because arrays and sub-objects can only be constructed from respectively List<?> and Map<String, ?> factory methods. Also the class support a limited set of value types (no custom classes, only String, Number, Boolean, etc...).

i feel somewhere it is storing it toString() representation.
Please refer below link, it might help you.
click here

Related

Serialize vertx JsonObject using Jackson

I'm using vertx and Jackson in my development. In one of my classes, I got a field of type JsonObject, something like this:
class User
private String name;
private JsonObject details;
This details field can contain other JsonObjects or JsonArrays, e.g.:
{"details": [{"street": "Broadway"}, {"building": 20}]}
I don't have a dedicated class of this structure, as far as there's no fixed structure and it can vary.
details object is being created in the way like this:
JsonObject details = new JsonObject().put("name", "value").put("another", "another")
This aproach allows me to store details of any structure inside my code. As far as I don't need to manipulate this data on my backend, I don't want to create a special structure for it.
Everything works fine until I'm trying to serialize this JsonObject using Jackson. Unfortunately, instead of beatiful JSON string, Jackson gives me map object serialized with all map's additional fields.
How can I serialize JsonObject of vertx using Jackson?
Looking at JsonObject's javadoc , I saw a getMap() method. I know Jackson is capable of serializing Maps with ease.
Finally, it turned out that vertx already has it's own implementation of Serializer.
It's enough just to use theirs class to perform serialization (which will use Jackson undercover).
JsonObject user = new JsonObject(Json.encode(new User());
And it works fine.
I would suggest creating using https://static.javadoc.io/com.fasterxml.jackson.core/jackson-databind/2.7.3/com/fasterxml/jackson/databind/ObjectMapper.html#convertValue(java.lang.Object,%20java.lang.Class) like this:
new JsonObject((Map)Json.mapper.convertValue(new User(), Map.class));
Converting to and from String takes time.

Get JSONobjects from string

So i have a string which contains multiple JSONobjects and looks like this:
[{"one":"1","two":"2","three":"3"},
{"one":"4","two":"5","three":"6"},
{"one":"7","two":"8","three":"9"}]
How can i iterate through this string using java and get every object? Is it possible using JSON api, or i should make parser by myself?
GSON library is a good option to convert java object to json string and vise versa.
for converting json to java object use: fromJson(String, Class)
for converting java object to json string use: toJson(Object)
In your case it's a List of Object.
sample code:
class MyPOJO {
private String one;
private String two;
private String three;
// getter & setter
}
String jsonString = "[{\"one\":\"1\",\"two\":\"2\",\"three\":\"3\"}, {\"one\":\"4\",\"two\":\"5\",\"three\":\"6\"}, {\"one\":\"7\",\"two\":\"8\",\"three\":\"9\"}]";
Type type = new TypeToken<ArrayList<MyPOJO>>() {}.getType();
ArrayList<MyPOJO> obj = new Gson().fromJson(jsonString, type);
System.out.println(new GsonBuilder().setPrettyPrinting().create().toJson(obj));
Note: The name of variable in your java POJO class should be same as JSON string.
Find more examples...
You Should defiantly use the Json API, you can download the jar from here and simply use
JSONArray myArray = new JSONArray(yourString);
for (int i=0; i < myArray.length(); i++)
{
JSONObject currentOb = myArray.get(i);
doSomthing(currentOb);
}
It is obvious that you should use a JSON library. Existing libraries are tested and validated. In very rare conditions you may need to write your own parser, your own implementation. If that is the case, I think you should double check your design. Because you might be doing something wrong if the existing library is in conflict with your design.
Library selection depends on your environment and your performance requirements.
In my case, Spring3 is the environment and the JSON objects are huge (10-20MB), and inserts occur on existing JSON objects. We prefer Jackson. Jackson's performance is outstanding. An independent performance comparison is in here. You will see that the Jackson outperforms GSon in here.

What is the most suitable Java data structure for representing JSON?

I' m developing a RESTful Android mobile client. Information exchange between my app and server is in JSON. So I' m now a little bit confused what data structure choose for represent JSON responses and data because there a lot of them. I've just stopped with LinkedHashMap<> but as far as i know JSON is unordered. Across the Internet I saw people use Map<> or HashMap<> for this. So the question - what is the best data structure for this purpose? Or if there is no a univocal answer - pros and cons of using data structures I' ve mentioned.
I would disagree with the first answer. The REST paradigm was developed so that you would operate with objects, rather than operations.
For me the most sensible approach will be if you declare beans on the client side and parse the json responses and request through them. I would recommend using the GSON library for the serialization/ deserialization. JsonObject/ JsonArray is almost never the best choice.
Maybe if you give examples of the operations you are about to use we might be able to help more precisely.
EDIT: Let me also give a few GSON Examples. Let's use this thread to compare the different libraries.
In the most cases REST services communicate objects. Let's assume you make a post of product, which has reference to shop.
{ "name": "Bread",
"price": 0.78,
"produced": "08-12-2012 14:34",
"shop": {
"name": "neighbourhood bakery"
}
}
Then if you declare the following beans:
public class Product {
private String name;
private double price;
private Date produced;
private Shop shop;
// Optional Getters and setters. GSON uses reflection, it doesn't need them
// However, better declare them so that you can access the fields
}
public class Shop {
private String name;
// Optional Getters and setters. GSON uses reflection, it doesn't need them
// However, better declare them so that you can access the fields
}
You can deserialize the json using:
String jsonString; // initialized as you can
GsonBuilder gsonBuilder = new GsonBuilder();
gsonBuilder.setDateFormat("MM-dd-yyyy HH:mm"); // setting custom date format
Gson gson = gsonBuilder.create();
Product product = gson.fromJson(jsonString, Product.class);
// Do whatever you want with the object it has its fields loaded from the json
On the other hand you can serialize to json even more easily:
GsonBuilder gsonBuilder = new GsonBuilder();
gsonBuilder.setDateFormat("MM-dd-yyyy HH:mm"); // setting custom date format
Gson gson = gsonBuilder.create();
String jsonString = gson.toJson(product);
Are you talking about receiving and parsing the JSON string from a server request?
For that you can use:
import org.json.JSONArray;
import org.json.JSONObject;
Using these, I read through my JSON array from my POST request and store the resulting information in Class objects in my project.
For each item in JSONArray, you can extract the JSONObject and attributes like this:
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject jsonObject = jsonArray.getJSONObject(i);
jsonObject.getString("text");
}
As far as actually storing the data, like mentioned above, JSON data can come in a wide array of formats depending on the source, and as such, it is usually parsed on the client end and saved in your application Class objects for use. Or more generically, you could store the data using Map<String, Object>
This is easily the best answer I've seen:
https://dzone.com/articles/which-is-the-right-java-abstraction-for-json
Summary: there are three abstrations: pojos, maps and lists, and custom classes to represent objects, arrays, and primitives. There are advantages and disadvantages to each, with no clear winner.
Pojos have the biggest advantages, but you can't always use them. Use them if you can, and use the others if you must.
If you are doing anything other than the most simple mapping then you should use a full class structure. Create your class hierarchy as a mirror of the data structure in JSON and use Jackson to map the JSON directly to the class hierarchy using the ObjectMapper.
With this solution you don't have any casting of Object to Map or messing around with JSONObject or JSONArray and you don't have any multi-level map traversal in your code. You simply take the JSON string, feed it to the ObjectMapper, and get a your Object, which contains child objects (even collections) automatically mapped by the ObjectMapper.
I've used xstream to serialize JSON, in the following way:
XStream xstream = new XStream(new JsonHierarchicalStreamDriver());
xstream.setMode(XStream.NO_REFERENCES);
xstream.alias("myAlias", MyClass.class); // requires a no argument constructor
System.out.println(xstream.toXML(product));
Ok, the gentleman in the comments wants a deserialization example, here you are:
XStream xstream = new XStream(new JsonHierarchicalStreamDriver());
xstream.alias("myAlias", MyClass.class);
Product product = (Product)xstream.fromXML(json);
System.out.println(product.getName());
Let me know if you need further assistance...

Dynamically entering class literal as method argument at runtime

I have an application which makes use of an external library (Jackson), and the method I need requires a class literal as an argument. So if I wish to parse my JSON string into a User object:
ObjectMapper mapper = new ObjectMapper();
User user = mapper.readValue(new File("user.json"), User.class);
Now, I wish to use this method dynamically (i.e. parse different JSON strings using the same line of code). For example:
String json1 = "{"type":"jacket",...}";
String json2 = "{"type":"sweater",...}";
Object object = mapper.readValue(json1/json2, ???);
//returns a Jacket object OR Sweater object based on the "type" key
//i.e. use Jacket.class as the 2nd argument if "type" is "jacket"
//OR Sweater.class if "type" is "sweater"
//After getting the deserialized object,
//if object is Jacket, cast as a Jacket
//if object is Sweater, cast as a Sweater
Of course, the JSON string in question can be for any class, so I can't simply hard-code an if-else loop. I've looked at custom serializers, but frankly am quite lost at what it's talking about, and would like some help in how I can go about this.
In summary, I need some way to first define a class literal from a String, and then cast the resulting Object into the specific class (but my focus is on getting readValue to work dynamically).
Looks like you need a mapping somewhere between JSON type variable and Java class type.
Generally result should be something like this map:
Map<String, Class<? extends YourSupertype>> map = new HashMap<>();
map.put("sweater", Sweater.class);
map.put("jacket", Jacket.class);
Just store possible clothing types somewhere in a file, then do something like:
String clothingType = nextEntryFromFile();
String className = constructClassNameFromClothingType(clothingType);
map.put(clothingType, Class.forName(className));
Since version 1.5 Jackson supports Polymorphic Type Handling, check here http://www.cowtowncoder.com/blog/archives/2010/03/entry_372.html
there are examples on how to correctly handle deserialization in those cases.

How to convert JAVA Object to JSON Efficiently..?

I am using Mule. I have a JAVA Object that is populated from my internal Class..It is actually a HashMap<String,Object>. Object can be anything..another HashMap, OR List etc ..Now i have to convert it into JSON (and removing all those keys that have value as NULL)..
When i use a given Mule Transformer , ObjectToJSON, it is converting into appropriate JSON..but not able to remove NULL value..And i could not find any properties to set in Custom-transformer that will remove NULL values..!!
So then, i wrote a custom transformer, that uses the net.sf.json-lib library and i am able to remove NULL values.
But in one of my JAVA Object , i have a HashMap<Integer,String> and since in JSON Object , Integer cannot be keys, net.sf.json library is giving an Exception :
Exception stack is:
1. JSON keys must be strings. (java.lang.ClassCastException)
net.sf.json.JSONObject:1120 (null)
2. java.lang.ClassCastException: JSON keys must be strings. (net.sf.json.JSONException)
net.sf.json.JSONObject:1160 (null)
3. java.lang.ClassCastException: JSON keys must be strings. (net.sf.json.JSONException). Message payload is of type: HashMap (org.mule.api.transformer.TransformerMessagingException)
and so it is unable to convert it into JSON..
So what is most viable option..??
I would recommend you to try gson it worked like a magic for me.
Collections Examples
Gson gson = new Gson();
Collection<Integer> ints = Lists.immutableList(1,2,3,4,5);
(Serialization)
String json = gson.toJson(ints); ==> json is [1,2,3,4,5]
(Deserialization)
Type collectionType = new TypeToken<Collection<Integer>>(){}.getType();
Collection<Integer> ints2 = gson.fromJson(json, collectionType);
ints2 is same as ints
Here is an example of how to write a custom serializer for JodaTime DateTime class.
private class DateTimeSerializer implements JsonSerializer<DateTime> {
public JsonElement serialize(DateTime src, Type typeOfSrc, JsonSerializationContext context) {
return new JsonPrimitive(src.toString());
}
}
Have you looked at Gson?
http://sites.google.com/site/gson/gson-user-guide#TOC-Null-Object-Support
From http://www.ietf.org/rfc/rfc4627.txt
An object structure is represented as a pair of curly brackets surrounding zero or more name/value pairs (or members). A name is a string.
I would suggest to modify your initial Java structure to use String as key type.
However with Jackson library you can create fancier solutions:
Use a custom deserializer Deserializing non-string map keys with Jackson
Use a Tree Model instead of your own Java POJO http://wiki.fasterxml.com/JacksonInFiveMinutes

Categories

Resources