Retrofit response does not contain response data - android

I am hitting this API https://westus.dev.cognitive.microsoft.com/docs/services/563309b6778daf02acc0a508/operations/563309b7778daf06340c9652/console
below is my retrofit code. I am not able to send raw JSON in retrofit.
public void createProfileAPI()
{
ApiInterface apiService = ApiClient.getClientRequest().create(ApiInterface.class);
try
{
//pbVrd.setVisibility(View.VISIBLE);
JSONObject paramObject = new JSONObject();
paramObject.put("locale", "en-us");
LocaleModel localeModel = new LocaleModel();
localeModel.setLocale("en-us");
Call<BaseModel> call = apiService.SearchResponse(localeModel);
call.enqueue(new Callback<BaseModel>()
{
#Override
public void onResponse(Call<BaseModel> call, Response<BaseModel> response)
{
int responseCode = response.code();
Log.d("Deepakw" , responseCode+"");
BaseModel response1 = response.body();
Log.d("Deepak" , response.body().getIdentificationProfileId() + " //// " +response1.getIdentificationProfileId()+"");
}
#Override
public void onFailure(Call<BaseModel> call, Throwable t)
{
Log.d("Responce Failed ", "failed Response Mersen Fuse ");
String message = t.getMessage();
Log.d("failure", message);
}
});
}
catch (Exception e)
{
e.printStackTrace();
}
}
public class ApiClient {
public static final String BASE_URL = "https://westus.api.cognitive.microsoft.com/spid/v1.0/";
private static Retrofit retrofit = null;
public static Retrofit getClientRequest() {
if (retrofit == null) {
retrofit = new Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build();
}
return retrofit;
}
}
public interface ApiInterface {
#Headers({
"Content-Type: application/json",
"Ocp-Apim-Subscription-Key: 0219cf3e3d444f0584f80b3a84613d12"
})
#POST("verificationProfiles")
Call<BaseModel> SearchResponse(#Body LocaleModel body);
};
I am not able to get response
API client
Please help

