XML Parsing using Retrofit - android

I'm trying to make XML Response, but there is an exception.
Exception in onFailure:
org.simpleframework.xml.core.ElementException: Element 'Date' does not have a match in class
Client
public static Retrofit getXMLClient() {
if (retrofitXML == null) {
retrofitXML = new Retrofit.Builder()
.baseUrl(BASE_URL)
.client(okHttpClient)
.addConverterFactory(SimpleXmlConverterFactory.create())
.build();
}
return retrofitXML;
}
Interface
#GET("odds-" + oddsAccessMode + "1"+"?")
Call<PojoOddsResponse> getOddsData(#Query("api_key") String api_key);
API call
ApiInterfaceSR apiService =
ApiClientSR.getXMLClient().create(ApiInterfaceSR.class);
Call<PojoOddsResponse> call = apiService.getOddsData(API_KEY);
call.enqueue(new Callback<PojoOddsResponse>() {
#Override
public void onResponse(Call<PojoOddsResponse> call, Response<PojoOddsResponse> response) {
if (response.body() != null && response.code() == 200) {
try {
String s = response.body().toString();
Log.d(TAG, "onResponse: "+s);
} catch (Exception e) {
Log.e("JSON exception", e.getMessage());
}
}
}
#Override
public void onFailure(Call<PojoOddsResponse> call, Throwable t) {
Log.e("api exception", t.getMessage());
}
});
Help me, please.

Related

Problem in getting values from Json response

I am hitting a URL with four parameters, If parameters not match I will get the Following response.
This is my JSON response:
{
"result": "0"
}
Now my question is. How do I get that result value from response?
Here's, my Retrofit instance
public class RetrofitClientInstance {
private static Retrofit retrofit;
private static final String BASE_URL = "https://URL/";
public static Retrofit getRetrofitInstance() {
if (retrofit == null) {
retrofit = new retrofit2.Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build();
}
return retrofit;
}
}
Retrofit Interface
public interface ApiInterface {
#GET("f/f/ff.php")
Call<Object> verifyUser (#QueryMap Map< String, String > params );
}
Code for getting the response
ApiInterface apiInterface = RetrofitClientInstance.getRetrofitInstance().create(ApiInterface.class);
Call<Object> call = apiInterface.verifyUser(params);
call.enqueue(new Callback<Object>() {
#Override
public void onResponse(Call<Object> call, Response<Object> response) {
Log.e("Code ", response.code() + "");
if (!response.isSuccessful()) {
Log.e("Code ", response.code() + "");
return;
}
// Convert String to json object
JSONObject json = null;
String str_value = null;
try {
json = new JSONObject(String.valueOf(response));
//JSONObject json_LL = json.getJSONObject("result");
// get value from LL Json Object
str_value = json.getString("result"); //<< get value here
} catch (JSONException e) {
e.printStackTrace();
}
// Log.e("Response ", json.length() + "");
Toast.makeText(RegistrationForm.this, str_value, Toast.LENGTH_SHORT).show();
Object responseBody = response.body();
}
#Override
public void onFailure(Call<Object> call, Throwable t) {
Log.e("Failed", t.getMessage() + "");
}
});
Since you're using Gson. You can replace Object with a class that holds the fields that you want to parse.
for example:
public class ResultResponse {
String result;
public String getResult() {
return result;
}
public void setResult(String result) {
this.result = result;
}
}
And change your endpoint method to return this class.
public interface ApiInterface {
#GET("f/f/ff.php")
Call< ResultResponse> verifyUser (#QueryMap Map< String, String > params );
}
Also don't forget to change the remaining code to use the new return type ResultResponse
Call<ResultResponse> call = apiInterface.verifyUser(params);
call.enqueue(new Callback<ResultResponse>() {
#Override
public void onResponse(Call<ResultResponse> call, Response<ResultResponse> response) {
Log.e("Code ", response.code() + "");
if (!response.isSuccessful()) {
Log.e("Code ", response.code() + "");
return;
}
ResultResponse resultResponse = response.body();
String str_value = resultResponse.getResult();
Toast.makeText(RegistrationForm.this, str_value, Toast.LENGTH_SHORT).show();
}
#Override
public void onFailure(Call<Object> call, Throwable t) {
Log.e("Failed", t.getMessage() + "");
}
});

in arraylist data.size() showing 0 which i want to return

please help me how to return data added which i'm using to set data to
cardview in recyclerview.
i didn't understand why arraylist size returning zero.anyone please explain.
private List<NotificationData> prepareData() {
data = new ArrayList<>();
data.clear();
SharedPreferences prfs = getSharedPreferences("userdetails", Context.MODE_PRIVATE);
String outletid = prfs.getString("outletid", "");
String authkey = prfs.getString("authkey", "");
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("http://xxxxxx-yyyyy.zzzz.com/api/v1/outlet/cpf-ghh/" + outletid + "/")
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.addConverterFactory(GsonConverterFactory.create())
.build();
FuelwareInterface fuelwareInterface = retrofit.create(FuelwareInterface.class);
Call<ResponseBody> responce_outlets;
Log.d("authkeyssss", "onClick: "+authkey);
responce_outlets = fuelwareInterface.getallindents(authkey);
responce_outlets.enqueue(new Callback<ResponseBody>() {
#Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
if (response.isSuccessful()) {
try {
String result = response.body().string();
Log.d("like", "*** " + result);
JSONObject jsonObject = new JSONObject(result);
JSONArray jsonObject1=jsonObject.getJSONArray("data");
Log.d("ghllwnmm", "________"+jsonObject1.length());
int i=jsonObject1.length();
data.clear();
for (int j=0;j<i;j++){
JSONObject jsonObject2=jsonObject1.getJSONObject(j);
NotificationData notificationData = new NotificationData(jsonObject2.getString("vehicle_number"),
jsonObject2.getString("indent_number"),jsonObject2.getString("id"),
jsonObject2.getString("fill_type"),jsonObject2.getString("product"),
jsonObject2.getString("fill_date"),jsonObject2.getString("status"),
jsonObject2.getString("litre"),jsonObject2.getString("amount"));
data.add(notificationData);
}
Log.d("lk000jhgfs", "prepareMovieData: "+data.size());
adapter.notifyDataSetChanged();
} catch (IOException e) {
e.printStackTrace();
} catch (JSONException e) {
e.printStackTrace();
}
}else {
Toast.makeText(getApplicationContext(),"Something Went Wrong",Toast.LENGTH_LONG).show();
}
}
#Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
Log.d("failuremethods", "content " + call.toString());
}
});
Log.d("lkjhgfs", "prepareMovieData: "+data.size());
return data;
}
data which i want to return showing size zero which i don't want.
The problem is return statement won't wait till onResponse method is called , so it will return 0 immediately, if you want to get the data, pass an interface to method and use callback to post as in
interface
public interface ResultCallback{
void onResult(List<NotificationData> data);
}
Method
private void prepareData(ResultCallback callback) { //< make it void
// some code
responce_outlets.enqueue(new Callback<ResponseBody>() {
#Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
if (response.isSuccessful()) {
try {
String result = response.body().string();
Log.d("like", "*** " + result);
JSONObject jsonObject = new JSONObject(result);
JSONArray jsonObject1=jsonObject.getJSONArray("data");
Log.d("ghllwnmm", "________"+jsonObject1.length());
int i=jsonObject1.length();
data.clear();
for (int j=0;j<i;j++){
JSONObject jsonObject2=jsonObject1.getJSONObject(j);
NotificationData notificationData = new NotificationData(jsonObject2.getString("vehicle_number"),
jsonObject2.getString("indent_number"),jsonObject2.getString("id"),
jsonObject2.getString("fill_type"),jsonObject2.getString("product"),
jsonObject2.getString("fill_date"),jsonObject2.getString("status"),
jsonObject2.getString("litre"),jsonObject2.getString("amount"));
data.add(notificationData);
}
callback.onResult(data); //<this will push data back to caller
Log.d("lk000jhgfs", "prepareMovieData: "+data.size());
adapter.notifyDataSetChanged();
} catch (IOException e) {
e.printStackTrace();
} catch (JSONException e) {
e.printStackTrace();
}
}else {
Toast.makeText(getApplicationContext(),"Something Went Wrong",Toast.LENGTH_LONG).show();
}
}
#Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
Log.d("failuremethods", "content " + call.toString());
}
});
//some code
}
Calling method to get data
prepareData(new ResultCallback(){
#Override
public void onResult(List<NotificationData> data){
// log data.size you will get everything
}
});

