I am trying to implement sendOTP of MSG91.There I have to API ,one for generating otp and another one for verifying otp.But there in post reuest I have to set a header ,so how can I set header in retrofit.I am attaching a pic of what to do.Please help me.enter image description here
post request:-
public class GenerateOTPRequest {
String countryCode;
String mobileNumber;
public GenerateOTPRequest(String countryCode, String mobileNumber) {
this.countryCode = countryCode;
this.mobileNumber = mobileNumber;
}
public String getCountryCode() {
return countryCode;
}
public void setCountryCode(String countryCode) {
this.countryCode = countryCode;
}
public String getMobileNumber() {
return mobileNumber;
}
public void setMobileNumber(String mobileNumber) {
this.mobileNumber = mobileNumber;
}
}
Response:-
public class GenerateOTPResponse {
#SerializedName("status")
#Expose
String status;
#SerializedName("response")
#Expose
String response;
public GenerateOTPResponse(String status, String response) {
this.status = status;
this.response = response;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public String getResponse() {
return response;
}
public void setResponse(String response) {
this.response = response;
}
}
my main activity:-
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_verify_otp);
CalligraphyConfig.initDefault(new CalligraphyConfig.Builder()
.setDefaultFontPath("fonts/opensanslight.ttf")
.setFontAttrId(R.attr.fontPath)
.build()
);
getSupportActionBar().setTitle("Verify Your OTP");
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
enterOTP = (EditText) findViewById(R.id.enter_otp);
verifyOTP = (Button) findViewById(R.id.verify_otp);
didntReceiveOTP = (TextView) findViewById(R.id.verify_otp_didnt_receive_otp);
sharedpreferences = getSharedPreferences(MyPREFERENCES, Context.MODE_PRIVATE);
phone = sharedpreferences.getString(Phone, "notPresent");
Log.d("jkhdds: ", "" + phone);
GenerateOTPRequest generateOTPRequest = new GenerateOTPRequest("","");
generateOTPRequest.setCountryCode("91");
generateOTPRequest.setMobileNumber(phone);
OkHttpClient.Builder httpClient = new OkHttpClient.Builder();
httpClient.addInterceptor(new Interceptor() {
#Override
public Response intercept(Interceptor.Chain chain) throws IOException {
Request original = chain.request();
Request request = original.newBuilder()
.header("application-key", "oEBg-3z4hgcv5X8sk_AYdVDiqpGCN02G3cFRjCK0er6MWhuSHAQDRT3TuJKxzOI__2H3D_gZZWeMJsns92zEm4LlksdilXYePbiFZRc1OLZxZd1DmSQOlmM-MIhDrXOqefgIVJX_deqP0QfRoBZ-PtlqpCtZFRqem1kl_J2Vra8=")
.method(original.method(), original.body())
.build();
return chain.proceed(request);
}
});
OkHttpClient client = httpClient.build();
Retrofit retrofit1 = new Retrofit.Builder()
.baseUrl("https://sendotp.msg91.com/api/")
.addConverterFactory(GsonConverterFactory.create())
.client(client)
.build();
final API service1 = retrofit1.create(API.class);
Call<GenerateOTPResponse> call = service1.generateOTP(generateOTPRequest);
call.enqueue(new Callback<GenerateOTPResponse>() {
#Override
public void onResponse(Call<GenerateOTPResponse> call, retrofit2.Response<GenerateOTPResponse> response) {
//GenerateOTPResponse generateOTPResponse = response.body();
//String status = otpResponse.getStatus();
Log.d("otp response " , response.body().getResponse());
}
#Override
public void onFailure(Call<GenerateOTPResponse> call, Throwable t) {
}
});
Log.d("Tag", String.valueOf(enterOTP.getText()));
OkHttpClient.Builder httpClient1 = new OkHttpClient.Builder();
httpClient.addInterceptor(new Interceptor() {
#Override
public Response intercept(Interceptor.Chain chain) throws IOException {
Request original = chain.request();
Request request = original.newBuilder()
.header("application-key", "oEBg-3z4hgcv5X8sk_AYdVDiqpGCN02G3cFRjCK0er6MWhuSHAQDRT3TuJKxzOI__2H3D_gZZWeMJsns92zEm4LlksdilXYePbiFZRc1OLZxZd1DmSQOlmM-MIhDrXOqefgIVJX_deqP0QfRoBZ-PtlqpCtZFRqem1kl_J2Vra8=")
.method(original.method(), original.body())
.build();
return chain.proceed(request);
}
});
OkHttpClient client1 = httpClient1.build();
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://sendotp.msg91.com/api/")
.addConverterFactory(GsonConverterFactory.create())
.client(client1)
.build();
final API service = retrofit.create(API.class);
Log.d("Tag",enterOTP.getText().toString());
Log.d("Tag","fuck u");
verifyOTP.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
final VerifyOTPRequest verifyOTPRequest = new VerifyOTPRequest("","","");
verifyOTPRequest.setCountryCode("91");
verifyOTPRequest.setMobileNumber(phone);
verifyOTPRequest.setOneTimePassword(enterOTP.getText().toString());
Log.d("Tag",enterOTP.getText().toString());
Call<VerifyOTPResponse> call = service.verifyOTP(verifyOTPRequest);
call.enqueue(new Callback<VerifyOTPResponse>() {
#Override
public void onResponse(Call<VerifyOTPResponse> call, retrofit2.Response<VerifyOTPResponse> response) {
Log.d("Tag", String.valueOf(response.body()));
String message = response.body().getStatus();
Log.d("Tag",message);
if (message.equals("success")) {
Toast.makeText(getApplicationContext(), "Successfully Verified", Toast.LENGTH_LONG).show();
Intent intent1 = getIntent();
String parentActivityName = intent1.getStringExtra("activity");
if (parentActivityName.equals("signup")) {
Intent selectSubject = new Intent(VerifyOTPActivity.this, SelectSubjectActivity.class);
progressDialog.dismiss();
startActivity(selectSubject);
} else {
Intent changepassword = new Intent(VerifyOTPActivity.this, ChangePasswordActivity.class);
progressDialog.dismiss();
startActivity(changepassword);
}
}
Log.d("message csdkhds", "" + message);
Log.d("phonre : ", " " + phone);
}
#Override
public void onFailure(Call<VerifyOTPResponse> call, Throwable t) {
}
});
}
});
}
my interface:-
#POST("generateOTP")
Call<GenerateOTPResponse> generateOTP(#Body GenerateOTPRequest generateOTPRequest);
#POST("verifyOTP")
Call<VerifyOTPResponse> verifyOTP(#Body VerifyOTPRequest verifyOTPRequest);
Just use annotation:
public interface Service {
#Headers("application-Key", your key)
#GET("/example")
Call<List<Example>> getExamples();
}
All examples are available here: https://futurestud.io/tutorials/retrofit-add-custom-request-header
You can use #Header annotation for your api method as it is clearly stated in a documentation https://square.github.io/retrofit/
#Headers("XYZ: value")
you can set it in your base retrofit file
request = original.newBuilder()
.header("header key", "your header)
.header("x-requested-with", "XMLHttpRequest")
.method(original.method(), original.body())
.build();
okhttp3.Response response = chain.proceed(request);
#Header
this is a Retrofit specific annotation which will allow you the pass the request headers to the targeting HTTP endpoint, where every argument represents a request header entry.
Related
I have a function inside a aar module that needs to wait the onResponse() or onError() response by using AndroidNetworking. The output is the return executes first before waiting on whatever response it will received. I'm having a problem on waiting the response to return on my app. I also used synchronized on the function. this is the code on my module
public static synchronized String getActivationData(final Context context, final String api, final String base64Header, final String endpoint, final JSONObject body) {
final String[] result = {null};
new Thread(new Runnable() {
#Override
public void run() {
StrictMode.ThreadPolicy policy =
new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
String baseURL = null;
if (api.equalsIgnoreCase("LOCAL")) {
baseURL = Environments.getMarkLocalAPI();
} else if (api.equalsIgnoreCase("DEVELOPMENT")) {
baseURL = Environments.getDevelopmentAPI();
} else if (api.equalsIgnoreCase("STAGING")) {
baseURL = Environments.getStagingAPI();
} else if (api.equalsIgnoreCase("DEPLOYMENT")) {
baseURL = Environments.getDeploymentAPI();
}
final String finalBaseURL = baseURL;
OkHttpClient okHttpClient = new OkHttpClient().newBuilder()
.connectTimeout(15, TimeUnit.SECONDS)
.readTimeout(15, TimeUnit.SECONDS)
.writeTimeout(15, TimeUnit.SECONDS)
.build();
AndroidNetworking.initialize(context, okHttpClient);
AndroidNetworking.post(finalBaseURL + endpoint)
.setPriority(Priority.HIGH)
.addJSONObjectBody(body)
.addHeaders("Project", base64Header)
.addHeaders("Content-Type", "application/json")
.build()
.getAsJSONObject(new JSONObjectRequestListener() {
#Override
public void onResponse(JSONObject response) {
result[0] = String.valueOf(response);
}
#Override
public void onError(ANError anError) {
if (anError.getErrorCode() != 0) {
result[0] = String.valueOf(anError.getErrorDetail());
} else {
result[0] = String.valueOf(anError.getErrorDetail());
}
}
});
Log.i("data", result[0]);
}
}).start();
return result[0];
}
and calling the function on my App via :
String data = ActivationResponseV2.getActivationData(getContext(), "LOCAL", header, "/sample/response", jsonObject);
may I know what I'm doing wrong?. Thanks!
Response was returned outside the post call: To handle this you can pass a callback method to your function to consume the result when its ready.
public static void getActivationData(final Context context,
final String api, final String base64Header, final String endpoint,
final JSONObject body, Callable<Void> methodParam) {
String baseURL = null;
if (api.equalsIgnoreCase("LOCAL")) {
baseURL = Environments.getMarkLocalAPI();
} else if (api.equalsIgnoreCase("DEVELOPMENT")) {
baseURL = Environments.getDevelopmentAPI();
} else if (api.equalsIgnoreCase("STAGING")) {
baseURL = Environments.getStagingAPI();
} else if (api.equalsIgnoreCase("DEPLOYMENT")) {
baseURL = Environments.getDeploymentAPI();
}
OkHttpClient okHttpClient = new OkHttpClient().newBuilder()
.connectTimeout(15, TimeUnit.SECONDS)
.readTimeout(15, TimeUnit.SECONDS)
.writeTimeout(15, TimeUnit.SECONDS)
.build();
AndroidNetworking.initialize(context, okHttpClient);
AndroidNetworking.post(baseURL + endpoint)
.setPriority(Priority.HIGH)
.addJSONObjectBody(body)
.addHeaders("Project", base64Header)
.addHeaders("Content-Type", "application/json")
.build()
.getAsJSONObject(new JSONObjectRequestListener() {
#Override
public void onResponse(JSONObject response) {
//result[0] = String.valueOf(response);
methodParam.call(String.valueOf(response));
}
#Override
public void onError(ANError anError) {
if (anError.getErrorCode() != 0) {
// result[0] = String.valueOf(anError.getErrorDetail());
} else {
//result[0] = String.valueOf(anError.getErrorDetail());
}
methodParam.call(String.valueOf(anError.getErrorDetail()));
}
});
// Log.i("data", result[0]);
}
Use like below
ActivationResponseV2.getActivationData(getContext(), "LOCAL", header,
"/sample/response", jsonObject, new Callable<Void>() {
public Void call(String data) {
//...Consume data here
return null;
});
I have done it by using ANRequest. After reading this document. I tried to replicate it and I get my desired output.
This is the code :
public static synchronized String getActivationData(final Context context, final String api, final String base64Header, final String endpoint, final JSONObject body) {
final String[] result = {null};
String baseURL = null;
if (api.equalsIgnoreCase("LOCAL")) {
baseURL = Environments.getMarkLocalAPI();
} else if (api.equalsIgnoreCase("DEVELOPMENT")) {
baseURL = Environments.getDevelopmentAPI();
} else if (api.equalsIgnoreCase("STAGING")) {
baseURL = Environments.getStagingAPI();
} else if (api.equalsIgnoreCase("DEPLOYMENT")) {
baseURL = Environments.getDeploymentAPI();
}
final String finalBaseURL = baseURL;
OkHttpClient okHttpClient = new OkHttpClient().newBuilder()
.connectTimeout(15, TimeUnit.SECONDS)
.readTimeout(15, TimeUnit.SECONDS)
.writeTimeout(15, TimeUnit.SECONDS)
.build();
AndroidNetworking.initialize(context, okHttpClient);
ANRequest request = AndroidNetworking.post(finalBaseURL + endpoint)
.setPriority(Priority.HIGH)
.addJSONObjectBody(body)
.addHeaders("Project", base64Header)
.addHeaders("Content-Type", "application/json")
.build();
ANResponse response = request.executeForJSONObject();
if (response.isSuccess()) {
result[0] = String.valueOf(response.getResult());
Log.d(TAG, "response : " + result[0]);
} else {
ANError error = response.getError();
Log.d(TAG, "response : " + error);
}
return result[0];
}
}
Happy Coding!
I am trying downlaodFile from Api Services so I am using Retrofit library,Below codes working but works runs as a asyncrounously,it starts to download all file at the same time,I want to download files as a sycnronously when one request(download process) is completed and response comes,other request(download process) will work, how can I do this? and how to handle finally all request is completed
for (int i = 0; i < urlList.size; i++){
downloadFile(headerData,context,urlList.get(i),fileNameList.get(i),fileType.get(i));
}
downloadFile.class
public static void downloadFile(String headerData,Context context,String url,String fileName,String fileType){
RestInterface restInterface = RetroClient.getClientFile(url).create(RestInterface.class);
Call<ResponseBody> call = restInterface.doGetFile(headerData);
call.enqueue(new Callback<ResponseBody>() {
#Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
if(response.isSuccessful()){
Log.d("Downloading FileResult:","" + response.body());
boolean success =
Utils.writeResponseBodyToDisk(response.body(),context,fileName,fileType);
if(success == true){
startManager(context);
}
}
}
#Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
Log.e("TAG", "error" + t.getMessage());
}
});
}
RestInterfac class
public interface RestInterface {
#GET(".")
Call<ResponseBody> doGetFile(#Header("Authorization") String authHeader);
}
RetroClient class
public class RetroClient{
public static Retrofit getClientFile(String url) {
String BaseUrl = url + "/";
Gson gson = new GsonBuilder()
.setLenient()
.create();
HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
OkHttpClient client = new OkHttpClient.Builder().addInterceptor(interceptor).build();
return new Retrofit.Builder()
.baseUrl(BaseUrl)
.addConverterFactory(ScalarsConverterFactory.create())
.addConverterFactory(GsonConverterFactory.create(gson))
.client(client)
.build();
}
}
Sncronously with execute method
private static class DownloadFileTask extends AsyncTask<String,Void,String>{
String Url,Header,FileName,FileType;
Context con;
public DownloadFileTask(String header,Context context,String url,String FileName,String FileType){
Url = url;
Header = header;
con = context;
this.FileName = FileName;
this.FileType = FileType;
}
#Override
protected String doInBackground(String... strings) {
RestInterface restInterface = RetroClient.getClientFile(Url).create(RestInterface.class);
Call<ResponseBody> call = restInterface.doGetFile(Header);
try{
Response<ResponseBody> response = call.execute();
ResponseBody responseBody = response.body();
Log.d("Downloading FileResult:","" + responseBody);
if(response.isSuccessful()){
boolean success = Utils.writeResponseBodyToDisk(response.body(),con,FileName,FileType);
/* if(success == true){
startManager(context);
}*/
}
}catch (Exception e){
e.printStackTrace();
}
return null;
}
}
calling Download File
public static void downloadFile(String headerData,Context context,String url,String fileName,String fileType){
new DownloadFileTask(headerData,context,url,fileName,fileType).execute();
}
I have a problem with Retrofit and post method.
My GET method with authentication work but POST isn't working.
I logged without any problems, and do any GET method.
When I am trying send some data to REST API (Spring) I get this error:
Response{protocol=http/1.1, code=401, message=, url=http://10.101.12.31:8080/add}
My Code:
DataAPI.java:
public class DataAPI {
private static final String BASE_URL = "http://10.101.12.31:8080/";
static OkHttpClient.Builder httpClient = new OkHttpClient.Builder();
private static Retrofit.Builder builder =
new Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create());
private static Retrofit retrofit = builder.build();
public static <S> S createService(Class<S> serviceClass) {
return createService(serviceClass, null, null);
}
public static <S> S createService(
Class<S> serviceClass, String username, String password) {
if (!TextUtils.isEmpty(username)
&& !TextUtils.isEmpty(password)) {
String authToken = Credentials.basic(username, password);
return createService(serviceClass, authToken);
}
return createService(serviceClass, null);
}
public static <S> S createService(
Class<S> serviceClass, final String authToken) {
if (!TextUtils.isEmpty(authToken)) {
AuthenticationInterceptor interceptor =
new AuthenticationInterceptor(authToken);
if (!httpClient.interceptors().contains(interceptor)) {
httpClient.addInterceptor(interceptor);
builder.client(httpClient.build());
retrofit = builder.build();
}
}
return retrofit.create(serviceClass);
}
public static DepartmentService getDepartmentService() {
return retrofit.create(DepartmentService.class);
}
}
AuthenticationInterceptor.java:
public class AuthenticationInterceptor implements Interceptor {
private String authToken;
public AuthenticationInterceptor(String token) {
this.authToken = token;
}
#Override
public Response intercept(Chain chain) throws IOException {
Request original = chain.request();
Request.Builder builder = original.newBuilder()
.addHeader("Authorization", authToken);
Request request = builder.build();
return chain.proceed(request);
}
}
Web interface:
public interface Service {
#POST("/add")
Call<Void> addUser(#Body User user);
}
Method:
public void buttonOne(View v) {
DataAPI.createService(Service.class, getIntent().getStringExtra("authToken"))
.addUser(user)).enqueue(new Callback<User>() {
#Override
public void onResponse(Call<User> call, Response<User> response) {
System.out.println(response);
}
#Override
public void onFailure(Call<User> call, Throwable t) {
Toast.makeText(getApplicationContext(),t.toString(),Toast.LENGTH_SHORT).show();
}
});
}
Well, I'm having problems to connect with my https URL, all works with postman, but I canĀ“t do it with my Android App, Can someone help me?
Image of code.
public class NetworkUtil{
public static RetrofitInterface getRetrofit(){
return new Retrofit.Builder()
.baseUrl(Constants.BASE_URL)
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.addConverterFactory(GsonConverterFactory.create())
.build().create(RetrofitInterface.class);
}
public static RetrofitInterface getRetrofit(String email, String password) {
String credentials = email + ":" + password;
String basic = "Basic " + Base64.encodeToString(credentials.getBytes(),Base64.NO_WRAP);
OkHttpClient.Builder httpClient = new OkHttpClient.Builder();
httpClient.addInterceptor(chain -> {
Request original = chain.request();
Request.Builder builder = original.newBuilder()
.addHeader("Authorization", basic)
.method(original.method(),original.body());
return chain.proceed(builder.build());
});
return new Retrofit.Builder()
.baseUrl(Constants.BASE_URL)
.client(httpClient.build())
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.addConverterFactory(GsonConverterFactory.create())
.build().create(RetrofitInterface.class);
}
I need to authenticate the tokens, how can i add that to the okhttp?
public static RetrofitInterface getRetrofit(String token) {
OkHttpClient.Builder httpClient = new OkHttpClient.Builder();
httpClient.addInterceptor(chain -> {
Request original = chain.request();
Request.Builder builder = original.newBuilder()
.addHeader("x-access-token", token)
.method(original.method(),original.body());
return chain.proceed(builder.build());
});
return new Retrofit.Builder()
.baseUrl(Constants.BASE_URL)
.client(okHttpClient)
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.addConverterFactory(GsonConverterFactory.create())
.build().create(RetrofitInterface.class);
}
}
Thanks in advance!
Try to use this code HTTPS working with OkHttp3 and Retrofit2
create API interface
public interface API {
#GET("/users/{user}")
Observable<Result<User>> getUser(#Path("user") String user);
}
create apiManager class which contains OKHttp3 and retrofit2 initialization and base url
public class ApiManager {
Context context;
public static final String BASE_URL = "https://api.github.com/";
private OkHttpClient okHttpClient;
private Authenticator authenticator = new Authenticator() {
#Override
public Request authenticate(Route route, Response response) {
return null;
}
};
private ApiManager() {
}
public void setAuthenticator(Authenticator authenticator) {
this.authenticator = authenticator;
}
public static class Builder {
String email, password;
ApiManager apiManager = new ApiManager();
public Builder setAuthenticator(Authenticator authenticator) {
apiManager.setAuthenticator(authenticator);
return this;
}
public ApiManager build(String param_email, String param_password) {
this.email = param_email;
this.password = param_password;
return apiManager.newInstance(email, password);
}
}
public class RequestTokenInterceptor implements Interceptor {
String email, password;
String credentials, basic;
public RequestTokenInterceptor(String email, String password) {
this.email = email;
this.password = password;
credentials = email + ":" + password;
basic = "Basic " + Base64.encodeToString(credentials.getBytes(), Base64.NO_WRAP);
}
#Override
public Response intercept(Interceptor.Chain chain) throws IOException {
Request original = chain.request();
Request.Builder builder = original.newBuilder()
.addHeader("Authorization", basic)
.method(original.method(), original.body());
return chain.proceed(builder.build());
}
}
private ApiManager newInstance(String email, String password) {
HttpLoggingInterceptor logging = new HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger() {
#Override
public void log(String message) {
Log.i("http", message);
}
});
logging.setLevel(HttpLoggingInterceptor.Level.BODY);
okHttpClient = new OkHttpClient.Builder()
.addInterceptor(logging)
.addInterceptor(new RequestTokenInterceptor(email, password))
.authenticator(authenticator)
.build();
return this;
}
public <T> T createRest(Class<T> t) {
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.client(okHttpClient)
.build();
return retrofit.create(t);
}
}
in Gradle add the libraries
compile 'com.squareup.okhttp3:okhttp:3.4.1'
compile 'com.squareup.okhttp3:okhttp-urlconnection:3.4.1'
compile 'com.squareup.okhttp3:logging-interceptor:3.4.1'
compile 'com.squareup.okhttp3:okhttp-ws:3.4.1'
compile 'com.squareup.retrofit2:retrofit:2.0.2'
compile 'com.squareup.retrofit2:converter-gson:2.0.2'
compile 'com.squareup.retrofit2:adapter-rxjava:2.0.2'
In MainActivity add
public class MainActivity extends AppCompatActivity {
private ProgressDialog feedbackDialog;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
feedbackDialog = new ProgressDialog(this);
feedbackDialog.setCanceledOnTouchOutside(false);
getUser();
}
public void getUser() {
API accountAPI4 = createRestApi4();
if (accountAPI4 != null) {
showFeedback(getResources().getString(R.string.loading));
BackgroundThreadObservable.toBackground(accountAPI4.getUser("SafAmin"))
.subscribe(new Action1<Result<User>>() {
#Override
public void call(Result<User> user) {
dismissFeedback();
Log.e("GIT_HUB","Github Name :"+user.response().body().getName()+"\nWebsite :"+user.response().body().getBlog());
}
}, new Action1<Throwable>() {
#Override
public void call(Throwable throwable) {
// do something with the error
if (throwable != null) {
dismissFeedback();
}
}
}
);
} else {
dismissFeedback();
}
}
public static API createRestApi4() {
ApiManager apiManager = new ApiManager.Builder().build(email, password);
return apiManager.createRest(API.class);
}
public void showFeedback(String message) {
feedbackDialog.setMessage(message);
feedbackDialog.show();
}
public void dismissFeedback() {
feedbackDialog.dismiss();
}
}
in AndroidManifest add
<uses-permission android:name="android.permission.INTERNET"/>
Hope it helps.
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;
}