Response is not coming from server using retrofit2 - java

Hi in the below code i have a get method from get method parsing the json response using retrofit library.
For the below challenge class parsing the json response through pojo classes and but response is not coming from server .
can any one please help to resolve this issue
response :
{
success: true,
result: {
token: TOKENSTRING, // Challenge token to be used for login.
serverTime: TIMESTAMP, // Current Server time
expireTime: TIMESTAMP // Time when token expires
}
}
GetChallenge.java:
private void getchallenge() {
//Here a logging interceptor is created
HttpLoggingInterceptor logging = new HttpLoggingInterceptor();
logging.setLevel(HttpLoggingInterceptor.Level.BODY);
//The logging interceptor will be added to the http client
OkHttpClient.Builder httpClient = new OkHttpClient.Builder();
httpClient.addInterceptor(logging);
final GetNoticeDataService service = RetrofitInstance.getRetrofitInstance().create(GetNoticeDataService.class);
/** Call the method with parameter in the interface to get the notice data*/
Call<ManageChallenge> call = service.getChallengeList();
/**Log the URL called*/
Log.wtf("URL Called", call.request().url() + "");
call.enqueue(new Callback<ManageChallenge>() {
#Override
public void onResponse(Call<ManageChallenge> call, Response<ManageChallenge> response) {
if(response.isSuccessful() ) {
ManageChallenge challenge=response.body();
// String response1=response.body().toString();
String success=challenge.getSuccess().toString();
if(success.equals("true")){
String result= challenge.getResult().toString();
try {
JSONObject jsonObject =new JSONObject(result);
String token = jsonObject.getString("token");
Log.i("token", "token" + token);
String serverTime =jsonObject.getString("serverTime");
Log.i("serverTime", "serverTime" + serverTime);
String expireTime =jsonObject.getString("expireTime");
Log.i("expireTime", "expireTime" + expireTime);
} catch (JSONException e) {
e.printStackTrace();
}
}
Log.i("REsult", "Get submitted to API." + challenge);
}
}
#Override
public void onFailure(Call<ManageChallenge> call, Throwable t) {
Toast.makeText(LoginActivity.this, "Something went wrong...Error message: " + t.getMessage(), Toast.LENGTH_SHORT).show();
}
});
}
RetrofitInstance.java:
public class RetrofitInstance {
private static Retrofit retrofit;
private static final String BASE_URL = "http://XXXXXXXXXXXX/";
/**
* Create an instance of Retrofit object
* */
public static Retrofit getRetrofitInstance() {
if (retrofit == null) {
retrofit = new retrofit2.Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build();
}
return retrofit;
}
}
GetNoticeDataService.java:
public interface GetNoticeDataService {
#Headers("Content-Type: application/json")
#GET("webservice.php?operation=getchallenge&username=admin")
Call<ManageChallenge> getChallengeList();
}
ManageChallenge.java:
public class ManageChallenge {
#SerializedName("success")
private String success;
#SerializedName("result")
private List <getChallengeList> result;
public String getSuccess() {
return success;
}
public void setSuccess(String success) {
this.success = success;
}
public List<getChallengeList> getResult() {
return result;
}
public void setResult(List<getChallengeList> result) {
this.result = result;
}
}
getChallengeList.java:
public class getChallengeList {
#SerializedName("token")
#Expose
private String token;
#SerializedName("serverTime")
#Expose
private String serverTime;
#SerializedName("expireTime")
#Expose
private String expireTime;
public String getToken() {
return token;
}
public void setToken(String token) {
this.token = token;
}
public String getServerTime() {
return serverTime;
}
public void setServerTime(String serverTime) {
this.serverTime = serverTime;
}
public String getExpireTime() {
return expireTime;
}
public void setExpireTime(String expireTime) {
this.expireTime = expireTime;
}
public getChallengeList(String tokens, String expireTimes, String serverTimes){
token = tokens;
expireTime = expireTimes;
serverTime = serverTimes;
}
}
Postman response:
{"success":true,"result":{"token":"5e2ab99eb318f","serverTime":1579858334,"expireTime":1579858634}}