retrofit calling json data but its response show null

Here is my code any one help, why it shows response is null? There is some mistake which I cannot found.
public void getAllTasksWithSuccess(){
String url = ""+ RetrofitClient.baseURL +"here is my service code ";
RetrofitClient.createRetrofitInstance();
Call<ResponseBody> call = RetrofitClient.getCallObject("getTodaysTask",url);
call.enqueue(new Callback<ResponseBody>() {
#Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
try {
Log.i("TAG",response.body().string());
} catch (IOException e) {
e.printStackTrace();
}
}
#Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
Log.i("tag2", "Failed : " + t.getMessage());
}
});
}
java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String okhttp3.ResponseBody.string()' on a null object reference
at com.ra.ra.DashboardFragments.FragmentTasks$2.onResponse(FragmentTasks.java:83)
Add below class ServiceGenerator:
public class ServiceGenerator {
public static final String API_BASE_URL = AppConstants.BASE_URL;
private static OkHttpClient.Builder httpClient = new OkHttpClient.Builder();
public static Retrofit retrofit = null;
private static Retrofit.Builder builder =
new Retrofit.Builder()
.baseUrl(API_BASE_URL)
.addConverterFactory(GsonConverterFactory.create());
public static Retrofit retrofit() {
retrofit = builder.client(httpClient.build()).build();
return retrofit;
}
}
And use below ErrorUtils class to parse your response's errorBody:
public class ErrorUtils {
public static ResponseBody parseError(Response<?> response) {
Converter<ResponseBody, ResponseBody> converter =
ServiceGenerator.retrofit()
.responseBodyConverter(ResponseBody.class, new Annotation[0]);
ResponseBody error;
try {
error = converter.convert(response.errorBody());
} catch (IOException e) {
return new ResponseBody();
}
return error;
}
}
And now in your onResponse do as below:
public void getAllTasksWithSuccess(){
String url = ""+ RetrofitClient.baseURL +"here is my service code ";
RetrofitClient.createRetrofitInstance();
Call<ResponseBody> call = RetrofitClient.getCallObject("getTodaysTask",url);
call.enqueue(new Callback<ResponseBody>() {
#Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
if(response.isSuccessful()){
// here your response.body() will not be null
}else{
// here your response.body() will be null
// and here you might get your response in response.errorBody();
ResponseBody res= ErrorUtils.parseError(response);
System.out.println("Response is:"+ res.toString());
}
}
#Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
Log.i("tag2", "Failed : " + t.getMessage());
}
});
}