//In ApiInterface do like this
#Headers("charset:UTF-8")
#POST("verificationProfiles")
Call<BaseModel> SearchResponse(
#Header("Content-Type") String contentType,
#Body LocaleModel body);
have you tried #SerializedName("") and #Expose in your pojo class
#SerializedName("status")
#Expose
private Boolean status;

Instead of JSONObject, you can use Map
For example:
Headers("Content-Type: application/json")
#POST("/apipath")
request(#Body Map<String, String> body);

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"
}

Login with retrofit in android

I am trying to use login api via retrofit. I need to send only mobile number. When i am using postman body it is getting an output. but when iam calling with android its getting an error json like below
{
"error": "Validation error",
"error_code": "001",
"Validation_errors": {
"mobile": "<p>The Mobile field is required.</p>"
}
}
HomeActivity.class
ApiInterface apiService =
ApiClient.getClient().create(ApiInterface.class);
Map<String,String> user = new HashMap<>();
user.put("mobile",username.getText().toString().trim());
Call<ResponseBody> mService = apiService.loginwithno(user);
Log.d("TAG", "response: " + mService.toString());
mService.enqueue(new Callback<ResponseBody>() {
#Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
if (response.isSuccessful()) {
try {
String result = response.body().string();
JSONObject mJsonObject = new JSONObject(result);
Log.d("TAG", "response: " + mJsonObject.toString());
} catch (JSONException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
} else {
buttonVisible();
username.setError("Please try again");
}
}
#Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
call.cancel();
buttonVisible();
Snackbar snackbar = Snackbar.make(buttonLogin,
"Please check your internet connection", Snackbar.LENGTH_LONG);
snackbar.show();
}
ApiClient
public class ApiClient {
public static final String BASE_URL = "http://nast.in/driverpool/api/index.php/";
private static Retrofit retrofit = null;
public static Retrofit getClient() {
retrofit = new Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build();
return retrofit;
}
}
ApiInterface
public interface ApiInterface {
#POST("account/login?")
Call<ResponseBody> loginwithno(#Body Map<String, String> mobile);
#POST("account/verifyotp")
Call<ResponseBody> verifyotp(#Body HashMap<String, String> mobile);//Param name: mobile, otp
#POST("account/resendotp")
Call<ResponseBody> resentotp(#Body HashMap<String, String> mobile);
}
Postman screenshot
First you don't need '?' in your api and i think you must send json in your #body so create class like this
public class SendLoginData{
#SerializedName("mobile")
public String mobile;
public SendLoginData(String mobile) {
this.mobile = mobile;
}
}
And use it in ApiInterface
#POST("account/login")
Call<ResponseBody> loginwithno(#Body SendLoginData post);
You need to make few changes in code.
Change your login api to receive json like this, include gson library if you have not added in project.
#POST("account/login?")
Call loginwithno(#Body Map mobile);
Create an ApiErrorResponse object to handle your api error. Add getter, setter and #SerializedName as required.
class ApiErrorResponse{
String error;
String error_code;
ValidationErrors Validation_errors;
}
class ValidationErrors{
String mobile;
}
on API error handle like this
if(!response.isSuccessful()){
Converter converter =
ApiClient.getClient().responseBodyConverter(ApiErrorResponse.class, new Annotation[0]);
ApiErrorResponse errors = null;
try {
errors = converter.convert(response.errorBody());
} catch (Exception e) {
}
if(errors!=null){
//Handle your API Error logic here
}
}

Retrofit json data passing

Below are the files for retrofit.
While passing the data in the form of JSON I am getting a null response.
Could anyone guide where can be the issue occurring?
I am trying to post the data in the form of JSON using the retrofit library. Can you suggest me the right approach?
My code:
public class ApiSellarClient {
public static final String BASE_URL = "Constant.BASE_URL";// it is from constant file..
private static Retrofit retrofit = null;
public static Retrofit getClient() {
HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
OkHttpClient client = new OkHttpClient.Builder().addInterceptor(interceptor).build();
if (retrofit == null) {
retrofit = new Retrofit.Builder()
.baseUrl(BASE_URL)
.client(client)
.addConverterFactory(ScalarsConverterFactory.create())
.addConverterFactory(GsonConverterFactory.create())
.build();
}
return retrofit;
}
}
public class ApiSellarConnection {
public static Call<String> getSignInData(JSONObject json) {
return ApiSellarClient.getClient().create(ApiSellarInterface.class).getSignInData(json);
}
}
public interface ApiSellarInterface {
#Headers("Content-Type: application/json")
#POST("integration/customer/token")
Call<String> getSignInData(#Body JSONObject json);
}
// Below is the controller class.
JSONObject paramObject = new JSONObject();
try {
paramObject.put("username", etUserName.getText().toString());
paramObject.put("password", etPassword.getText().toString());
ApiSellarConnection.getSignInData(paramObject).enqueue(new Callback<String>() {
#Override
public void onResponse(Call<String> call, Response<String> response) {
Log.d("tag", "helper" + response.body());
}
#Override
public void onFailure(Call<String> call, Throwable t) {
}
});
} catch (JSONException e) {
e.printStackTrace();
}

Retrofit 2 - string error body is empty

Server returns JSON object in case of success and simple String for error case.
There are no problems with parsing JSON into object. The problem rises when I want to parse error since the response.errorBody().string() is empty.
When I send the same request using Postman the response as follows:
And I can't read this error... Anyone faced such problem?
Code code
gradle:
compile 'com.squareup.retrofit2:retrofit:2.0.0-beta4'
compile 'com.squareup.retrofit2:converter-gson:2.0.0-beta4'
compile 'com.squareup.okhttp:okhttp:2.6.0'
RestClient.java:
private static GitApiInterface gitApiInterface;
...
public static GitApiInterface getClient() {
if (gitApiInterface == null) {
OkHttpClient okClient = new OkHttpClient();
okClient.interceptors().add(new Interceptor() {
#Override
public Response intercept(Chain chain) throws IOException {
Response response = chain.proceed(chain.request());
return response;
}
});
Retrofit client = new Retrofit.Builder()
.baseUrl(URL_BASE)
.addConverterFactory(GsonConverterFactory.create())
.build();
gitApiInterface = client.create(GitApiInterface.class);
}
return gitApiInterface;
}
ApiInterface.java:
public interface ApiInterface {
#POST("/register/user/{email}/")
Call<User> postRegisterUser(#Path(value = "email", encoded = true) String email,
#Query("firstname") String firstName,
#Query("lastname") String lastName,
#Query("country") String country,
#Query("phone") String phone,
#Query("deviceid") String deviceId);
...
ServerRequests.java:
public void registerUser(#NonNull String email,
#NonNull String firstName,
#NonNull String lastName,
#NonNull String country,
#NonNull String phone,
#NonNull String deviceId,
#NonNull final RegisterUserCallback callback) {
showProgressBar();
RestClient.GitApiInterface service = RestClient.getClient();
Call<User> call = service.postRegisterUser(email, firstName, lastName, country, phone, deviceId);
call.enqueue(new Callback<User>() {
#Override
public void onResponse(Call<User> call, Response<User> response) {
hideProgressBar();
User user = response.body(); //this works great
if (response.isSuccess()) {
Log.d(TAG, "REGISTER success: " + response.message());
callback.onRegisteredUser(user);
} else {
try {
Log.e(TAG, "REGISTER fail: " + response.errorBody().string()); //empty error body
callback.onRegisterFailed(response.errorBody().string());
} catch (IOException e) {
e.printStackTrace();
}
}
}
#Override
public void onFailure(Call<User> call, Throwable t) {
hideProgressBar();
callback.onRegisterFailed("error");
}
});
}
My answer is based on HttpLoggingInterceptor class.
I wrote getStatusError() method by given in parameter response.errorBody().
private StatusError getStatusError(ResponseBody responseBody) {
StatusError statusError = null;
if (responseBody != null) {
try {
BufferedSource source = responseBody.source();
if (source != null) {
source.request(Long.MAX_VALUE); // Buffer the entire body.
Buffer buffer = source.buffer();
Charset charset = UTF8;
MediaType contentType = responseBody.contentType();
if (contentType != null) {
charset = contentType.charset(UTF8);
}
String string = buffer.clone().readString(charset);
if (!TextUtils.isEmpty(string)) {
GsonBuilder gsonBuilder = new GsonBuilder();
Gson gson = gsonBuilder.create();
statusError = gson.fromJson(string, StatusError.class);
}
}
} catch (Exception e) {
LogUtils.LOGW(TAG, "Impossible to get StatusError stream", e);
}
}
return statusError;
}
StatusError is a POJO class to map (JSON) elements:
public class StatusError {
#SerializedName("message")
public String message;
#SerializedName("errors")
public ArrayList<ErrorDetail> errors;
}

How to send Form data in retrofit2 android

Hi i have a json to send to the server (POST METHORD){"country":"india","devicetype":"android"} it is in form data model
like the key for this json is data ie is the server accept it like
data={"country":"india","devicetype":"android"} am using retrofit i use Multipart like this
#Multipart
#POST("initiate")
#Headers({
"Content-Type: application/json",
"Cache-Control: no-cache"
})
Call<UserInfoServerResponse> getUserInfoRequest(#Part(value="data") UserInfo mUserInfo);
here UserInfo is the json but am getting fail message from server after that i used FormUrlEncoded methord
#FormUrlEncoded
#POST("initiate")
#Headers({
"Content-Type: application/json",
"Cache-Control: no-cache"
})
Call<UserInfoServerResponse> getUserInfoRequest(#Field(value="data",encoded = false) String mUserInfo);
its out put is also same failure result from server, but the data sending to the server is in the formate
data=%7B%22country%22%3A%22india%22%2C%22devicetype%22%3A%22%22%7D
My UserInfo.class
public class UserInfo {
public String country;
public String devicetype;
public UserInfo( String country,String devicetype) {
this.country=country;
this.devicetype=devicetype;
}
}
My adaptor class
RemoteRetrofitInterfaces mService;
Retrofit mRetrofit;
HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
OkHttpClient client = new OkHttpClient.Builder()
.connectTimeout(20, TimeUnit.SECONDS)
.writeTimeout(20, TimeUnit.SECONDS)
.readTimeout(30, TimeUnit.SECONDS).addInterceptor(interceptor)
.build();
mRetrofit = new Retrofit.Builder()
.baseUrl(AppConstant.HOST).addConverterFactory(GsonConverterFactory.create())
.client(client)
.build();
mService = mRetrofit.create(RemoteRetrofitInterfaces.class);
Call<UserInfoServerResponse> api = mService.getUserInfoRequest(new Gson().toJson(mUserInfo));
api.enqueue(new Callback<UserInfoServerResponse>() {
#Override
public void onResponse(Call<UserInfoServerResponse> responseCall, Response<UserInfoServerResponse> response) {
if (response.body().status != null) {
if (response.body().status.equals("success")) {
Log.d(TAG, "success---");
}
} else {
Log.d(TAG, "Failed---");
}
}
#Override
public void onFailure(Call<UserInfoServerResponse> responseCall, Throwable t) {
t.printStackTrace();
}
});
so how can i send the json to server using retrofit successfully i gone through the retofit document and follow couple of steps but i dont get any result. can any one help me in this
Thank you
finally i found the solution hope this will help some other
i achieve the solution by using FieldMap
of retrofit.
#POST("initiate")
#FormUrlEncoded
Call<UserInfoServerResponse> getUserInfoRequest(#FieldMap Map<String,String> params);
and in the Rest Adaptor section i changed request data from string to Hashmap form like following
Log.d(TAG, "sendUserInfo called");
UserInfo mInfo = new UserInfo("countyname","android");
String request = new Gson().toJson(mUserInfo);
// Here the json data is add to a hash map with key data
Map<String,String> params = new HashMap<String, String>();
params.put("data", request);
Call<UserInfoServerResponse> api = mService.getUserInfoRequest(params);
api.enqueue(new Callback<UserInfoServerResponse>() {
#Override
public void onResponse(Call<UserInfoServerResponse> responseCall, Response<UserInfoServerResponse> response) {
if (response.body().status != null) {
if (response.body().status.equals("success")) {
Log.d(TAG, "success---" + response.body());
}
} else {
Log.d(TAG, "Failed---");
}
}
#Override
public void onFailure(Call<UserInfoServerResponse> responseCall, Throwable t) {
t.printStackTrace();
}
});
Basilcally what I used #FormUrlEncoded for form data and #FieldMap to put my request JSON as a key value. i got solution by following this method, hope this will help some one :)
The above solution works but is cumbersome to use , a better solution will be to use a converter for #Multipart formData
Please use the bellow code for proceeding with #Multipart FormData
This is because
"" is added to your posting strings
import java.io.IOException;
import java.lang.annotation.Annotation;
import java.lang.reflect.Type;
import okhttp3.MediaType;
import okhttp3.RequestBody;
import okhttp3.ResponseBody;
import retrofit2.Converter;
import retrofit2.Retrofit;
/**
* Created by kural on 10/27/17.
*/
public class StringConverterFactory extends Converter.Factory {
private static final MediaType MEDIA_TYPE = MediaType.parse("text/plain");
public static StringConverterFactory create() {
return new StringConverterFactory();
}
#Override
public Converter<ResponseBody, ?> responseBodyConverter(Type type, Annotation[] annotations, Retrofit retrofit) {
if (String.class.equals(type)) {
return new Converter<ResponseBody, String>() {
#Override
public String convert(ResponseBody value) throws IOException {
return value.string();
}
};
}
return null;
}
#Override
public Converter<?, RequestBody> requestBodyConverter(Type type, Annotation[] parameterAnnotations, Annotation[] methodAnnotations, Retrofit retrofit) {
if (String.class.equals(type)) {
return new Converter<String, RequestBody>() {
#Override
public RequestBody convert(String value) throws IOException {
return RequestBody.create(MEDIA_TYPE, value);
}
};
}
return null;
}
}
and in your retrofit client add this line
.addConverterFactory(StringConverterFactory.create())
public class RetroFitClient {
private static Retrofit retrofit = null;
public static Retrofit getClient(String baseUrl) {
if (retrofit==null) {
HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
OkHttpClient client = new OkHttpClient.Builder().addInterceptor(interceptor).build();
/*retrofit = new Retrofit.Builder()
.baseUrl(baseUrl)
.client(client)
.addConverterFactory(GsonConverterFactory.create())
.build();*/
retrofit = new Retrofit.Builder()
.baseUrl(baseUrl)
.client(client)
.addConverterFactory(StringConverterFactory.create())
.addConverterFactory(GsonConverterFactory.create())
.build();
}
return retrofit;
}
This works fine for me and return a json to obtain new valid Microsoft Azure Token :
My end point :
#PostMapping(value = "/get-new-token", consumes = {"application/JSON"}, produces = {"application/JSON"})
#Timed
public ResponseEntity<String> getNewToken(#RequestBody String refreshToken) throws IOException {
JSONObject json = tokenService.getNewTokenByRefreshToken(refreshToken);
return new ResponseEntity<>(json.toString(), HttpStatus.OK);
}
My getGraphRepository :
public GraphRepository getGraphRepository() {
HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
OkHttpClient client = new OkHttpClient.Builder()
.addInterceptor(interceptor).build();
// Create and configure the Retrofit object
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(" https://login.microsoftonline.com")
.client(client)
.addConverterFactory(JacksonConverterFactory.create())
.build();
// Generate the graph repo
return retrofit.create(GraphRepository.class);
}
My Token Service :
public JSONObject getNewTokenByRefreshToken(String refreshToken) throws IOException {
GraphRepository graphRepository = getGraphRepository();
// My list of -> Key : Value
Map<String,String> params = new HashMap<String, String>();
params.put("grant_type", "refresh_token");
params.put("client_id", this.client_id);
params.put("client_secret", client_secret);
params.put("refresh_token", refreshToken);
RefreshToken data = graphRepository.getRefreshToken(tenantId, params).execute().body();
JSONObject json = new JSONObject(data);
return json;
}
My GraphRepository :
#POST("/{tenant_id}/oauth2/v2.0/token")
#FormUrlEncoded
Call<RefreshToken> getRefreshToken(
#Path("tenant_id") String tenant_id,
#FieldMap Map<String, String> params
);
I hope this can help someone.

Categories

Resources