Declaring json object in a java model class - java

Can we declare a attribute of type json object in a java model class
For example.
public class Sample {
private JSONobject data;
//getters and setters
}
In this way can we declare an attribute?
If so, do we need to add anything extra? I got an exception on runtime while populating the field.

I've yet seen anyone using JSONObject /JsonObject in a model.
Please refer to this for the difference between POJO (java model object) and DTO (objects like JSONObject) and this for when should you use JSONObject.
So the answer to your question is probably not.
This answer to serialization/deserialization should help you understand POJO and JSON better.
So far, I've only seen primitive values and list in a java model.
The JSONObjects need to be deserialized to POJO objects (vice versa). (Please refer to this post on why use POJO over JSONObject)
Your code won't even compile as it is asking for the parameter type of JSONObject which is not among java primitive values and part of Java collection.
However, you could argue that you can have
public class Sample<JSONobject> {
private JSONobject data;
//getters and setters
}
But this would be an unrelated object inside another object, which has no logic in implementation. For best practice, it's better to follow the common usages as many code bases would be serializing/deserializing JSON.

Related

Create POJO Model with dynamic object value

I have a 3 object value from JSON, and the second object is dynamic value, i.e. it can be an array or an object. So it look like this one :
{
obj1 : {....},
dynamicObj2 : {....}, // it can be object or array
obj3 : {....}
}
So, my question is how can this be achieved in the POJO class? I am using GSON for this case. And it will be implemented at Android end and I am using retrofit for the networking library. Any suggestion for POJO class? Or I must use manual String object and parsing one by one?
If the Object it can be is of the same kind as the elements in the Array just make it always an array in your Java Class. if not then you will need to use the Object class and cast it to the appropriate type you want later.
You can also automatically generate a POJO using this tool: http://www.jsonschema2pojo.org/
You can even make it serializable, parcelable, and so on. Just check Gson and preview to see if the class is in your liking.

simple method/extendable class to make my toString method of a POJO output json like output?

I have a number of pojos which are being used for a jersey client to be filled with the JSON data from a restful call. The client is reading in json and filling these objects using the JacksonJsonProvider. I'm not using any annotations, the variable names are equal to the json coming in.
I would like the toStrng methods for these PoJos to automatically output a representation of the json they represent, without my having to manually write each toString. Since these are basic POJO which are structured in a simlpe tree format it should be realatively easy to output these pojo as json in the toString method. In fact I know I could use reflection to do this myself in some parent/abstract class if I felt like it. However, it feels like I shouldn't have to do this by hand. Is there already some method out there that will do this for me I can use instead?
I don't insist that the output be json, though that would be preferable, but any similar method of visualizing the variables automatically without my manually writing it would be fine.
Thanks
If you use Google GSON you can serialize objects into JSON. Your toString() would then look something like:
public String toString() {
return StaticLib.GSON.toJson(this);
}
A GSON object can be shared across all objects, hence my inclusion of this mystery StaticLib class. You can find the correct name or place for that in your own project I'm sure.

Cast to class from JSONObject

I got JSONObject from service response.
Well in case of an error I need to cast it to one of the error classes.
Json is something like
{"message":"This means that the userID is not valid.","name":"UserNotFoundException"}
where name can be any of the exceptions in model package
Can I do this?
Class ex = Class.forName("com.myapp.model.Exceptions." + jsonObject.getString("name"));
How can I cast ex to UserNotFoundException class so I can use its methods i.e.
ex.doSomething()
If you really need to do this (although this is something that is usually done very rarely), take a look at reflection: Java how to instantiate a class from string
You can use GSON. it easily serializes and de-serializes json data..
For Reference -- > https://code.google.com/p/google-gson/
you aren't actually casting anything in your code, you are retrieving a class instance using a naming convention of your own. You'll need to create an instance of that exception class later on using the message from your JSON object.
Casting is a complete different thing, to get some understanding you can look at this answer.
The thing is, you can't cast a JSON object to a Java class, the same way you can't cast a DOM tree to a Java object tree. What you can do (and everyone does) is to marshal/unmarshal the JSON object to a Java class. This means, creating instances of the Java classes that match the JSON object structure and then map the attributes of that Java class with the attributes of the JSON object.
So, in your code it would look like:
Class ex = Class.forName("com.myapp.model.Exceptions." + jsonObject.getString("name"));
Constructor cons = ex.getConstructor(String.class);
UserNotFouncException unfe = (UserNotFoundException) cons.newInstance(jsonObject.getString("message")); // here is where actual casting is happening
Note: please, be aware that above code may throw exceptions that you need to guard for.

jackson deserialization into pojos

I'm trying to deserialize JSON Object coming from an application I can't control. Here my JSON :
{"assembly":
{"name":"mm9",
"id":32,
"chromosomes":[
{"chromosome":
{"name":"MT"}
}]}}
My Pojos, are
class Assembly{
private String name;
private int id;
private ArrayList<Chromosome> chromosomes;
// getters & setters
}
class Chromosome {
private String name;
//getter/setters
}
But it's not working because of the extra fields "assembly" & "chromosome", so with a JSON like :
{"name":"mm9",
"id":32,
"chromosomes":[
{"name":"MT"}
] }}
it simply working.
Is there a way to modify configuration or something to achieve this without create more complex POJOS?
The problem is that in the first JSON snippet, chromosomes is a dictionary (Map), of which one of the entries (chromosome) happens to correspond to your Chromosome object.
A more accurate direct mapping to a Java class would be
class Assembly{
...
private Map<String, Chromosome> chromosomes;
}
Since you mention you can't control the format of the source JSON, you may want to look into using custom deserializers, or perhaps using the streaming support from Jackson rather than ObjectMapper for direct mapping, if you aren't happy changing your POJOs in this way.
By the way, it is best to refer to collections by their interface type (List) rather than a concrete type (ArrayList). It is very unlikely that code that refers to this class truly cares or needs to know that it is using an ArrayList, referring to just the List interface instead makes it a lot easier to swap other implementations in if needed (as a general principle).

Use different bean class in Jackson JSON based on variable?

I have JSON like the following:
[{
'kind':'1',
'value1': 'foo',
'value2': 'bar',
...
},
{
'kind':'2',
'value1': 'foo',
'value2': 'bar',
...
}
..]
Basically a list of objects with the same variables. In my code, I'd like to create an ArrayList of some class A, which would contain these objects. However, I'd like each object to be of subclass One or Two, depending on the 'kind' value.
How can I accomplish this?
Thanks!
This is what Jackson calls "polymorphic type handling". There's a good explanation of how to do this here. You need to tell Jackson to put the class name into the JSON when you serialize it, and use that class name when you deserialize it. This is done via annotation:
#JsonTypeInfo(use=JsonTypeInfo.Id.NAME,
include=JsonTypeInfo.As.PROPERTY, property="kind")
[Source: #StaxMan (below).]
If you don't have control over the JSON format, you can use Jackson to deserialize it into some common intermediate object and then write code that creates the desired subclass object from it. Alternatively, use the json.org library to deserialize the JSON string into an org.json.JSONObject, and then write code to construct your desired objects based on the JSONObject's properties.

Categories

Resources