Downloading of file stops due to TimeOut using Retrofit and OkHTTPClient

I am using Retrofit to download files but after few seconds downloading stops by giving this error "retrofit give Thread suspension timed out: 110 during download" or mostly "JavaBinder: !!! FAILED BINDER TRANSACTION !!! (parcel size = 2840) ," , how to resolve this issue? File could be of any size 5MB,10MB and time of downloading could be any depending upon internet speed. Downloading shouldn't stop in case of latency.
Code :
public void run() {
OkHttpClient.Builder httpClient = new OkHttpClient.Builder()
.addNetworkInterceptor(new Interceptor() {
#Override
public Response intercept(Chain chain) throws IOException {
try {
Response originalResponse = chain.proceed(chain.request());
return originalResponse.newBuilder()
.body(new ProgressResponseBody(originalResponse.body(), progressListener))
.build();
}
catch (Exception e) {
e.printStackTrace();
progressListener.onError(e.getCause()+": "+e.getMessage());
}
return chain.proceed(chain.request());
}
});
AppGlobal.Log("usm_fileUrl","baseUrl= "+BASE_URL+" ,fileName= "+fileName);
Retrofit.Builder builder = new Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
;
Retrofit retrofit = builder.client(httpClient.build()).build();
RetrofitInterface downloadService = retrofit.create(RetrofitInterface.class);
Call<ResponseBody> call = downloadService.downloadFileByUrl(fileName);
this.notificationId = this.mNotification.createNotification(fileTitle,"Downloading...");
call.enqueue(new Callback<ResponseBody>() {
#Override
public void onResponse(Call<ResponseBody> call, final retrofit2.Response<ResponseBody> response) {
if (response.isSuccessful()) {
Log.d(TAG, "Got the body for the file");
new AsyncTask<Void, Long, Void>() {
#Override
protected Void doInBackground(Void... voids) {
saveToDisk(response.body());
return null;
}
}.execute();
} else {
Log.d(TAG, "Connection failed " + response.errorBody());
}
}
#Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
t.printStackTrace();
Log.e(TAG, t.getMessage());
}
});
}

