I'm using https://github.com/amitshekhariitbhu/Fast-Android-Networking in my project.
Does it support GSON?
if yes how does it work with it?
I tried searching it in the documentation but it only contains information about JacksonParserFactory.
I found a GsonParserFactory in it
Using it like below
AndroidNetworking.setParserFactory(new GsonParserFactory());
but not sure how it works as I always get
org.json.JSONObject
You can use GSON to parse the JSON response to your Java Class Object
private Gson gson;
GsonBuilder gsonBuilder = new GsonBuilder();
gson = gsonBuilder.create();
//If your response id JSON array
AndroidNetworking.get("your_url")
.build()
.getAsJSONArray(new JSONArrayRequestListener() {
#Override
public void onResponse(JSONArray response) {
//For JSON array Response
List<YourModel> responseArray = Arrays.asList(gson.fromJson(response, YourModel[].class));
}
#Override
public void onError(ANError error) {
// handle error
}
});
//If your response is JSON object
AndroidNetworking.post("your_url")
.build()
.getAsJSONObject(new JSONObjectRequestListener() {
#Override
public void onResponse(JSONObject response) {
//For JSON object response
YourModel responseObject = gson.fromJson(response, YourModel.class);
}
#Override
public void onError(ANError error) {
// handle error
}
});
Related
I'm trying to read this JSON using Retrofit but I got this error Could not locate ResponseBody converter for class org.json.JSONObject.
The JSON in ALE2 file
{
"a1":[...],
"a2":[...],
"a3":[...]
}
Code
Retrofit retrofit = new Retrofit.Builder().baseUrl(Constants.BASE_URL).build();
retrofit.create(RetrofitInterface.class).getData().enqueue(new Callback < JSONObject > () {
#Override
public void onResponse(Call < JSONObject > call, Response < JSONObject > response) {
}
#Override
public void onFailure(Call < JSONObject > call, Throwable t) {
}
});
RetrofitInterface
public interface RetrofitInterface {
#GET("ALE2")
Call<JSONObject> getData();
}
I don't want to store them in any model I just want to get the JSON as a string
Your interface should look like this :
public interface RetrofitInterface {
#GET("ALE2")
Call<ResponseBody> getData();
}
To get raw json object return type should be Call<ResponseBody>
Once that is done in response you can handle it like below :
retrofit.create(RetrofitInterface.class).getData().enqueue(new Callback<ResponseBody> () {
#Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
String responseBody = response.body().string();
JSONObject json = new JSONObject(responseBody);
}
#Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
}
});
This is how you can set string in JSON object.
I am using an API the returns a Json object { "results": 1, "data": [...]} on success and a webpage "<DOCTYPE HTML> <HTML>.... </HTML>" on error. How can I handle this? I am using Retrofit 2 and Gson on Android in Java. I am also using two custom deserializers to handle string returned instead of object when a data item errors out.
Have you tried to use the OkHttp3 ResponseBody for your call, and based on the type of the response either parse the Json with Gson or display an error ?
For instance you can create a function that determines if a string is a gson like this:
public static boolean isJson(String Json) {
Gson gson = new Gson();
try {
gson.fromJson(Json, Object.class);
return true;
} catch (com.google.gson.JsonSyntaxException ex) {
return false;
}
}
Then do your retrofit call like this:
Call<ResponseBody> res = yourService.yourmethod();
res.enqueue(new Callback<ResponseBody>() {
#Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
if (response.isSuccessful()) {
try {
String resString = response.body().string();
if (isJson(resString)) {
Gson gson = new Gson();
YourModel responseObject = gson.fromJson(resString, YourModel.class);
// do something with the object
} else { // this is not a Json so most likely your html response
// Do something else, like display an error
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
#Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
t.printStackTrace();
}
});
If you need to parse the html to display what is returned, you can also use Jsoup, here it would be something like Document document = Jsoup.parse(resString);, then do what you need with the result.
You also have the option of using a WebView and directly display the html response in it, with webView.loadData(resString, "text/html", "UTF-8");
According to the response code, you can handle it but it should take care by your backend. Backend developer should give proper error message along with response code.
in case the API returns something else than HTTP 200 OK on error, one can differ:
#Override
public void onResponse(#NonNull Call<SomeModel> call, #NonNull Response<SomeModel> response) {
switch(response.code()) {
case 200: {
if (response.body() != null) {
...
}
break;
}
default: {
if (response.errorBody() != null) {
String content = response.errorBody().string();
...
}
break;
}
}
}
i wanted to post the json object using retrofit.
i have created following interface:
public interface syncinter {
#POST("url")
void sync_data(#Body JSONObject ordObj, Callback<JsonObject> callback);
}
the following data i want it to post.
final JSONObject ordJsonObj = new JSONObject();
JSONArray ordJsonArray = new JSONArray();
try {
ordJsonObj.put("Order_Nos",mOrdArr.size());
for (int i=0; i<mOrdArr.size();i++) {
JSONObject ordObj = new JSONObject();
ordObj.put("Order_No",mOrdArr.get(i).getorderID());
ordObj.put("Order_Date",mOrdArr.get(i).getorderDate());
ordObj.put("Customer_id",mOrdArr.get(i).getCustPKID());
Customer aCust = db.getEmployee(mOrdArr.get(i).getCustPKID());
ordObj.put("Cust_name",aCust.getEmpName());// query DB
ordObj.put("Company_id",sharedpreferences.getString(OrderApplication.CompanyID,"")); // sharedP
ordObj.put("Device_Ref",mOrdArr.get(i).getOrdPKID());// sharedP
ordObj.put("User_ID",sharedpreferences.getString(OrderApplication.UserID,""));// sharedP
JSONArray prodJsonArray = new JSONArray();
ArrayList<Product> mProdArr = db.getAllProductOrder(mOrdArr.get(i).getorderID());
for (int j=0; j<mProdArr.size();j++) {
JSONObject prodObj = new JSONObject();
prodObj.put("Product_id",mProdArr.get(j).getPrID());
prodObj.put("Product_name",mProdArr.get(j).getprName());
prodObj.put("Product_Brand",mProdArr.get(j).getBrandName());
prodObj.put("Qty",mProdArr.get(j).getPrQty());
prodObj.put("Rate",(Double.parseDouble(mProdArr.get(j).getPrAmt()+"")/ mProdArr.get(j).getPrQty()));
prodObj.put("Total_Amount",(Double.parseDouble(mProdArr.get(j).getPrAmt()+"")));
prodJsonArray.put(j, prodObj);
}
ordObj.put("OrderDetails",prodJsonArray);
ordJsonArray.put(i,ordObj);
}
ordJsonObj.put("Orders",ordJsonArray);
Log.d("response", "" + ordJsonObj.toString());
I have written the following retrofit code to post the json object but with this following code I am getting
failure -> error : 400 Bad Request.
RestAdapter adapter = new RestAdapter.Builder()
.setEndpoint(OrderApplication.getBase_URL)
.build();
//Creating object for our interface
syncinter api = adapter.create(syncinter.class);
api.sync_data(ordJsonObj, new Callback<JsonObject>() {
#Override
public void success(JsonObject jsonObject, retrofit.client.Response response) {
}
#Override
public void failure(RetrofitError error) {
Log.d("ERROR", String.valueOf(error));
Toast.makeText(getActivity(),"Order failed to place on Server",Toast.LENGTH_LONG).show();
}
});
i was able to post it using TypedInput declare the api as shown below
#PUT(ServerEndPoint)
void callApi(#Body TypedInput input, Callback<Response> response);
and send the json object like this
TypedInput input = null;
try {
JSONObject obj = new JSONObject();
obj.put("KEY", "value");
input = new TypedByteArray("application/json", obj.toString().getBytes("UTF-8"));
} catch (Exception e) {
e.printStackTrace();
}
callApi(input, new Callback<Response>() {
#Override
public void success(Response response, Response response2) {
}
#Override
public void failure(RetrofitError error) {
}
});
not of relative importance i am using retrofit 1.9
I am using retrofit to get data from http URL.
My Interface Class :
public interface SlotsAPI {
/*Retrofit get annotation with our URL
And our method that will return a Json Object
*/
#GET(url)
retrofit.Call<JSONObject> getSlots();
}
My request method.
public void getResponse(){
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(URL)
.addConverterFactory(GsonConverterFactory.create())
.build();
//Creating an object of our api interface
SlotsAPI api = retrofit.create(SlotsAPI.class);
retrofit.Call<JSONObject> callback = api.getSlots();
callback.enqueue(new Callback<JSONObject>() {
#Override
public void onResponse(Response<JSONObject> response) {
if (response != null) {
Log.d("OnResponse", response.body().toString());
}
}
#Override
public void onFailure(Throwable t) {
t.printStackTrace();
}
});
}
In the response I am receiving an empty body.And the server responds with 200 OK.
D/OnResponse: {}
But when I open the URL in browser I am getting JSONObject on the screen.
you should try like this way ....
public interface SlotsAPI {
/*Retrofit get annotation with our URL
And our method that will return a Json Object
*/
#GET(url)
Call<JsonElement> getSlots();
}
in request method
retrofit.Call<JsonElement> callback = api.getSlots();
callback.enqueue(new Callback<JsonElement>() {
#Override
public void onResponse(Response<JsonElement> response) {
if (response != null) {
Log.d("OnResponse", response.body().toString());
}
}
Please check your JsonObject. If you want to get response in json you must be define a response type JsonObject not JSONObject other wise specify the pojo class in your interface.
I think you are not understanding the retrofit filosofy.
The correct interface should be:
public interface SlotsAPI {
/*Retrofit get annotation with our URL
And our method that will return a Json Object
*/
#GET(url)
JSONObject getSlots();
}
When you call the getSlots method, retrofit will automatically do the HTTP request and return the JSONObject.
You will need to do this out of the main thread.
Make sure that the url of #Get is relative path
#Base URL: always ends with /
#Url: DO NOT start with /
Example:
String URL = http://api.co/base/ ;
And
#GET("webservice/syncdown")
JSONObject getSlots();
You may receiving a list of Slots. the Gson converter will handle it if you sending array of json
#GET(url)
retrofit.Call<List<Slot>> getSlots();
You are using the retrofit 2 or 1? The version 2 still is in beta.
If you are using the version 1. Use this:
public interface SlotsAPI {
/*Retrofit get annotation with our URL
And our method that will return a Json Object
*/
#GET(url)
void getSlots(Callback<JsonElement> callback);
}
With this the call will be asynchronous.
Same problem here, and answer from curiousMind saved my day.
More on the same subject: if you need to get a value from a pair use:
String value = response.body().getAsJsonObject().get("pair_name").getAsString();
Call<Void> getSlots() worked for me.
private void APIRetrofit_method() {
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(RecyclerInterface.JSONURL)
// .client(okHttpClient)
.addConverterFactory(GsonConverterFactory.create())
.build();
RecyclerInterface api = retrofit.create(RecyclerInterface.class);
Call<ResponseBody> call = api.getString(); /// GET METHOD without passing params
// Post METHOD CODE START
// HashMap<String, String> params = new HashMap<String, String>();
// params.put("name", "yuva");
// params.put("pass", "" + "123");
// Call<ResponseBody> call1 = api.getProspectList(params);
// Post METHOD CODE END
call.enqueue(new Callback<ResponseBody>() {
#Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
try {
Log.d(TAG, "GetProspectlistresponse" + "" + response.isSuccessful());
utility.hideProgressDialog();
if (response.isSuccessful()) {
String remoteResponse = new String(response.body().string());
Log.d(TAG, "Holidaylistresponse" + "" + remoteResponse);
try {
JSONObject object = new JSONObject(remoteResponse);
JSONArray array = object.getJSONArray("Holidays_Details");
if (array.toString().equals("[]")) {
holiday_recyclerView.setVisibility(View.GONE);
} else {
holiday_recyclerView.setVisibility(View.VISIBLE);
for (int i = 0; i < array.length(); i++) {
JSONObject c = array.getJSONObject(i);
String holidayDate = c.getString(TAG_HOLIDAYDATE);
String holidayName = c.getString(TAG_HOLIDAYName);
String holidaytype = c.getString(TAG_HOLIDAYtype);
HashMap<String, String> customers = new HashMap<String, String>();
customers.put(TAG_HOLIDAYDATE, holidayDate);
customers.put(TAG_HOLIDAYName, holidayName);
customers.put(TAG_HOLIDAYtype, holidaytype);
arrayList.add(customers);
}
getHolidaylistAdapter.notifyDataSetChanged();
}
} catch (JSONException e) {
e.printStackTrace();
}
} else {
utility.hideProgressDialog();
}
} catch (IOException e) {
e.printStackTrace();
}
#Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
Log.i("ErrorResponsestring", call.toString());
}
});
}
String JSONURL = "https://demonuts.com/Demonuts/JsonTest/Tennis/";
#GET("json_parsing.php")
Call<ResponseBody> getString();
// #POST("getProspectList")
// #FormUrlEncoded
// Call<ResponseBody> getProspectList(#FieldMap HashMap<String, String> body);
implementation 'com.squareup.retrofit2:retrofit:2.0.2'
implementation 'com.squareup.retrofit2:converter-gson:2.0.2'
implementation 'com.squareup.okhttp3:okhttp:4.0.0'
I'm trying to figure out how to extract data from my JSON response and loop through the data. I have the following Retrofit code to request the JSON data from my REST API:
final RestAdapter restAdapter = new RestAdapter.Builder()
.setEndpoint(URL)
.build();
final ApiEndpointInterface apiService = restAdapter.create(ApiEndpointInterface.class);
apiService.getJsonData(1, new Callback<User>() {
#Override
public void success(User user, Response response) {
Gson gson = new GsonBuilder().registerTypeAdapter(User.class, new Deserializer()).create();
User c = gson.fromJson(response.getBody().toString(), User.class);
}
#Override
public void failure(RetrofitError retrofitError) {
retrofitError.printStackTrace();
}
});
And my deserializer:
class Deserializer implements JsonDeserializer<User> {
#Override
public User deserialize(JsonElement je, Type type, JsonDeserializationContext jdc)
throws JsonParseException {
// Get the "content" element from the parsed JSON
JsonElement content = je.getAsJsonObject().get("data");
// Deserialize it. You use a new instance of Gson to avoid infinite recursion
// to this deserializer
return new Gson().fromJson(content, User.class);
}
}
The JSON response:
{
"success":true,
"data":[
{
"id":"1",
"username":"User1"
},
{
"id":"2",
"username":"User2"
}
]
}
Within Retrofit's success callback, I'm not sure how to actually loop through the data's items and extract the data from it (like the person's username).
Create this model classes:
private class ResponseData {
public boolean success;
public List<User> data;
}
private class User {
public String id;
public String username;
}
Now you can do this:
final RestAdapter restAdapter = new RestAdapter.Builder()
.setEndpoint(URL)
.build();
final ApiEndpointInterface apiService = restAdapter.create(ApiEndpointInterface.class);
apiService.getJsonData(1, new Callback<ResponseData>() {
#Override
public void success(ResponseData responseData, Response response) {
for (User u : responseData.data) {
String name = u.username;
// etc
}
}
#Override
public void failure(RetrofitError retrofitError) {
retrofitError.printStackTrace();
}
});