How does Retrofit convert to objects? - java

In their example (http://square.github.io/retrofit), the third code block appears to retrieve data in the type List<Repo>, but where does the conversion from a string to a JSON array to List<Repo> occur? I'm a bit lost as to how Retrofit works.
In trying to replicate this with my own REST api, (json -> List<User>)...
java.lang.IllegalArgumentException: Could not locate call adapter for java.util.List<com.keenant.app.User>.

Behind the scenes, Retrofit uses Gson to convert the JSON to domain objects. In your case, Gson can't deserialize your User object. You'll probably need to register a custom TypeAdapter so that Gson knows how to handle your User objects.

Related

Gson get unused data in java class POJO

I am developing an API that reads data generate by another program. The data is in a json format and I want to use Gson to read that json data into a json object and also report any unused data that hasn't been specified in the class. For example, I have this json:
{"Event": "ChatMessageSent", "Message": "This is a test message!", "Time":1628466226}
Now, the class only has the Event String and Message String, so it will only store that data. My question is how can I set up my POJO Class or get Gson to also return the Time data in a special method that returns all unused data, so it can be sent to a debug log for throwing a warning for unused data. Since the data may change at any version, I need to create a logging system that tells me if the API missed some data.
Any pointers are much appreciated, thanks in advance!
How about creating a custom GSon deserializer for the fields you need. You could look into TypeAdaptor.

why addConverterFactory is need in Retrofit

My question is around Retrofit and GSON. I know GSON is used for JAVA object <-> JSON . I know that Retrofit parses our response. What i don't understand is why we need GsonConverterFactory .Also why is addConverterFactory needed in retrofit
UPDATE:
Pojo objects in Kotlin are data classes and annotation use is as in Java
ANSWER:
If your application is Restful, so gets and sends data from / to server
Converter factory need to be added, just for retrofit can convert JSON data (got from server) into java (model) objects (POJO), to use in Android Project.
There are some converter libraries for converting JSON to Java objects,
(GSON, Jackson..etc) you have to decide which converter you want to use in your project and add same factory
Dependencies in app.gradle
implementation "com.squareup.retrofit2:converter-gson:VERSION"
and Factories in Retrofit settings
GsonConverterFactory or JacksonConverterFactory
Retrofit.Builder().addConverterFactory(GsonConverterFactory.create());
Also if the remote data type is XML, you need to add SimpleXmlConverterFactory
if the json converters don't meet your needs you'll need to Add a customized converter factory for serialization and deserialization of your objects. consider this case.
i wish you'll find this article helpful.
The world is not just json and gson. There are other formats that you can use to implement Rest Apis, i.e. XML.
Also, in the world of json parsers there's not only gson but way more like Jackson and Moshi.
It would be extremely difficult to maintain all possible format converters inside Retrofit, so it offloads the parsing to classes that implement the interface for a converter. Putting this behind a factory lets Retrofit decouple even the creation of these converters, so it can have different ones for different responses and requests.
This also allows you to have multiple converters within the same Retrofit instance and it's also an easy way to let you implement your own converter.
All in all, this decoupling allows for way more flexibility than coupling it with specific libraries.
If you are using Spring, you should create a mapper configuration (or use a default, like in this example), in the retrofit configuration, you should att this code:
#Bean
fun retrofitBuilder(): Retrofit.Builder {
return Retrofit.Builder()
.addConverterFactory(JacksonConverterFactory.create(ObjectMapper()))
}
Then, in your application could read and write Kotlin data class Json, even with no # information.

Why we need POJO when we can use jsonObject in Restful services

Currently I am working in a project where we are using restful services and jdbc connection. We can handle request response either by jsonObject or with a POJO class. I am confused between these. which one to use and why?
Yes you can read response by using either but if you use jsonObject it will give you an immutable JSON object value. Now it all comes down to your requirement if you have a requirement where you don't need to change any value then you can directly read the response and send it to where ever you want but if you are doing any modification then you need POJO with getter and setter methods.
Similarly in case of creating a request you can use below code:
JsonObject object = Json.createObjectBuilder().build();
but then you end up creating all the nodes and child which is ok for small request but it there are more fields in request then using POJO is a good idea.
POJO:
Its a simple blue print that defines the properties with getter and setter.
jsonObject:
This is a simple data interchangeable format used for client-server interaction
You can use both. If you are receiving Json request or response as string you can convert it to a Json object. Then you can map that fields into POJO class and use them through the POJO class to build your code logic.

Gson streaming API with different types of objects according to value of JSON field

I'm trying to parse the Wikidata JSON dump using the Gson streaming API, since the file is around 70GB of json. The overall structure of the file is as follows:
[
{"type":"item",... other fields ...},
{"type":"property",... other fields ...},
.....
]
It is an array of objects in which each object can be of type item or property and I would like to instantiate a different class (namely I have a corresponding Item and Property class in my Java code) according to the object that I encounter.
Basically, I'd like to look at the type field and then parse the following JSON accordingly. Since the JsonReader doesn't seem to provide a getNextJsonObject() or similar function, is there a way to do this besides preprocessing the whole file and splitting the entries into two separate ones? The file is so big that I'd like to avoid the extra preprocessing step when I could do everything on the fly.
I actually found a very easy solution after a bit of thinking. The Gson API provides the method:
Gson.fromJson(JsonReader reader, Class class)
This will read the next object from the reader and deserialize to the class you pass as parameter. Since in my case I don't know which class to serialize to I can do the following:
JsonObject asd = gson.fromJson(reader, JsonObject.class);
if (asd.get("type").getAsString().equals("item")) {
// Instantiate item
} else {
// Instantiate property
}

Alternative GSON Fields

So basically, I'm using GSON to parse some JSON on Android, and when grabbing a List of objects using JavaBeans I came across an issue - one of the object types has 2 variants
These 2 JSON objects are exactly identical except there can either be a String field (field 'a'), or an object field (field 'b')
Is it possible to get GSON to accept a JSON object with either one of these 2 options, and just leave the field that's not included in the JSON as null in the Java object?
Thanks
I recommend using either Jackson or Moshi for working with JSONs and avoid using Gson in your next project, as it is much slower for deserialization and while marginally faster than Moshi at serializing objects, the resulting JSON might be larger due to the HTML-compatible escape characters that Gson inserts into it.

Categories