I'm working on an Android app. The app gets the data as JSON string (name of universities and student lists) and manipulate the app according to the data.
What will be a better approach?
Create a new Object and parse the JSON string into it, and work with the object, or
Keep the JSON string, and just use JSONObject whenever I need to grab information from the string
Or any other way?
If I'm using the new Object, how can I transfer (or share) the object with other activities in the app?
I know that for string we can use putextra().
Use objects.
I would suggest to use Jackson library,
be cause it is very fast and easy to ingrate.
You can find code examples here :
http://www.mkyong.com/java/how-to-convert-java-object-to-from-json-jackson/
P.S. : Jackson is not the only library for this approach > Jackson Vs. Gson
I almost always parse the JsonObject into a specific object E.g. class University.
One benefit of doing this, is you can put it nicely into collections. E.g. HashMaps, Set or just straight List. When dealing with it as a JsonObject you won't be able to as easily work with it.
You can do things like sort it if you Object inherits Comparable, and can define equals/toString/hashCode.
There are a number of other benefits, but I think you'll find holding that data in a real data structure will give you the most benefit
I would recommend parsing the string (or using a library to do this for you!) and filling an object. This way, your model object can control the data and how it is shared with other objects, and use internal data structures to optimize usage. If you stuck with the JSON string you'd end up parsing it multiple times to pull out data.
However you decide to share the object/string across activities shouldn't affect your decision for how to model the data. You'll likely end up passing it across activities in any case.
I suggest that you use objects too.
You can use Gson library to do any conversion between json string and objects. It is very, very easy to use. http://code.google.com/p/google-gson/
To transfer the data between other activities you can make your object implement the Serializable interface, this way you can use the .putExtra() and pass it forward.
Related
I have a JSON file that is marshalled into custom object using GSON.
All works fine.
An example of the structure I have:
public class Domain {
private String id;
private String name;
//other fields
private ArrayList<Structures> structs;
private ArrayList<Buildings> buildings;
private ArrayList<CustomObject> objects;
// some more lists and fields
}
So basically I create a builder and parse the json
Gson gson = new GsonBuilder().create();
gson.fromJson(jsonString, Domain.class);
This works absolutely fine. Parsing is done and I get my data.
Problem:
I don't really need to have various fields of the Domain class populated from the start because e.g. I may have the Domain class with a lot of elements in the e.g. list for structs but I might not really need to access them.
What I need to do is some kind of pattern for lazy loading.
I.e. I would like to not load some parts of class during the json parsing and only load them when needed.
Question:
If I understand correctly the way to skip fields from being parsed is by making them transient.
But then if at some later time I need to access e.g. the structs how would I actually load them at that point? I think that reloading/reparsing all the json again is suboptimal.
What is a standard/good approach for this?
This is a really lengthy topic. There are many approaches to this and all of them are usually a lot more complicated. The easiest one, if you really value something very simple for me was so far not using gson, but for example something like JSONObject and then populate the object myself. using this you could easily split this up into multiple steps. The problem that now arises is, that you never know, what exactly is already loaded - or more - what is maybe loaded, but just not filled as a field.
Lazy loading using automatic conversions like gson is unfortunately always gonna involve unnecessary object creation too, so question then is if its not less pain just to do it yourself from the beginning.
if it has to be gson, you could have different objects for different stages. read them in through json and then apply to your main object.
a favourable version of that is probably to split up the object into different components (or aspects or whatever you want to call it) that match the different loading stages. Different possibilities but lets just pick one of them:
class Domain {
private String id;
private DomainStructs domainStructs;
}
class DomainStructs {
private ArrayList<Structures> structs;
}
Now you need a new Object in this version of doing this. This means the overall size of the model is slightly (but not much really) bigger and you should probably match together things that are necessary together anyway - so not load every field separate, but this way you can leave out parts and easily add them later by populating them from Gson like 2 steps here:
Gson gson = new GsonBuilder().create();
Domain domain = gson.fromJson(jsonString, Domain.class); // first time
domain.structs = gson.fromJson(jsonString, DomainStructs.class); // now adding
I am not saying this is the best idea ever, but it fulfills your idea while still using gson.
I would though consider splitting up the Data already - so not storing the strings, but holding the data in different components in this case if it is possible. Basically you want a domainJsonString and a domainStructsJsonString if you get what i mean. stored in a way so you can easily retrieve them separately.
I hope this helps you to move a bit forward
Sometimes, we need to create some thrift objects in unit tests. We can do it by manually create object using Java code, like:
MyObj myObj = new MyObj();
myObj.setName("???");
myObj.setAge(111);
But which is not convenient. I'm looking for a way to create objects with some readable text.
We can convert thrift objects to JSON with TSimpleJSONProtocol, and get very readable JSON string, like:
{ "name": "???", "age": 111 }
But the problem is TSimpleJSONProtocol is write only, thrift can't read it back to construct an instance of MyObj.
Although there is a TJSONProtocol which supports to serialize and deserialize, but the generated JSON is not readable, it uses a very simplified JSON format and most of the field names are missing. Not convenient to construct it in tests.
Is there any way to convert thrift objects to readable string and also can convert it back? If TSimpleJSONProtocol supports converting back, which is just what I'm looking for
The main goal of Thrift is to provide efficient serialization and RPC mechanisms. What you want is something that is - at least partially - contrary to that. Human-readable data structures and machine processing efficiency are to a good extent conflicting goals, and Thrift favors the latter over the former.
You already found out about the TSimpleJson and TJson protocols and about their pros and cons, so there is not much to add. The only thing that is left to say is this: the protocol/transport stack of Thrift is simple enough.
This simplicity makes it possible to add another protocol based on your specific needs without much or overly complicated work. One could probably even write an XML protocol (if anyone really wants such bloatware) in short time.
The only caveat, especially vis-à-vis your specific case, is the fact that Thrift needs the field ID to deserialize the data. So you either need to store them in the data, or you need some other mechanism which is able to retrieve that field ID based on the field and structure names.
I have a JSON string representing an object, and I want to put its information into a Java object B with a different structure. Currently the solution I am taking is creating a Java Object A with a structure identical to the JSON object, made the conversion from JSON to A using Jackson and later, made the mapping from A to B using Dozer with XML mappings. Is there anyway to avoid having the A objects?
Making it short, currently I have this:
JSON--Jackson-->A--Dozer(XML mappings)-->B
and I would like to achieve this
JSON--???-->B
You may know this already, but Jackson can use loosely structure types like Map, or JsonNode as target, so you can do, say:
JsonNode root = mapper.readTree(jsonSource);
Map<String,Object> asMap = mapper.readValue(jsonSource, Map.class);
and then construct your B. Jackson has only limited amount of structural conversions (simple unwrapping), by design, although there is extensive set of scalar conversions (non-structural conversions), so if you do need structural changes it may make sense to use a library that is focused on structural changes.
I am working with GSON in my current project, i am amazed to see its power and was wondering how did it work internally. How can a GSON object change the any object into JSON and vice versa. I did read the google user guide but the internal working is not mentioned their. Can anyone explain. Also this question might not appeal some people but i am new to android programming and was exploring things. Although i used gson successfully. But i do like to know its working methodology. Can any one explain.
Thanks a lot.
Gson's internals are built on three core types:
JsonReader reads the elements in a JSON document from a stream.
JsonWriter writes the elements in a JSON document to a stream.
TypeAdapter converts a single JSON element to a single object, or vice versa.
One key pattern is that TypeAdapter is implemented recursively. For example, the TypeAdapter<FoodDelivery> may delegate to a TypeAdapter<Address> and a TypeAdapter<MenuItem>. The TypeAdapterFactory interface makes it easy to build type adapters for arbitrary types.
One other key pattern is that Gson includes some awesome type adapters built-in by default. There's type adapters for primitives, strings, collections. Plus a special type adapter that takes an arbitrary Java class and converts it to a JSON object field-by-field.
I suggest that you do not perform recreation of objects and not force GSON except where it is needed. IMO, you have to use GSON anywhere where you have REST service, but GSON is more slower than java collections (ArrayList or HashMap or any other ...) and you will decrease app performances if you continue to use GSON everywhere.
Second reason is that when you perform object recreation, this is done in phone memory, and just for example, I had a problem with JSON (GSON) object which was exposed over service because it was 35-40MB and object creation uses over 70MB of RAM. There I had OutOfMemoryException, MemoryExhaustedException and more problems this kind.
If this limitations are not interested for you (you don't have large objects, or high speed is not required), then proceed to convert objects to GSON.
I'm trying to flatten an object graph completely to a map.
Complex objects should also be flattened to the top level using "namespaces". So if the object A contains an int i, a string pid and another object B that contains a string id, the resulting Map would look like {i=1, pid="test", B.id="test1"}.
I also want to be able to reconstruct the original object from a given map.
I've searched around for libraries that do this. But I'm not quite getting what I'm looking for. I see stuff that maintains the hierarchy but nothing that completely flattens the structure.
I do see something in Spring Integration that looks like what I want to do:
http://static.springsource.org/spring-integration/api/org/springframework/integration/transformer/ObjectToMapTransformer.html#ObjectToMapTransformer%28%29
But I can't get it to work.
Any help would be appreciated.
Thanks.
The Apache BeanUtils library has a describe() method that does something similar to what I was looking for.
Another possible solution would be via the Jackson JSON library, since JSON objects are essentially key-value pairs.
Related discussions: How to convert a Java object (bean) to key-value pairs (and vice versa)?
Have you considered using Protobufs?
The json-flattener library solves exactly your problem