Retrofit POST raw string body

I am using Retrofit to send a POST request to a server. The body of the POST must be in the form jdata={"key1":"value1",...} along with a Content-Type header set to application/x-www-form-urlencoded. I found a similar question but the accepted answer is not working.
Here's what I tried -
My interface
public interface APIHandler {
#Headers("Content-Type: application/x-www-form-urlencoded")
#FormUrlEncoded
#POST(URL)
Call<ResponseBody> getdata(#Field("jdata") String jdata);
}
Call function
public void load() {
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("BASE_URL")
.addConverterFactory(GsonConverterFactory.create())
.build();
// prepare call in Retrofit 2.0
APIHandler iAPI = retrofit.create(APIHandler.class);
String requestBody = "{\"id\":\"value\",\"id1\":\"value2\"}"
Call<ResponseBody> call = iAPI.getData(requestBody);
call.enqueue(new Callback<ResponseBody>() {
#Override
public void onResponse(Call<ResponseBody> c, Response<ResponseBody> response) {
if (response.isSuccess()) {
ResponseBody result = response.body();
String gs = new Gson().toJson(result);
Log.d("MainActivity", "response = " + gs + " status: " + statusCode);
} else {
Log.w("myApp", "Failed");
}
}
#Override
public void onFailure(Call<ResponseBody> c, Throwable t) {
}
});
}
But I receive response = null and status = 200. What am I doing wrong? The expected response is only a string and not a JSON array.
I am leaving this here so that it helps someone.
The above code is correct. As I mentioned in the last line, a plain string response was expected. But since it is not a JSON response, the conversion probably did not work and the response was null. The only solution I could find was to directly convert the response to string -
try {
stresp = response.body().string()
Log.d("MainActivity", "response = " + stresp + " status: " + statusCode);
} catch (IOException e) {
//Handle exception
}
There might be a better way to handle this but that worked for me!
You can use like that. I have tested this and it working fine
public interface APIHandler {
#POST(URL)
Call<ResponseBody> getdata(#Body JsonObject body);
}
Request body:
JsonObject requestBody = new JsonObject();
requestBody.addProperty("id", "value1");
requestBody.addProperty("id1", "value2");
Prepare call in Retrofit 2.0
APIHandler iAPI = retrofit.create(APIHandler.class);
And Call function :
Call<ResponseBody> call = iAPI.getData(requestBody);
call.enqueue(new Callback<ResponseBody>() {
#Override
public void onResponse(Call<ResponseBody> c, Response<ResponseBody> response) {
if (response.isSuccess()) {
String result = response.body().string();
Log.d("MainActivity", "response = " + result);
} else {
Log.w("myApp", "Failed");
}
}
#Override
public void onFailure(Call<ResponseBody> c, Throwable t) {
}
});

Categories

Resources