Retrofit2 returns 999 when I called api - android

I use Retrofit2 to call api, when I do apiTest("http://xxx.xx.xx.xxx:xxxx/", "T001", "Futek10911-01"), the response.code is 999 but it returns correct value in Postman. Where's the problem?
private void apiTest(String url, String machId, String check) throws JSONException {
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(url)
.addConverterFactory(GsonConverterFactory.create())
.build();
MyAPIService myAPIService = retrofit.create(MyAPIService.class);
JSONObject jsonObject = new JSONObject();
jsonObject.put("MACHID", machId);
jsonObject.put("CHECK", check);
Call<GetHostTime> call = myAPIService.getHostTime("sRequest", jsonObject);
call.enqueue(new Callback<GetHostTime>() {
#Override
public void onResponse(Call<GetHostTime> call, Response<GetHostTime> response) {
if(response.isSuccessful()){
Log.d("response ", "isSuccessful");
}else {
Log.d("response code ", response.code() + "");
}
}
#Override
public void onFailure(Call<GetHostTime> call, Throwable t) {
Log.d("Failure", t.getMessage());
}
});
public interface MyAPIService {
#POST("TcLeaseParkAPI/api/ParkingAPI/GetHostTime")
#FormUrlEncoded
Call<GetHostTime> getHostTime(#Field("MACHID") String key, #Field("CHECK") JSONObject jsonObject);
}

Comparing your Postman request and your code. It is clear I feel you are sending the request in wrong manner.
So we modify your Retrofit request as follows
public interface MyAPIService {
#POST("TcLeaseParkAPI/api/ParkingAPI/GetHostTime")
#FormUrlEncoded
Call<GetHostTime> getHostTime(#Field("sRequest") JSONObject jsonObject);
And then your request Call as follows
Call<GetHostTime> call = myAPIService.getHostTime(jsonObject);
Now your JSONObject will go in the key sRequest

Related

Getting error code 400 bad request in retrofit but works on postman

I'm working on an Registraion API
which takes the json input as follow / request perameters
{"httpMethod":"POST",
"firstname":"Ali",
"lastname":"Patel",
"email":"alipatel05#gmail.com",
"password":"12345678",
"country":"Canada",
"state":"Quebec",
"city":"Montreal",
"type":"Parent"}
but when i call the api from android app it gives me bad response with error code 400 but works pretty fine on postman.
my API Client
public class APIClient {
private static Retrofit retrofit = null;
public static final String BASE_URL = "https://5r8ndtx9zc.execute-api.us-east-2.amazonaws.com/";
public static Retrofit getClient() {
HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
OkHttpClient client = new OkHttpClient.Builder().addInterceptor(interceptor).build();
/*Gson gson = new GsonBuilder()
.setLenient()
.create();*/
retrofit = new Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.client(client)
.build();
return retrofit;
}
}
my API interface
public interface APIInterface {
#Headers({
"Content-Type: application/json;charset=utf-8",
"Accept: application/json;charset=utf-8",
"Cache-Control: no-cache"
})
#POST("vaccinesApi")
Call<ResponseBody> registerUser(#Body JSONObject locationPost);
}
and here's my api call
private void registerUser() {
HashMap<String, String> newhashMap = new HashMap<>();
JSONObject hashMap = new JSONObject();
try {
hashMap.put("httpMethod","POST");
hashMap.put("firstname",mEditFirstName.getText().toString().trim());
hashMap.put("lastname",mEditLastName.getText().toString().trim());
hashMap.put("email",mEditEmail.getText().toString().trim());
hashMap.put("password",mEditPassword.getText().toString().trim());
hashMap.put("country","Canada");
hashMap.put("state","Quebec");
hashMap.put("city",mSelectedCity);
hashMap.put("type",mUserType);
} catch (JSONException e) {
e.printStackTrace();
}
Call<ResponseBody> call = apiInterface.registerUser(hashMap);
call.enqueue(new Callback<ResponseBody>() {
#Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
progressDialog.hide();
try {
JSONObject jsonObject = new JSONObject(response.body().toString());
Log.e("SignupFragment", jsonObject.toString());
if (response.code() == 200) {
Toast.makeText(RegistrationActivity.this, "Success",Toast.LENGTH_SHORT).show();
/*Intent intent = new Intent(RegistrationActivity.this, LoginActivity.class);
startActivity(intent);
finishAffinity();*/
} else {
Toast.makeText(RegistrationActivity.this, "Failed",Toast.LENGTH_SHORT).show();
}
} catch (Exception e) {
e.printStackTrace();
}
}
#Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
progressDialog.hide();
call.cancel();
Toast.makeText(RegistrationActivity.this, "Failed",Toast.LENGTH_SHORT).show();
}
});
}
Should i need to changes my interface or there may be some error in my api call?
Thanks in andvance
The issue is with your locationPost type, it should be JsonObject and not JSONObject, so try one of the following approaches
Approach 1
Api Interface
Call<ResponseBody> registerUser(#Body JsonObject locationPost);
Api call
JsonObject obj = new JsonObject();
obj.addProperty("httpMethod","POST");
obj.addProperty("firstname",firstNameValue);
// add the rest of the field
Call<ResponseBody> call = apiInterface.registerUser(obj);
//rest of the logic remains same
Approach 2
create a POJO class representing the object and pass the instance of the object
public class RequestObject{
final String httpMethod, firstname;
// declare member variables for all the keys
RequestObject(String method,String firstname){
this.httpMethod = method;
this.firstname = firstname;
}
}
API Interface
Call<ResponseBody> registerUser(#Body RequestObject locationPost);
Api call
RequestObject requestobject = new RequestObject("POST","firstName");
// add the rest of the field
Call<ResponseBody> call = apiInterface.registerUser(requestObject);
//rest of the logic remains same
I think you have to re-check these parameters carefully.
{
"httpMethod": "POST",
"firstname": "Ali",
"lastname": "Patel",
"email": "alipatel05#gmail.com",
"password": "12345678",
"country": "Canada",
"state": "Quebec",
"city": "Montreal",
"type": "Parent"
}

Unable to perform POST request with retrofit android

While I am trying to perform the post request with retrofit, it is throwing timeout exception. While using postman the API Url is working perfectly fine. Is there any error in the code. This is my code:
ApiInterface apiInterface = ApiClient.getClient().create(ApiInterface.class);
JSONObject jsonObject = new JSONObject();
try {
jsonObject.put("accessToken", token);
Log.e("Token Object", jsonObject.toString());
} catch (JSONException e) {
e.printStackTrace();
}
Call<ResponseBody> callUser = apiInterface.facebookLogin(jsonObject);
dialog.show();
callUser.enqueue(new Callback<ResponseBody>() {
#Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
if (response.code() == 200)
Log.e("Token Object", response.toString());
dialog.dismiss();
}
#Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
Toast.makeText(getContext(), "Sorry! Somme Error Occured" + t.toString(), Toast.LENGTH_LONG).show();
dialog.dismiss();
}
});
This is the interface:
//facebook login
#POST("/api/users/facebooklogin")
Call<ResponseBody> facebookLogin(#Body JSONObject jsonObject);
This is the Retrofit Client
public class ApiClient {
public static final String BASE_URL = "http://192.168.100.15:8000/";
private static Retrofit retrofit = null;
public static Retrofit getClient() {
OkHttpClient client = new OkHttpClient.Builder()
.connectTimeout(100, TimeUnit.SECONDS)
.readTimeout(100,TimeUnit.SECONDS).build();
if (retrofit == null) {
retrofit = new Retrofit.Builder()
.baseUrl(BASE_URL)
.client(client)
.addConverterFactory(GsonConverterFactory.create())
.build();
}
return retrofit;
}
}
This is the successful postman request
Pass the request parameters as RequestBody as follows:
#POST("/api/users/facebooklogin")
Call<ResponseBody> facebookLogin(#Body RequestBody request);
JSONObject jsonObject = new JSONObject();
try {
jsonObject.put("accessToken", token);
Log.e("Token Object", jsonObject.toString());
} catch (JSONException e) {
e.printStackTrace();
}
RequestBody requestBody = RequestBody.create(MediaType.parse("application/json; charset=utf-8"), jsonObject.toString());
Call<ResponseBody> callUser = apiInterface.facebookLogin(requestBody);

How to send responsive array from android using retrofit

I am trying to call web service which receives responsive array. I am sending Hash map with values using retrofit in android but it is giving me 500 internal server error.Following is my code:
#POST("/save")
public void CreateAccount(
#Body Map<String, String> data,
Callback<Response> callback);
That's how you can do this with Retrofit 2
Interface:
#POST("/save")
Call<JsonElement> CreateAccount(#Body RequestBody requestBody);
Request code:
//create JsonObject with key-pair values
JsonObject root = new JsonObject();
root.addProperty("key1", "value1");
root.addProperty("key2", "value2");
//get is as string
String resultJson = root.toString();
//parse it to RequestBody type
RequestBody requestBody = RequestBody.create(MediaType.parse("application/json"), resultJson);
//create adapter
Retrofit restAdapter = new Retrofit.Builder()
.baseUrl(Constants.ROOT_API_URL)
.addConverterFactory(GsonConverterFactory.create())
.build();
IConstructSecureAPI service = restAdapter.create(IConstructSecureAPI.class);
Call<JsonElement> result = service.CreateAccount(requestBody);
result.enqueue(new Callback<JsonElement>() {
#Override
public void onResponse(Call<JsonElement> call, retrofit2.Response<JsonElement> response) {
if(response.isSuccessful()){
JsonElement jsonElement = response.body();
JsonObject withResponse = jsonElement.getAsJsonObject();
}
else{
System.out.println(response.message());
}
}
#Override
public void onFailure(Call<JsonElement> call, Throwable t) {
}
});

Receiving an empty body in retrofit Response

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'

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