Parse RequestBody as a request paramter in Retrofit 2.0 - android

I have to parse the following web service:
http://api.mytracemobile.com/mobile.svc/getHotelApp?data={"AvailabilitySearch":
{"Authority": { "Currency": "USD" },"Cityname": "Jaipur, India", "CheckInDate": "2017-11-18","CheckOutDate": "2017-11-19", "Searchid": "111111", "Room": [{"Guests": {"Adult": [{ "Title": "Mr" },{ "Title": "Mr" }]}},{"Guests": {"Adult": { "Title": "Mr" }}}],"Nationality": "IN"}}
How can I create a RequestBody for it so ?data= also includes in that request body.
Please let me know how this will be implemented
Thanks in Advance

Read about GSON and Retrofit, there are sufficient articles on both.
Instead of above data sample, Check the dummy sample and Model class to understand the process
Sample: A:{B:"",C:"",D:[{D1:""},{D1:""}]}
Models:
Class1 {#SerializedName("A") private Class2 a; }
Class2 { #SerializedName("B") private String b;
#SerializedName("C") private String c;
#SerializedName("D") private Arraylist<Class3> d; }
Class3 { #SerializedName("D1") private String D1; }
Note: Add Getter setter or constructor in Models to access the values.
After this, You can decrypt the JSON response just by passing reference of Class1.
Read about GSON(for #SerializedName) and then about Retrofit to fetch JSON Response also check this StackOverflow post.

Related

Retrofit2 Inconsistency Response from Server in android java

I am new to Android development and learning how to use Retrofit and I am having a hard time to deal with inconsistency response from the server.
There are more than two kinds of responses will be returned from the server.
May I know how to deal with this kind of server response? Should I create different data class to handle it based on the server response?
Server Response
Result - Success
{
"status": true,
"result": {
"id": 1,
"name": "User",
"email": "user#gmail.com"
}
}
Result - Fail
{
"status": false,
"result": []
}
Android Model
public class User implements Serializable {
private boolean status;
private ResultModel result;
public static class ResultModel implements Serializable{
private String id;
private String name;
private String email;
}
}

Json parsing using Gson and Retrofit (Custom Deserializer)

I need to build list of places (from response array create instance of place and finally receive list of places (place in json))?
How to parse it using Gson and Retrofit with custom deserializer?
I have following strucutre:
{
"success": true,
"error": null,
"response": [
{
"loc": {
"lat": 51.50853,
"long": -0.12574
},
"place": {
"name": "London",
"state": "",
"stateFull": "",
"country": "GB",
"countryFull": "United Kingdom",
"region": "",
"regionFull": "",
"continent": "eu",
"continentFull": "Europe"
},
"profile": {
"elevM": 21,
"elevFT": 69,
"pop": 7556900,
"tz": "Europe/London",
"tzname": "BST",
"tzoffset": 3600,
"isDST": true,
"wxzone": null,
"firezone": null,
"fips": null,
"countyid": null
}
},
.............
.............
]
}
You can use Android Studio plugin RoboPOJOGenerator. It is very easy to make model classes from data.
This answer tells how to handle List response in retrofit.
Update
I don't think it is good idea to make custom deserializer just to parse a list. When you can filter or map list after getting response. It will take upto 3-4 lines of code.
If you don't want many classes. then you can safely delete Profile.java and Loc.java in your case, Gson will parse only data that you have declared in your pojo.
Make generic response class
You can make single class for handling all response by using Java Generics. See example.
public class ApiResponse<T> {
#SerializedName("error")
#Expose
private String error;
#SerializedName("success")
#Expose
private boolean success;
#SerializedName("response")
#Expose
private T response;
// make getter setters
}
Now in ApiService you can define response type. Like this
#GET("api/users/login")
Call<ApiResponse<ModelUser>> getUser();
#GET("api/users/login")
Call<ApiResponse<ModelCity>> getCity();
Thus you don't have to create 3 classes every time. This generic class will do work for all response.

handle retrofit error as a gson model

i have a web service for registration. and i have a success response for response code 200 like this
{
"data": {
"email": "azadbar#yahoo.com"
},
"code": 201,
"success": true
}
and i have error response with code 422 like this
{
"message": "The given data was invalid.",
"errors": {
"email": [
"The email has already been taken."
]
}
}
but when also i have problem with password the response error show me like this
{
"message": "The given data was invalid.",
"errors": {
"email": [
"The email must be a valid email address."
],
"password": [
"The password must be at least 6 characters.",
"The password confirmation does not match."
]
}
}
the problem is some field some time show and some time is gone. and also we have some response model and in retrofit interface we should only have One response like RegisterResponse in below sample
#POST("/api/v1/register")
Call<RegisterResponse> register(#Body RegisterRequest request);
how can i handle this response?
You need to create a pojo that means a model class of name RegisterResponse that will have the properties that you are getting in your JSON response. So, according to your example case, it would be like :
Class RegisterResponse{
private Data data;
private String code;
private Boolean success;
private String message;
private Error errors;
}
Class Data{
private String email;
}
Class Error{
private List<String> email;
private List<String> password;
}
Now inside every class, you need to create the getter and setter for every properties that you have included.
So when the response comes then handle it accordingly that mean if it comes null, set the property to null else set the received value for the respective property
You need to make a model with all possible fields and depending on result some will be filled or null.
class Model{
private Data data;
private int code;
private boolean success;
private Errors errors;
private String message;
public isSuccess(){
return success;
}
....
}

Retrofit parse JSON dynamic keys

I'm a newbie in Retrofit. How to parse the Json below using retrofit?
{
"data": {
"Aatrox": {
"id": 266,
"title": "a Espada Darkin",
"name": "Aatrox",
"key": "Aatrox"
},
"Thresh": {
"id": 412,
"title": "o GuardiĆ£o das Correntes",
"name": "Thresh",
"key": "Thresh"
}
},
"type":"champion",
"version":"6.23.1"
}
You could make your model POJO contain a Map<String, Champion> to deserialize into, to deal with the dynamic keys.
Example:
public class ChampionData {
public Map<String, Champion> data;
public String type;
public String version;
}
public class Champion {
public int id;
public String title;
public String name;
public String key;
}
I'm not familiar with Retrofit besides that, but as someone in the comments said, the deserializing is done by Gson:
public ChampionData champions = new Gson().fromJson(json, ChampionData.class);
So to build on to the answer someone else posted, you can then do the following, assuming you've added the GsonConverterFactory:
public interface API {
#GET("path/to/endpoint")
Call<ChampionData> getChampionData();
}
Assuming Retrofit2, the first thing you need to do is call following when building your Retrofit instance.
addConverterFactory(GsonConverterFactory.create())
Then it's just a matter of writing a POJO (e.g. MyPojoClass) that maps to the json and then adding something like following to your Retrofit interface.
Call<MyPojoClass> makeRequest(<some params>);

Custom retrofit json deserializer

I've been using Retrofit library recently and I like it so far. However, I've come across API that returns response with the following structure:
"data":
{
"meta":
{
"code": 200
"data": "data"
},
"body": [
{
"id": "id",
"field1": "data",
"field2": "data"
},
{
"id": "id",
"field1": "data",
"field2": "data"
}]
}
Assuming I have following class:
public class Entity {
long id;
String field1;
String field2;
}
and following interface:
public interface EntityService {
#GET("/api/method")
void getEntities(Callback<List<Entity>> callback);
}
what is the correct way to use Retrofit if I want to get a list of Entity objects from data.body element from response? I know I could have passed Response object in the callback and manually parse it using org.json package or something else, but is there any better way?
Why not just make a class that represents the data like you've already half done? That's what I've done in multiple apps along with other developers:
public class Meta {
String code;
String data;
}
public class Data {
Meta meta;
List<Entity> body;
}
public interface EntityService {
#GET("/api/method")
void getEntities(Callback<Data> callback);
}
It seems that extra data in your result could be re-used. You should use a generic class like this one:
public class Data<E> {
Meta meta;
E body;
public static class Meta {
int code;
String data;
}
}
Then you could use
Data<List<Entity>>
or whatever you want:
public interface EntityService {
#GET("/api/method")
void getEntities(Callback<Data<List<Entity>>> callback);
}

Categories

Resources