According to your response, there is no List there for the issue is here
#SerializedName("result")
private List<GetChallengeList> result;
Change it like this
public class ManageChallenge {
#SerializedName("success")
private String success;
#SerializedName("result")
private GetChallengeList result;
public String getSuccess() {
return success;
}
public void setSuccess(String success) {
this.success = success;
}
public GetChallengeList getResult() {
return result;
}
public void setResult(GetChallengeList result) {
this.result = result;
}
}
GetChallengeList class
public class GetChallengeList {
#SerializedName("token")
#Expose
private String token;
#SerializedName("serverTime")
#Expose
private String serverTime;
#SerializedName("expireTime")
#Expose
private String expireTime;
public String getToken() {
return token;
}
public void setToken(String token) {
this.token = token;
}
public String getServerTime() {
return serverTime;
}
public void setServerTime(String serverTime) {
this.serverTime = serverTime;
}
public String getExpireTime() {
return expireTime;
}
public void setExpireTime(String expireTime) {
this.expireTime = expireTime;
}
public GetChallengeList(String tokens, String expireTimes, String serverTimes){
token = tokens;
expireTime = expireTimes;
serverTime = serverTimes;
}
}

In your postman response, "result" return a json object, but in your ManageChallenge.java. You declare result as List of object. So I thinks that it may cause some error when casting.
PS. You should declare your class name with upper case at the 1st character. If not, it's may cause some confuse in the future.
PS2. Sorry for my terrible English skill.

I dont understand this you are using retrofit and getting the response using json object, directly you can pass you model call into retrofit and than easily get the data using the model call . responce.body().challenge().getResult().toString()

Related

I want to add a bearer token to my retrofit post request

