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);
Related
Hello i using Post method in retrofit . I have one Activity ProfileActivity and I try to update ProfileActivity. When i try to update my Activity it response like :-
"name": "\"\\\"\\\\\\\"\\\\\\\\\\\\\\\"JohndoeOperator\\\\\\\\\\\\\\\"\\\\\\\"\\\"\"",
I try to remove this extra "\"\" from my String ,But question is why
this add when i try to update my profile
Here is my code:-
APIInterface.java
#Multipart
#POST("updateProfile")
Call<UpdateProfileUserSideResponse> updateProfile(#Part("userId") int userId,
#Part("name") String name,
#Part("companyName") String companyName,
#Part("gstin") String gstin,
#Part("address") String address,
#Part("landmark") String landmark,
#Part("city") String city,
#Part("state") String state,
#Part("pincode") String pincode,
#Part MultipartBody.Part image);
and Here is my API call :-
final ApiInterface api = ApiClient.getApiService();
Call<UpdateProfileUserSideResponse> call = api.updateProfile(preferenceManager.getUserId(), edt_user_FullName.getText().toString(), "", "", edt_user_address.getText().toString(), edt_user_landMark.getText().toString(), edt_user_city.getText().toString(), edt_user_state.getText().toString(), edt_user_pincode.getText().toString(), fileToUpload);
call.enqueue(new Callback<UpdateProfileUserSideResponse>() {
#Override
public void onResponse(Call<UpdateProfileUserSideResponse> call, Response<UpdateProfileUserSideResponse> response) {
Toast.makeText(getContext(), "" + response.message(), Toast.LENGTH_SHORT).show();
preferenceManager.setName(response.body().getData().getName());
Log.e("AHHHHHHAHAAA", "" + response.body().getData().getName());
preferenceManager.setAddress(response.body().getData().getAddress());
preferenceManager.setLandmark(response.body().getData().getLandmark());
preferenceManager.setCity(response.body().getData().getCity());
preferenceManager.setState(response.body().getData().getState());
preferenceManager.setPincode(response.body().getData().getPincode());
preferenceManager.setImage(response.body().getData().getImage());
progressDialog.dismiss();
}
#Override
public void onFailure(Call<UpdateProfileUserSideResponse> call, Throwable t) {
Toast.makeText(getContext(), t.getMessage(), Toast.LENGTH_LONG).show();
progressDialog.dismiss();
}
});
First, check your API on postman plugin of chrome browser
Is gives the same result on postman as well.
i'm new to android and using retrofit for the first time.
i've implemented all the things but retrofit is giving null values of responses.
this is my sample request:
http://192.168.1.0/demo/kdemo//webservice/api.php?query=user.auttentication&user_name=admin&password=admin
for this I'm taking base url as :
BASE_URL="http://192.168.1.0/demo/kdemo//webservice/"
and End point in interface as :
#GET("api.php")
Call<UserAuthenticaiton> getUserAuthentication(#Query("user.auttentication")
String userAuttentication,
#Query("user_name") String
user_name,
#Query("password") String
password);
JSon viewer is giving values but retrofit is not..
This is Api call:
ApiInterface apiService= ApiClient.getClient().create(ApiInterface.class);
Call<UserAuthenticaiton> call=apiService.getUserAuthentication("user.auttentication","admin","admin");
call.enqueue(new Callback<UserAuthenticaiton>() {
#Override
public void onResponse(Call<UserAuthenticaiton> call, Response<UserAuthenticaiton> response) {
String id=response.body().getId();
String error=response.body().getError();
Toast.makeText(LoginActivity.this, "Id: "+id+" Error: "+error, Toast.LENGTH_SHORT).show();
Intent intentNew=new Intent(LoginActivity.this,MainActivity.class);
startActivity(intentNew);
}
#Override
public void onFailure(Call<UserAuthenticaiton> call, Throwable t) {
Toast.makeText(LoginActivity.this, "Failed to load", Toast.LENGTH_SHORT).show();
}
});
I am able to do the initial log in to the server and get the token, but when I try to do another request I get the HTTP error 403, so I am not actually being authenticated.
When I go through the browser or the android application, this is the key that I am getting when I log in.
{
"key": "64ea43a78fa18da19364d2d0ae5a12371e5d0ee2"
}
Is there anything that I can do with this key using retrofit? I have tried using the header "Authorization" and following with the token.
Here is my RestClient interface:
public interface RestClient {
#POST ("rest-auth/login/")
Call<Token> login(
#Body Login body
);
#GET ("v2/users/{user}/")
Call<List<CustomUser>> getUser(
#Header("Authorization") String token,
#Path("user") String user
);
Here is the AsyncTask which will perform the requests to the server. The authenticateUser gives me an HTTP response of 200, but the syncUser gives 403.
public class ActionSync extends AsyncTask<String, Void, Boolean> {
RestClient client;
IData activity;
private static String token;
public ActionSync(Context context) {
activity = (IData) context;
}
#Override
protected Boolean doInBackground(String... params) {
Retrofit.Builder builder = new Retrofit.Builder()
.baseUrl("http://" + params[2] + ":" + params[3] + "/")
.addConverterFactory(GsonConverterFactory.create());
Retrofit retrofit = builder.build();
client = retrofit.create(RestClient.class);
//Authenticate the user.
authenticateUser(params[0], params[1]);
//Once the authentication has been completed, we can now move on the syncing data.
syncUser(params[0]);
//If we get to the end without any errors, then return true. This means that the sync is complete.
return true;
}
#Override
protected void onPostExecute(Boolean loggedIn) {
super.onPostExecute(loggedIn);
}
public void authenticateUser(String username, String password){
//First, we must log into the server given our credentials. Otherwise, we will not be able to get any data.
Login login = new Login(username, password);
Call<Token> call = client.login(login);
call.enqueue(new Callback<Token>() {
#Override
public void onResponse(Call<Token> call, Response<Token> response) {
if(response.isSuccessful()){
Log.v("ActionSync", "Login was successful");
token = response.body().getKey();
} else {
Log.v("ActionSync", "Login was unsuccessful");
}
}
#Override
public void onFailure(Call<Token> call, Throwable t) {
Log.v("ActionSync", "Error occurred during login");
}
});
}
public void syncUser(String username){
Call<List<CustomUser>> call = client.getUser(token, username);
call.enqueue(new Callback<List<CustomUser>>() {
#Override
public void onResponse(Call<List<CustomUser>> call, Response<List<CustomUser>> response) {
Log.v("ActionSync", "The response from get user: " + response.toString());
}
#Override
public void onFailure(Call<List<CustomUser>> call, Throwable t) {
Log.v("ActionSync", "No response from get user");
}
});
}
public interface IData {
}
}
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.
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) {
}
});