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();
}
Related
I'm new to android development and trying to learn it. I recently ran into an issue, when I use get method I get a response as below:
As there is a status given as '0' from the backend I'm unable to catch the "response_data" array.
Could anyone please guide me how can I catch the response.
Thanks.
API CLIENT:
public class ApiClient {
private final static String BASE_URL = "http://api.xxxxxx.com/app/";
public static ApiClient apiClient;
private Retrofit retrofit = null;
public static ApiClient getInstance() {
if (apiClient == null) {
apiClient = new ApiClient();
}
return apiClient;
}
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;
}
}
MAIN ACTIVITY:
public class MainActivity extends AppCompatActivity {
TextView tvResponse;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tvResponse=findViewById(R.id.tvResponse);
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();
}
});
}
}
RESPONSE DATA:
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;
}
}
In this case you need to let Gson know how you want to parse your json.
You can add many specific TypeAdapter's for each specific class case or you can create one TypeAdapterFactory that will be used to parse all your jsons. Remember to add it to your Retrofit builder.
This code example is a TypeAdapterFactory that will ignore status and parse only response_data to your object.
class ResponseDataTypeAdapterFactory implements TypeAdapterFactory {
public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> type) {
TypeAdapter<T> delegate = gson.getDelegateAdapter(this, type);
TypeAdapter<JsonElement> elementTypeAdapter = gson.getAdapter(JsonElement.class);
return new TypeAdapter<T>() {
public void write(JsonWriter out, T value) throws IOException {
delegate.write(out, value);
}
public T read(JsonReader reader) throws IOException {
JsonElement jsonElement = elementTypeAdapter.read(reader);
if (jsonElement.isJsonObject()) {
JsonObject jsonObject = jsonElement.getAsJsonObject();
if (jsonObject.has("response_data")) {
jsonElement = jsonObject.get("response_data");
}
}
return delegate.fromJsonTree(jsonElement);
}
};
}
}
And on your Retrofit builder
Gson gson = new GsonBuilder()
.registerTypeAdapterFactory(ResponseDataTypeAdapterFactory())
.create();
new Retrofit.Builder()
.baseUrl(BASE_URL)
.client(client.build())
.addConverterFactory(new GsonConverterFactory.create(gson))
.build();
And at the Retrofit interface, you only need to call the class that corresponds with response_datamapping.
public interface ApiInterface {
#GET("/product-data")
Call<List<ResponseDataItem>> fetchData();
}
With this implementation, you can remove your ResponseData class and care only about the important model.
Make an interface
public interface ApiInterface {
#GET
Call<JsonElement> getTimeDifference(#Url String url);
}
Crate an Retrofit client calss
public class RetrofitClient {
private static final String TAG = "RetrofitClient";
public static Retrofit geBaseUrl() {
Retrofit retrofit = null;
HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
if (BuildConfig.DEBUG) {
interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
}else{
interceptor.setLevel(HttpLoggingInterceptor.Level.NONE);
} OkHttpClient client = new OkHttpClient.Builder().addInterceptor(interceptor).build();
if (retrofit==null) {
retrofit = new Retrofit.Builder()
.baseUrl("...your base url...")
.client(client)
.addConverterFactory(GsonConverterFactory.create())
.build();
}
return retrofit;
}
}
String endpoint = "...your end point...";
ApiInterface ret = RetrofitClient.geBaseUrl(url).create(ApiInterface.class);
Call<JsonElement> call = ret.getTimeDifference(endpoint);
call.enqueue(new Callback<JsonElement>() {
#Override
public void onResponse(Call<JsonElement> call, Response<JsonElement> response) {
try {
Log.d("String", "onResponse: response" + response.body().toString());
} catch (Exception e) {
}
}
#Override
public void onFailure(Call<JsonElement> call, Throwable t) {
Log.d("response", "onFailure: " + t + " " + call);
}
});
For Catching response you use interceptor like HttpLoggingInterceptor ,stetho,chuck
Creating the Retrofit instance
// Add the interceptor to OkHttpClient
OkHttpClient client=new OkHttpClient().newBuilder()
.addNetworkInterceptor(new StethoInterceptor()) \\ StethoInterceptor
.addInterceptor(new ChuckInterceptor(context)) \\ ChuckInterceptor
.connectTimeout(30, TimeUnit.SECONDS)
.readTimeout(5, TimeUnit.MINUTES)
.writeTimeout(5, TimeUnit.MINUTES)
.build();
public static final String BASE_URL = "http://api.myservice.com/";
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.client(client)
.build();
for stetho interceptor
implementation 'com.facebook.stetho:stetho:1.5.0'
implementation 'com.facebook.stetho:stetho-okhttp3:1.5.0'
for chuck
debugImplementation 'com.readystatesoftware.chuck:library:1.1.0'
releaseImplementation 'com.readystatesoftware.chuck:library-no-op:1.1.0'
I want to use retrofit for fetching data from my server. My server send data as a string json.
I create a server like this:
public class ServiceGenerator {
public static final String BASE_URL = "http://192.168.100.73/ChartReport/Service1.svc/";
static OkHttpClient okHttpClient = new OkHttpClient.Builder()
.connectTimeout(1, TimeUnit.MINUTES)
.readTimeout(30, TimeUnit.SECONDS)
.writeTimeout(15, TimeUnit.SECONDS)
.build();
private static Retrofit.Builder builder =
new Retrofit.Builder()
.baseUrl(BASE_URL)
.client(okHttpClient)
.addConverterFactory(GsonConverterFactory.create());
private static Retrofit retrofit = builder.build();
public static <S> S createService(Class<S> serviceClass) {
return retrofit.create(serviceClass);
}
}
And then i have created client like blow:
public interface IReportCLient {
#POST("json/GetDataReport")
Call<ResponseBody> getReporst();
}
And I have used into my activity :
IReportCLient service = ServiceGenerator.createService(IReportCLient.class);
Call<ResponseBody> reporst = service.getReporst();
reporst.enqueue(new Callback<ResponseBody>() {
#Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
try {
JsonObject post = new JsonObject().get(response.body().string()).getAsJsonObject();
} catch (IOException e) {
e.printStackTrace();
}
}
#Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
}
});
When I run my app in debug mode for first time i fetch my data by this command:
response.body().string()
but immediately my result is null when i run response.body().string() again??
What is happens?
string() method can only be called once on RequestBody. So it will return empty string if you try to call it again. This is true for debugging as well. If you try to evaluate expressions response.body().string() while debugging, your actual methods will get empty string.
An HTTP response. Instances of this class are not immutable: the
response body is a one-shot value that may be consumed only once and
then closed. All other properties are immutable.
https://square.github.io/okhttp/3.x/okhttp/okhttp3/Response.html
Read this as well https://stackoverflow.com/a/32307866/6168272
This is how I get JsonObject from my response object. You can give it a try.
private JSONObject parseJsonFromResponse(Response response) {
ResponseBody responseBody = response.body();
if (responseBody != null) {
try {
return new JSONObject(responseBody.string());
} catch (JSONException | IOException e) {
e.printStackTrace();
return new JSONObject();
}
} else return new JSONObject();
}
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);
I am using retrofit to post the request to server but it is posting data twice. I have checked code, I made only on call. I know retrofit trying to connect server again and again until it connected or timeout but if once data posted to server and I get the response from server than why retrofit making again call for the same.
Call<LoanSaveResponse> call = apiService.saveLoan(loan);
call.enqueue(new retrofit2.Callback<LoanSaveResponse>() {
#Override
public void onResponse(Call<LoanSaveResponse> call, Response<LoanSaveResponse> response) {
customProgressBar.stopProgressBar();
Log.e(" response", new Gson().toJson(response));
if (response != null) {
if (response.body() != null) {
// Showing Alert Message
showDialog(response.body().loan_id);
}
}
}
#Override
public void onFailure(Call<LoanSaveResponse> call, Throwable t) {
customProgressBar.stopProgressBar();
Log.e("Failed", t.toString());
}
});
}
public class ApiClient {
/*http://172.16.40.1:8080/loyalty/*/
//:http://54.83.7.62:8080/loyalty/userAnswer
private static Retrofit retrofit = null;
public static Retrofit getClient() {
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(GlobalBaseUrl.BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.client(client)
.build();
}
return retrofit;
}
}
For Retrofit 2
Define a listener in your web service instance:
public interface OnConnectionTimeoutListener {
void onConnectionTimeout();
}
Add an interceptor to your web service:
public WebServiceClient() {
OkHttpClient client = new OkHttpClient();
client.setConnectTimeout(10, TimeUnit.SECONDS);
client.setReadTimeout(30, TimeUnit.SECONDS);
client.interceptors().add(new Interceptor() {
#Override
public Response intercept(Chain chain) throws IOException {
return onOnIntercept(chain);
}
});
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.client(client)
.build();
webService = retrofit.create(WebService.class);
}
Enclose your intercept code with the try-catch block and notify the listener when an exception happens:
private Response onOnIntercept(Chain chain) throws IOException {
try {
Response response = chain.proceed(chain.request());
String content =
UtilityMethods.convertResponseToString(response);
Log.d(TAG, lastCalledMethodName + " - " + content);
return;
response.newBuilder().body
(ResponseBody.create
(response.body().contentType(), content))
.build();}
catch (SocketTimeoutException exception) {
exception.printStackTrace();
if(listener != null)
listener.onConnectionTimeout();
}
return chain.proceed(chain.request());
}
Callback is not working on some screens sometimes while many times it's working perfectly. I have almost done project with this library. So kindly help
My ApiClient code is:
public class ApiClient {
public static final String BASE_URL = AppUtils.MainURL;
private static Retrofit retrofit = null;
public static Retrofit getClient(final String token) {
OkHttpClient defaultHttpClient = new OkHttpClient.Builder()
.addInterceptor(
new Interceptor() {
#Override
public Response intercept(Interceptor.Chain chain) throws IOException {
Request request = chain.request().newBuilder()
.addHeader("AccessToken", token).build();
return chain.proceed(request);
}
}).retryOnConnectionFailure(true).connectTimeout(1, TimeUnit.MINUTES)
.readTimeout(1, TimeUnit.MINUTES)
.writeTimeout(1, TimeUnit.MINUTES).build();
if (retrofit == null) {
retrofit = new Retrofit.Builder()
.baseUrl(BASE_URL)
.client(defaultHttpClient)
.addConverterFactory(GsonConverterFactory.create())
.build();
}
return retrofit;
}
}
and calling method is:
ApiInfo apiService =
ApiClient.getClient(preference.getToken()).create(ApiInfo.class);
Call<JobDetailsResponse> responseCall = apiService.getJobDetails(preference.getLoginId(), preference.getToken(), "" + jobId);
responseCall.enqueue(new Callback<JobDetailsResponse>() {
#Override
public void onResponse(Call<JobDetailsResponse> call, Response<JobDetailsResponse> response) {
progressDialog.dismiss();
JobDetailsResponse jobDetailsResponse = response.body();
}
#Override
public void onFailure(Call<JobDetailsResponse> call, Throwable t) {
progressDialog.dismiss();
}
});