Retrofit2 POST request with Body - android

I need make POST request with parameters "guid=1" in Body. i use Retrofit2
I try :
#POST("/api/1/model")
Call<ApiModelJson> getPostClub(#Body User body);
User Class:
public class User {
#SerializedName("guid")
String guid;
public User(String guid ) {
this.guid = guid;
}
MailActivity:
User user =new User ("1");
Call<ApiModelJson> call = service.getPostClub(user);
call.enqueue(new Callback<ApiModelJson>() {
#Override
public void onResponse(Response<ApiModelJson> response) {
}
#Override
public void onFailure(Throwable t) {
dialog.dismiss();
}
How make this request?

you have to call call.enqueue, providing an instance of Callback< ApiModelJson>, where you will get the response. enqueue executes your backend call asynchronously. You can read more about call.enqueue here

With code below, you can make the request synchronously:
ApiModelJson responseBody = call.execute();
If you want it to be asynchronous:
call.enqueue(new Callback<ApiModelJson>() {
#Override
public void onResponse(Response<ApiModelJson> response, Retrofit retrofit) {
}
#Override
public void onFailure(Throwable t) {
}
});

Related

How to get response from server as String ,Retrofit 1.9

I would like to handle my response from server , but I don't know how JSON (from server) its looks like. So I tried to display response as String , but I cant do it. Is it possible to display response as String? And then handle the response correctly. thanks
(Retrofit 1.9)
LoginService loginService = RetrofitClient.createService(LoginService.class);
loginService.searchOffer(getToken(), offerSearch, new Callback<String>() {
#Override
public void success(String offerSearchRequestResource, Response response) {
String responseFromSercer = response.getBody();
}
#Override
public void failure(RetrofitError error) {
}
});
change your response model to
JSONObject (from Gson)
then in your
public void success(...){response.body.toString();}
like this:
Call<JsonObject> call = YOUR_API_INTERFACE().YOUR_METHOD(YOUR_PARAMS);
call.enqueue(new Callback<JsonObject>() {
#Override
public void onResponse(Call<JsonObject> call, #NonNull Response<JsonObject> response) {
if(response.isSuccessful()) {
String responseFromSercer = response.body.toString();
}
}
#Override
public void onFailure(Call<JsonObject> call, Throwable t) {
.....
}
});
If you are sure the request runs successfully and there is a response back...use
System.out.println(response.getBody());
i'd also suggest you add Logging Interceptors here so that you can get a detailed view of all your API calls

Android Send String to Server via retrofit

i want to send string from app to server with retrofit 2, and get back return values. what is the problem?
but it doesn't work.
Retrofit retrofit = new Retrofit.Builder().baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build();
RatingApiService retrofitService=retrofit.create(RatingApiService.class);
Call<String> call = retrofitService.registration("saeed","ali");
call.enqueue(new Callback<String>() {
#Override
public void onResponse(Call<String> call, Response<String> response) {
if(response!=null){
Log.i("upload","is success:" +response.body());
}else{
Log.i("upload","response is null");
}
}
#Override
public void onFailure(Call<String> call, Throwable t) {
Log.i("upload","onFailure: "+t.getMessage());
}
});
Interface:
public interface RatingApiService {
#FormUrlEncoded
#POST("android/add2/{email}{password}")
Call<String> registration(#Path("email") String email, #Path("password") String password);
}
Instead of using parameters to pass your data; put it in a req.body, then send it. By doing so, you can bypass the URL string limit and the code is much more organized.
public interface RatingApiService {
#Headers("Content-Type: application/json") //Must be set to application/json so req.body can be read.
#POST("android")
Call<String> registration(#Body UserRegistrationRequest body);
}
Now, you might ask what is the " UserRegistrationRequest" class? that will be the object class that will be sent as a JSON object. We define it by:
public class UserRegistrationRequest {
final String email;
final String password;
UserRegistrationRequest(String email, String password){
this.email = email;
this.password = password;
}
}
And then the final step. This is how you convert the object to a JSON object and send it to your server.
UserRegistrationRequest userRegistrationRequest = new UserRegistrationRequest(
RegisterNameFragment.sFirstName, RegisterNameFragment.sLastName, RegisterEmailFragment.sEmail,
RegisterPasswordFragment.sPassword, RegisterAgeFragment.sAge);
Call<Void> call = retrofit.insertUserRegistration(userRegistrationRequest);
call.enqueue(new Callback<UserRegistration>() {
#Override
public void onResponse(Call<UserRegistration> call, Response<UserRegistration> response) {
Log.d("blue", "Data is sent");
}
#Override
public void onFailure(Call<UserRegistration> call, Throwable t) {
Log.d("blue", "fail");
}
});
You need to add #Body annotation to your method like below.
#POST("users/new")
Call<User> createUser(#Body User user);
The content of #Body is sent to server as request body.
If you want to send email and password to server, you should create object that contains such data and use the object in the #Body annotation.

Send POST parameters with Retrofit

I am trying to implement a POST request via Retrofit, but the approach seems to be wrong, I guess. I followed the steps I used for GET request:
I defined the end point:
public interface GitHubEmailAPI {
#POST("/users/{user}")
Call<GitHubEmail> postEmail(#Field("email") String email);
}
The model:
public class GitHubEmail {
#SerializedName("email")
private String email;
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
}
And the calling:
public void postEmail (){
GitHubEmailAPI apiService =
ApiClient.getClient().create(GitHubEmailAPI.class);
final Call<GitHubEmail> callEmail = apiService.postEmail
(String.valueOf(enterEmailEt.getText()));
callEmail.enqueue(new Callback<GitHubEmail>() {
#Override
public void onResponse(Call<GitHubEmail> call, Response<GitHubEmail> response) {
testTV.setText(callEmail.toString());
}
#Override
public void onFailure(Call<GitHubEmail> call, Throwable t) {
Log.e("Email", t.toString());
}
});
I am using the github api as a test, not sure if the access token needs to be included as a parameter in the request.
There are some info which you know about Retrofit ....
Your BASE_URL must be end with / .
When you using #Field notation you must put #FormUrlEncoded in Your Api call.
When you using {user} in the API method you have to use #Path("user") String user to relate to url data .
Your POST method URL will be like this #POST("users/{user}").
When your response Callback done the actual Data inside your Response<GitHubEmail> response in this variable. You have to use response.body() to get what you get response from API CALL.
Here is a sample code
#FormUrlEncoded
#POST("users/{user}")
Call<YourResultPojoClassHere> yourFuntionName(#Field("id") String id,#Path("user") String path);
please take look on below code ....
callEmail.enqueue(new Callback<GitHubEmail>() {
#Override
public void onResponse(Call<GitHubEmail> call, Response<GitHubEmail> response) {
if (response.isSuccessful()) {
if (response.body().getSuccess())
Toast.makeText(ClassName.this, response.body().getMessage(), Toast.LENGTH_SHORT).show();
else
Toast.makeText(ClassName.this, response.body().getMessage(), Toast.LENGTH_SHORT).show();
} else
Toast.makeText(ClassName.this, "Sorry for inconvince server is down", Toast.LENGTH_SHORT).show();
}
#Override
public void onFailure(Call<GitHubEmail> call, Throwable t) {
Toast.makeText(ClassName.this, "Check your Internet connection", Toast.LENGTH_SHORT).show();
}
}
});
For POST in retrofit you must include #FormUrlEncoded
#FormUrlEncoded
#POST("path_here")
Call<ResponseBody> function_name(#Field("data") String data);

How to do unit testing for retrofit2 callbacks?

I want to do an unit test that verifies if function1() or function2() were called. I haven't work with callbacks before, can you give me any idea about how to do it?
public void sendData(HttpService service, Document userData) {
Call<String> call = service.updateDocument(getId(), userData);
call.enqueue(new Callback<String>() {
#Override
public void onResponse(Call<String> call, Response<String> response) {
function1(response.code());
}
#Override
public void onFailure(Call<String> call, Throwable t) {
function2();
}
});
}
I couldn't try, but it should work. Maybe you have to fix generic type
casting errors like mock(Call.class);.
#Test
public void should_test_on_response(){
Call<String> onResponseCall = mock(Call.class);
doAnswer(invocation -> {
Response response = null;
invocation.getArgumentAt(0, Callback.class).onResponse(onResponseCall, response);
return null;
}).when(onResponseCall).enqueue(any(Callback.class));
sendData(....);
// verify function1
}
#Test
public void should_test_on_failure(){
Call<String> onResponseCall = mock(Call.class);
doAnswer(invocation -> {
Exception ex = new RuntimeException();
invocation.getArgumentAt(0, Callback.class).onFailure(onResponseCall, ex);
return null;
}).when(onResponseCall).enqueue(any(Callback.class));
sendData(....);
// verify function2
}

How to SendDataToServer?

Condition: I've a button. When user click the button (example ADD NEW NAME button) so the data will send to server.
I've question: How to add new data to server?
What should I put into onResponse and onFailure based on this code:
private void sendDataToServer() {
APIClient client = ServiceGenerator.createService(APIClient.class);
Call<ResponseBody> result = client.addNewName(etName.getText().toString(),
etEnglish.getText().toString(),
etGender.getText().toString());
result.enqueue(new Callback<ResponseBody>() {
#Override
public void onResponse(Response<ResponseBody> response) {
}
#Override
public void onFailure(Throwable t) {
}
}
);}
*et - Edit Text
Thanks.

Categories

Resources