I have an app that is to register people into a platform but I get a response of Unauthenticated each time I submit the form data. The form is submitted using an API which requires a bearer token for each post request with the aid of retrofit. I have been out of touch with Java.
Note: its just a plain form. No authentication has been implemented in the app.
My ApiClient.java class
public class ApiClient {
private static Retrofit getRetrofit(){
HttpLoggingInterceptor httpLoggingInterceptor = new HttpLoggingInterceptor();
httpLoggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
OkHttpClient okHttpClient = new OkHttpClient.Builder().addInterceptor(httpLoggingInterceptor).build();
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("xxxxxxxxxxxxx")
.addConverterFactory(GsonConverterFactory.create())
.client(okHttpClient)
.build();
return retrofit;
}
public static UserService getUserService(){
UserService userService = getRetrofit().create(UserService.class);
return userService;
}
}
My UserService.java class
public interface UserService {
#POST("algonapi/api/enroll_vehicle")
Call<UserResponse> saveUser(#Body UserRequest userRequest);
}
My saveUser Method
public void saveUser(UserRequest userRequest){
Call<UserResponse> userResponseCall = ApiClient.getUserService().saveUser(userRequest);
userResponseCall.enqueue(new Callback<UserResponse>() {
#Override
public void onResponse(Call<UserResponse> call, Response<UserResponse> response) {
if (response.isSuccessful()){
Toast.makeText(MainActivity.this, "Registration Successfull! Click on Reset Form to Start a New Enumeration...", Toast.LENGTH_LONG).show();
}else {
Toast.makeText(MainActivity.this, "Registration Failed!", Toast.LENGTH_LONG).show();
}
}
#Override
public void onFailure(Call<UserResponse> call, Throwable t) {
Toast.makeText(MainActivity.this, "Registration Failed!" +t.getLocalizedMessage(), Toast.LENGTH_LONG).show();
}
});
}
My UserRequest
package com.example.xxxxx;
public class UserRequest {
private String FullName;
private String StickerNumber;
private String Address;
private String Email;
private String Phone;
private String Nationality;
private String State;
private String LGA;
private String RC;
private String DriversLicenseNo;
private String LicenseIssued;
private String LicenseExpiry;
private String VehicleType;
private String VehicleLicense;
private String VehicleTyres;
private String LGAofOperation;
private String NOKFullName;
private String NOKAddress;
private String NOKPhone;
private String NOKEmail;
private String NOKNationality;
private String NOKState;
public String getFullName() {
return FullName;
}
public void setFullName(String fullName) {
FullName = fullName;
}
public String getStickerNumber() {
return StickerNumber;
}
public void setStickerNumber(String stickerNumber) {
StickerNumber = stickerNumber;
}
public String getAddress() {
return Address;
}
public void setAddress(String address) {
Address = address;
}
public String getEmail() {
return Email;
}
public void setEmail(String email) {
Email = email;
}
public String getPhone() {
return Phone;
}
public void setPhone(String phone) {
Phone = phone;
}
public String getNationality() {
return Nationality;
}
public void setNationality(String nationality) {
Nationality = nationality;
}
public String getState() {
return State;
}
public void setState(String state) {
State = state;
}
public String getLGA() {
return LGA;
}
public void setLGA(String LGA) {
this.LGA = LGA;
}
public String getRC() {
return RC;
}
public void setRC(String RC) {
this.RC = RC;
}
public String getDriversLicenseNo() {
return DriversLicenseNo;
}
public void setDriversLicenseNo(String driversLicenseNo) {
DriversLicenseNo = driversLicenseNo;
}
public String getLicenseIssued() {
return LicenseIssued;
}
public void setLicenseIssued(String licenseIssued) {
LicenseIssued = licenseIssued;
}
public String getLicenseExpiry() {
return LicenseExpiry;
}
public void setLicenseExpiry(String licenseExpiry) {
LicenseExpiry = licenseExpiry;
}
public String getVehicleType() {
return VehicleType;
}
public void setVehicleType(String vehicleType) {
VehicleType = vehicleType;
}
public String getVehicleLicense() {
return VehicleLicense;
}
public void setVehicleLicense(String vehicleLicense) {
VehicleLicense = vehicleLicense;
}
public String getVehicleTyres() {
return VehicleTyres;
}
public void setVehicleTyres(String vehicleTyres) {
VehicleTyres = vehicleTyres;
}
public String getLGAofOperation() {
return LGAofOperation;
}
public void setLGAofOperation(String LGAofOperation) {
this.LGAofOperation = LGAofOperation;
}
public String getNOKFullName() {
return NOKFullName;
}
public void setNOKFullName(String NOKFullName) {
this.NOKFullName = NOKFullName;
}
public String getNOKAddress() {
return NOKAddress;
}
public void setNOKAddress(String NOKAddress) {
this.NOKAddress = NOKAddress;
}
public String getNOKPhone() {
return NOKPhone;
}
public void setNOKPhone(String NOKPhone) {
this.NOKPhone = NOKPhone;
}
public String getNOKEmail() {
return NOKEmail;
}
public void setNOKEmail(String NOKEmail) {
this.NOKEmail = NOKEmail;
}
public String getNOKNationality() {
return NOKNationality;
}
public void setNOKNationality(String NOKNationality) {
this.NOKNationality = NOKNationality;
}
public String getNOKState() {
return NOKState;
}
public void setNOKState(String NOKState) {
this.NOKState = NOKState;
}
}
Create the OkHttpClient like this
OkHttpClient okHttpClient = new OkHttpClient.Builder().addInterceptor(new Interceptor() {
#NotNull
#Override
public Response intercept(#NotNull Chain chain) throws IOException {
Request request=chain.request().newBuilder()
.addHeader("Authorization", "Bearer " + token)
.build();
return chain.proceed(request);
}
}).build();
If you most of your https requests need authentication then the first answer is perfect but if some of your requests need then you can pass the header to each methods.
public interface UserService {
#POST("algonapi/api/enroll_vehicle")
Call<UserResponse> saveUser(
#Header("Authorization") String token,
#Body UserRequest userRequest
);
}
While calling the method simply pass your token along with userRequest.

How to show a list in Android by using retrofit library?

I have to show A list in an Activity
MY API key is:
http://api.cuidadotechnologies.com/NSSPL/leave_dtls.php
Using GSON converter and retrofit library.
this API throws response in JSON like this
{
"status": 0,
"response_data": [
{
"id": "12",
"uid": "USER00000003",
"reason": "Test",
"type": "Plan Leave",
"SataDate": "2018-09-18",
"EndDate": "2018-09-25",
"ApprovedBy": "USER00000002",
"ApprovedDate": "2018-09-18",
"Status": "REJECTED",
"Remarks": "Test Reject"
},
{
"id": "13",
"uid": "USER00000003",
"reason": "Wedding",
"type": "Plan Leave",
"SataDate": "2018-01-28",
"EndDate": "2018-02-05",
"ApprovedBy": "USER00000002",
"ApprovedDate": "2018-09-18",
"Status": "APPROVED",
"Remarks": "Ok"
}
]
}
I am novice in this method please help me to do this step by step.
Try this way..
make retrofit object..
public class ApiClient {
private final static String BASE_URL = "http://api.cuidadotechnologies.com/NSSPL/";
public static ApiClient apiClient;
private Retrofit retrofit = null;
public static ApiClient getInstance() {
if (apiClient == null) {
apiClient = new ApiClient();
}
return apiClient;
}
//private static Retrofit storeRetrofit = null;
public Retrofit getClient() {
return getClient(null);
}
private Retrofit getClient(final Context context) {
HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
OkHttpClient.Builder client = new OkHttpClient.Builder();
client.readTimeout(60, TimeUnit.SECONDS);
client.writeTimeout(60, TimeUnit.SECONDS);
client.connectTimeout(60, TimeUnit.SECONDS);
client.addInterceptor(interceptor);
client.addInterceptor(new Interceptor() {
#Override
public okhttp3.Response intercept(Chain chain) throws IOException {
Request request = chain.request();
return chain.proceed(request);
}
});
retrofit = new Retrofit.Builder()
.baseUrl(BASE_URL)
.client(client.build())
.addConverterFactory(GsonConverterFactory.create())
.build();
return retrofit;
}
}
make interface for api calling.
public interface ApiInterface {
#GET("leave_dtls.php")
Call<ResponseData> getData();
}
make pojo class for response.
public class ResponseDataItem{
#SerializedName("Status")
private String status;
#SerializedName("uid")
private String uid;
#SerializedName("reason")
private String reason;
#SerializedName("ApprovedDate")
private String approvedDate;
#SerializedName("Remarks")
private String remarks;
#SerializedName("ApprovedBy")
private String approvedBy;
#SerializedName("id")
private String id;
#SerializedName("type")
private String type;
#SerializedName("EndDate")
private String endDate;
#SerializedName("SataDate")
private String sataDate;
public void setStatus(String status){
this.status = status;
}
public String getStatus(){
return status;
}
public void setUid(String uid){
this.uid = uid;
}
public String getUid(){
return uid;
}
public void setReason(String reason){
this.reason = reason;
}
public String getReason(){
return reason;
}
public void setApprovedDate(String approvedDate){
this.approvedDate = approvedDate;
}
public String getApprovedDate(){
return approvedDate;
}
public void setRemarks(String remarks){
this.remarks = remarks;
}
public String getRemarks(){
return remarks;
}
public void setApprovedBy(String approvedBy){
this.approvedBy = approvedBy;
}
public String getApprovedBy(){
return approvedBy;
}
public void setId(String id){
this.id = id;
}
public String getId(){
return id;
}
public void setType(String type){
this.type = type;
}
public String getType(){
return type;
}
public void setEndDate(String endDate){
this.endDate = endDate;
}
public String getEndDate(){
return endDate;
}
public void setSataDate(String sataDate){
this.sataDate = sataDate;
}
public String getSataDate(){
return sataDate;
}
}
final response..
public class ResponseData {
#SerializedName("response_data")
private List<ResponseDataItem> responseData;
#SerializedName("status")
private int status;
public void setResponseData(List<ResponseDataItem> responseData){
this.responseData = responseData;
}
public List<ResponseDataItem> getResponseData(){
return responseData;
}
public void setStatus(int status){
this.status = status;
}
public int getStatus(){
return status;
}
}
called api into fragment or activity like this way..
ApiInterface apiInterface = ApiClient.getInstance().getClient().create(ApiInterface.class);
Call<ResponseData> responseDataCall=apiInterface.getData();
responseDataCall.enqueue(new Callback<ResponseData>() {
#Override
public void onResponse(Call<ResponseData> call, Response<ResponseData> response) {
if (response.isSuccessful() && response.body()!=null && response!=null){
List<ResponseDataItem> data=response.body().getResponseData();
}
}
#Override
public void onFailure(Call<ResponseData> call, Throwable t) {
t.printStackTrace();
}
});
You can use use POJO classes for converting JSON into classes. Use below website to convert JSON to POJO.
http://www.jsonschema2pojo.org
After that you can use Retrofit to call API and get response. Get reference from this site : https://square.github.io/retrofit/
After you convert into classes you can use Gson Methods for conversion.
SomeModelClass responseModel = new Gson().fromJson(response, SomeModelClass.class);
You can use this addConverterFactory(GsonConverterFactory.create()) retrofit method to directly convert response into class model if you don't want to do it manually.
And finally you can Create adapter using ViewHolder Pattern and use that adapter with RecyclerView.

How to fix Expected BEGIN_OBJECT in Retrofit?

In my application i want use Retrofit for get some data from server.
I write below codes but when run application and call api show me below error :
E/socketLogResponse: Err : com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was STRING at line 1 column 1 path $
Please see my above codes and help me
API response from server :
{
"status": "ok",
"time": 0.014972925186157227
}
ApiService interface :
#POST("api/log")
Call<SocketPingResponse> getSocketPingLog(#Header("jwt") String jwt, #Body SocketPingBodySendData socketPingBodySendData);
SocketPingResponse class :
public class SocketPingResponse {
#SerializedName("status")
#Expose
private String status;
#SerializedName("time")
#Expose
private Double time;
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public Double getTime() {
return time;
}
public void setTime(Double time) {
this.time = time;
}
}
SocketPingBodySendData class :
public class SocketPingBodySendData {
#SerializedName("auction_id")
#Expose
int auction_id;
#SerializedName("data")
#Expose
List<SocketPingEntity> data;
public int getAuction_id() {
return auction_id;
}
public void setAuction_id(int auction_id) {
this.auction_id = auction_id;
}
public List<SocketPingEntity> getData() {
return data;
}
public void setData(List<SocketPingEntity> data) {
this.data = data;
}
}
Api call codes in activity :
pingEntityList.addAll(socketPingDatabase.socketPingDao().getSocketPingEntityList());
SocketPingBodySendData pingBodySendData = new SocketPingBodySendData();
pingBodySendData.setAuction_id(auctionID);
pingBodySendData.setData(pingEntityList);
Toast.makeText(context, ""+pingEntityList.size(), Toast.LENGTH_SHORT).show();
Call<SocketPingResponse> pingResponseCall = apis.getSocketPingLog(jwtToken, pingBodySendData);
pingResponseCall.enqueue(new Callback<SocketPingResponse>() {
#Override
public void onResponse(Call<SocketPingResponse> call, Response<SocketPingResponse> response) {
if (response.body() != null) {
Toast.makeText(context, response.body().getStatus(), Toast.LENGTH_SHORT).show();
if (response.body().getStatus().equals("ok")) {
pingEntityList.clear();
socketPingDatabase.socketPingDao().deleteAll();
}
}
}
#Override
public void onFailure(Call<SocketPingResponse> call, Throwable t) {
Log.e("socketLogResponse", "Err : " + t.toString());
}
});
How can i fix this issue?
You need to add a gsonconverter factory before building your api service interface.
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build();
retrofit.create(apiservice.class)

Retrofit/Jackson error on deserializing

i'm trying to get a JSON from my web service and deserialize to my class UserSync, but i'm getting the following error:
Can not instantiate value of type [simple type, class com.example.breno.teste.model.User] from String value (''); no single-String constructor/factory method
at [Source: okhttp3.ResponseBody$BomAwareReader#fbf814f; line: 1, column: 86] (through reference chain: com.example.breno.teste.dto.UserSync["user"])
I've read some posts saying that i need to declare my User class static in UserSync, but when i do that, jackson can't find any user property, even with JsonDescription. Another posts say that i may need to declare a default constructor, so i did.
Here is the UserSync class:
#JsonIgnoreProperties(ignoreUnknown = true)
public class UserSync {
#JsonProperty("status")
private String Status;
#JsonProperty("currentDate")
private String CurrentDate;
#JsonProperty("message")
private String Message;
#JsonProperty("user")
private static User NewUser;
public UserSync() {
}
public String getStatus() {
return Status;
}
public String getCurrentDate() {
return CurrentDate;
}
public String getMessage() {
return Message;
}
public static User getNewUser() {
return NewUser;
}
The User class:
public class User implements Serializable {
#JsonProperty("userKey")
private UUID UserKey;
#JsonProperty("userPassword")
private String UserPassword;
#JsonProperty("userGroupKey")
private UUID UserGroupKey;
#JsonProperty("signInDate")
private String SignInDate;
#JsonProperty("active")
private boolean Active;
#JsonProperty("profilePicturePath")
private String ProfilePic;
#JsonProperty("completeName")
private String UserCompleteName;
#JsonProperty("email")
private String UserEmail;
#JsonProperty("isLogged")
private boolean IsLogged;
public User() {
}
public boolean getIsLogged() {
return IsLogged;
}
public void setIsLogged(boolean isLogged) {
IsLogged = isLogged;
}
public String getUserEmail() {
return UserEmail;
}
public void setUserEmail(String userEmail) {
UserEmail = userEmail;
}
public UUID getUserKey() {
return UserKey;
}
public void setUserKey(UUID userKey) {
UserKey = userKey;
}
public String getUserPassword() {
return UserPassword;
}
public void setUserPassword(String userPassword) {
UserPassword = userPassword;
}
public UUID getUserGroupKey() {
return UserGroupKey;
}
public void setUserGroupKey(UUID userGroupKey) {
UserGroupKey = userGroupKey;
}
public String getSignInDate() {
return SignInDate;
}
public void setSignInDate(String signInDate) {
SignInDate = signInDate;
}
public boolean getActive() {
return Active;
}
public void setActive(boolean active) {
Active = active;
}
public String getProfilePic() {
return ProfilePic;
}
public void setProfilePic(String profilePic) {
ProfilePic = profilePic;
}
public String getUserCompleteName() {
return UserCompleteName;
}
public void setUserCompleteName(String userCompleteName) {
UserCompleteName = userCompleteName;
}
}
My service class (Using now the postNewUser):
public interface UserService {
#GET("Login/LoginUser?")
Call<UserSync> login(#Query("email") String email, #Query("password") String password);
//region NewUser Services
#GET("Login/VerifyNewUser?")
Call<UserSync> validateNewUser(#Query("email") String email);
#POST("Login/PostNewUser")
Call<UserSync> postNewUser(#Body User user);
//endregion
}
And finally, the JSON:
{
"status": "OK",
"currentDate": "20/07/2017 11:59:02",
"message": "teste",
"user": {
"userKey": "8e2f0d2d-3522-472d-be1d-28791367f4ee",
"email": "teste_teste#hotmail.com",
"userPassword": "123456",
"profilePicturePath": "teste",
"completeName": "Jorge",
"userGroupKey": null,
"signInDate": "2017-07-07T16:26:06.097",
"active": true,
"isLogged": true
}
}
Can someone help me, please?
EDIT 1 - Here is the method that i'm using to do the retrofit call:
public void register(User user) {
Call<UserSync> postCall = new RetrofitInitializator().getUserService().postNewUser(user);
postCall.enqueue(getRegisterCallback());
}
#NonNull
private Callback<UserSync> getRegisterCallback() {
return new Callback<UserSync>() {
#Override
public void onResponse(Call<UserSync> call, Response<UserSync> response) {
User user = response.body().getNewUser();
}
#Override
public void onFailure(Call<UserSync> call, Throwable t) {
Log.e("Register - onFailure", t.getMessage());
}
};
}
EDIT 2 - The retrofitInicializator class:
public class RetrofitInitializator {
private final Retrofit retrofit;
public RetrofitInitializator() {
HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
OkHttpClient.Builder builder = new OkHttpClient
.Builder();
builder.addInterceptor(interceptor);
retrofit = new Retrofit.Builder()
.baseUrl("http://192.168.15.6:7071/api/")
.addConverterFactory(JacksonConverterFactory.create())
.client(builder.build())
.build();
}
public UserService getUserService() {
return retrofit.create(UserService.class);
}
}
I managed to resolve my problem switching the type User to JsonNode and doing the convertion after this.
#JsonProperty("status")
private String Status;
#JsonProperty("currentDate")
private String CurrentDate;
#JsonProperty("message")
private String Message;
#JsonProperty("user")
private JsonNode NewUser;
and the convertion:
private User getUserFromUserAsync(UserSync userSync) throws JsonProcessingException {
ObjectMapper mapper = new ObjectMapper();
return mapper.treeToValue(userSync.getNewUser(), User.class);
}

Android JSON parsing Retrofit

I'm new to Retrofit and JSON and I don't really know how to parse the next json string:
{
"weight":[
{ "bmi":21,
"date":"2016-12-09",
"fat":14.059000015258789,
"logId":1222222222222,
"source":"Aria",
"time":"11:58:24",
"weight":68
},
{ "bmi":21.83,
"date":"2016-12-14",
"logId":1222222222223,
"source":"Aria",
"time":"14:31:39",
"weight":70.7
}
]
}
I just want "weight" and "date" inside weight array. I've created a pojo class following some examples but it's not working.
Also when trying it with my pojo class I couldn't get "weight" as a string (I'll then use it as a double) using .string().
(I know using .toString() shows something like "com.myPackage.MyPojo#xxxx").
For now, I have only been able to get the whole json through ResponseBody:
Call<ResponseBody>call = repository.getFitbitApi().getData();
call.enqueue(new Callback<ResponseBody>() {
#Override
public void onResponse(Call<ResponseBody> call, retrofit2.Response<ResponseBody> response) {
try {
System.out.println(response.body().string());
} catch (IOException e) {
e.printStackTrace();
}
}
#Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
}
});
What am I doing wrong? Here are my pojo classes, just an attempt...:
public class WeightList {
#SerializedName("weight")
#Expose
private ArrayList<WeightLogFitbit> weight = new ArrayList<>();
public WeightList(){
}
public ArrayList<WeightLogFitbit> getWeight() {
return weight;
}
public void setWeight(ArrayList<WeightLogFitbit> weight) {
this.weight = weight;
}
}
And:
public class WeightLogFitbit {
//Variables in my JSON
#SerializedName("bmi")
#Expose
private String bmi;
#SerializedName("date")
#Expose
private String date;
#SerializedName("logId")
#Expose
private String logId;
#SerializedName("source")
#Expose
private String source;
#SerializedName("time")
#Expose
private String time;
#SerializedName("weight")
#Expose
private double weight;
#SerializedName("fat")
#Expose
private String fat;
public WeightLogFitbit(){}
//Getters and setters
public double getWeight() {
return weight;
}
public void setWeight(double weight) {
this.weight = weight;
}
public String getDate() {
return date;
}
public void setDate(String date) {
this.date = date;
}
public String getSource() {
return source;
}
public void setSource(String source) {
this.source = source;
}
public String getBmi(){
return bmi;
}
public void setBmi(String bmi) {
this.bmi = bmi;
}
//
public String getFat(){
return fat;
}
public void setFat(String fat) {
this.fat = fat;
}
public String getTime() {
return time;
}
public void setTime(String time) {
this.time = time;
}
public String getLogId() {
return logId;
}
public void setLogId(String logId) {
this.logId = logId;
}
}
NOTE: I'm using RxSocialConnect library, which implements RxJava, Retrofit 2, OkHttp3 and gson, just in case. I did this following this example.
Rest of classes I'm using:
public class FitbitBtnActivity extends AppCompatActivity {
private FitbitRepository repository;
#Override protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_fitbit_btn);
repository = new FitbitRepository();
setUpFitbit();
}
private void setUpFitbit() {
findViewById(R.id.fitbitbtn).setOnClickListener(v ->
RxSocialConnect.with(this, repository.fitbitService())
.subscribe(response -> response.targetUI().showToken(response.token()),
error -> showError(error))
);
findViewById(R.id.retrievebtn).setOnClickListener(v -> {
Call<ResponseBody>call = repository.getFitbitApi().getData();
call.enqueue(new Callback<ResponseBody>() {
#Override
public void onResponse(Call<ResponseBody> call, retrofit2.Response<ResponseBody> response) {
try {
System.out.println(response.body().string());
} catch (IOException e) {
e.printStackTrace();
}
}
#Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
}
});
//Original code from example in RxSocialConnect
/*.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Action1<Object>() {
#Override
public void call(Object user) {
FitbitBtnActivity.this.showUserProfile(user.toString());
}
},
error -> FitbitBtnActivity.this.showError(error));*/
}
);
}
And:
public class FitbitRepository {
private final FitbitApiRest fitbitApi;
public FitbitRepository() {
fitbitApi = initFitbitApiRest();
}
private FitbitApiRest initFitbitApiRest() {
OkHttpClient client = new OkHttpClient.Builder()
.addInterceptor(new OAuth2Interceptor(FitbitApi20.class))
.build();
return new Retrofit.Builder()
.baseUrl(FitbitApiRest.URL_BASE)
.client(client)
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.addConverterFactory(GsonConverterFactory.create())
.build().create(FitbitApiRest.class);
}
FitbitApiRest getFitbitApi() {
return fitbitApi;
}
interface FitbitApiRest {
String URL_BASE = "https://api.fitbit.com";
#GET("myrequest.json")
Call<ResponseBody> getData();
}
OAuth20Service fitbitService() {
final String client_id = "xxxxx";
final String client_secret = "1xxxxxxxxxxxxxxxxxx";
final String redirect_uri = "http://example.com";
final String permissions = "weight";
return new ServiceBuilder()
.apiKey(client_id)
.apiSecret(client_secret)
.callback(redirect_uri)
.scope(permissions)
.build(FitbitApi20.instance());
}
}
You need to add this to your dependencies:
compile 'com.squareup.retrofit2:converter-gson:your-version'
and then add a gson converter to your Retrofit instance like this:
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://api.example.com")
.addConverterFactory(GsonConverterFactory.create())
.build();
and change your call in the api to return WeightList:
Call<WeightList> getData();

Categories

Resources