Post request with query params and body - java

I am making use of Retrofit to call the restful webservices in the android, I have come across the scenario like I need to pass query params and request payload object in the retrofit request, so I've tried something like this
#POST("actual url")
Call<ReceiptList> getData(#Query("limit") String limit,
#Query("page") String page,
#Body ReceiptRequestPayload receiptRequestPayload);
Calling API
Call<cutomObject> responseCall = API.getData("10", "1", requestPayload);
responseCall .enqueue(new Callback<cutomObject>() {
#Override
public void onResponse(Call<cutomObject> call, retrofit2.Response<cutomObject> response) {
Log.d(TAG, "onResponse: Receipts"+response);
Log.d(TAG, "onResponse: Receipts"+response.body());
}
#Override
public void onFailure(Call<ReceiptList> call, Throwable t) {
}
});
But it's not working.
Thanks in advance

Use OkHttp Logging Interceptor to log your HTTP request and response data

Related

Android HTTP Get to api

I´m trying to get data from my api. In postman the request works, here´s the response:
{
"ips_Beacons_BeaconID": 14,
"ips_Beacons_BeaconDescription": "b2",
"ips_Beacons_BeaconLat": 12.3123,
"ips_Beacons_BeaconLon": 32.123,
"ips_Beacons_BeaconImgX": 45,
"ips_Beacons_BeaconImgY": 123
}
I´ve tried and i got the response with Okhttp. However it stopped working for some reason.
Although i got the response, i wish to serialize the json string it and instanciate objects. But i couldn´t get the response out of the onSuccess method inside the callback.
This is what i had that workd but doens´t work anymore:
OkHttpClient client = new OkHttpClient();
String url ="http://192.168.1.95:44374/api/beacons";
Request request = new Request.Builder().url(url).build();
client.newCall(request).enqueue(new Callback() {
#Override
public void onFailure(Call call, IOException e) { e.printStackTrace();
}
#Override
public void onResponse(Call call, Response response) throws IOException {
if (response.isSuccessful()){
String myResponse = response.body().string();
listBeacons = objectMapper.readValue(myResponse, new TypeReference<List<Beacon>>(){});
Log.i(TAG, myResponse);
}
}
});
I need the listBeacons List to perform other operations outside this activity.

OKHTTP GET and POST request return empty body message

I want to a upload file on my server and I've decided to try OKHTTP instead of my current method which is based on android own HTTP implementation and AsyncTask.
Anyway, I used OKHTTP and its asynchronous implementation (from its own recipes) but it returns an empty message (the request code is ok, the message is empty) in both GET and POST methods.
Did I implement it wrong or is there anything else remained that I did not considered? In the meantime, I couldn't find a similar case except this which says used AsyncTask.
Here's the code:
Request request;
Response response;
private final OkHttpClient client = new OkHttpClient();
private static final String postman_url = "https://postman-echo.com/get?foo1=bar1&foo2=bar2";
String message_body;
public void Get_Synchronous() throws IOException
{
request = new Request.Builder()
.url(postman_url)
.build();
Call call = client.newCall(request);
response = call.execute();
message_body = response.toString();
//assertThat(response.code(), equalTo(200));
}
public void Get_Asynchronous()
{
request = new Request.Builder()
.url(postman_url)
.build();
Call call = client.newCall(request);
call.enqueue(new Callback() {
public void onResponse(Call call, Response response)
throws IOException
{
message_body = response.toString();
}
public void onFailure(Call call, IOException e)
{
}
});
}
Edit:
I catch the log on response:
onResponse: Response{protocol=h2, code=200, message=, url=https://postman-echo.com/get?foo1=bar1&foo2=bar2}
OK, for anyone who wants to receive an string from a call, response and response.messgage() don't provide that. To catch the response from your provider, you just need to call response.body().string() inside onResponse which returns the message inside your request.
But after all, Retrofit is a better choice if you want to receive a JSON file using
.addConverterFactory(GsonConverterFactory.create(gson)).
If you still want to receive an string just use .addConverterFactory(ScalarsConverterFactory.create()) as explained here.

How to make authenticated django rest api call from android client?

I am making an android app which has a django rest api as the backend and want to make authenticated network calls using the token given to the user when he/she has logged in.
I am using retrofit to make requests to the backend. Here is what I am doing right now to attempt to make an authenticated network call to the rest api.
#Override
public void loadAllUsers() {
Call<List<User>> call = userServiceApi.loadAllUsers();
call.enqueue(new Callback<List<User>>() {
#Override
public void onResponse(#NonNull Call<List<User>> call, #NonNull Response<List<User>> response) {
if (response.isSuccessful()) {
List<User> users = response.body();
eventBus.post(new LoadAllUsersEvent(users));
} else {
eventBus.post(new FailLoadAllUsersEvent());
Log.d(TAG, response.message());
}
}
#Override
public void onFailure(#NonNull Call<List<User>> call, #NonNull Throwable t) {
eventBus.post(new LoadUsersUnreachableServerEvent());
Log.d(TAG, t.toString());
}
});
}
Here is the retrofit interface relevant to this api request:
#GET("users/")
Call<List<User>> loadAllUsers(#Header("Authorization: Token ") Token token);
When I make this call passing the user's token in as the header, I get status code 401: Unauthenticated: "GET /users/ HTTP/1.1" 401 58
What am I doing wrong for django rest Token Authentication to work and to make an authenticated django rest api call?
The quick fix for this would be to change your api interface:
#GET("users/")
Call<List<User>> loadAllUsers(#Header("Authorization") Token token);
Value you are passing in should be formated as "Token %s".
This is not a very good solution, because you'd have to pass the token around to all of your api calls.
Better way to solve your authorization issues is by using OkHttp client and implement authenticator, which takes care of everything for you.
OkHttp and Retrofit work together very well.

Retrofit enqueue doesn't work but execute work

I'm using com.squareup.retrofit2:retrofit:2.2.0
HttpLoggingInterceptor logging = new HttpLoggingInterceptor();
logging.setLevel(HttpLoggingInterceptor.Level.BODY);
OkHttpClient.Builder httpClient = new OkHttpClient.Builder();
httpClient.addInterceptor(logging);
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("http://localhost:9000")
.addConverterFactory(GsonConverterFactory.create())
.client(httpClient.build())
.build();
final UserService service = retrofit.create(UserService.class);
Call<User> userCall = service.createUser(user)
Here is the problem: when I run the execute it make REST API request but when I use enqueue it does nothing (no exception, no log)
userCall.execute(); //this work
//this does not work
userCall.enqueue(new Callback<User>() {
#Override
public void onResponse(Call<User> call, Response<User> response) {
// no response
}
#Override
public void onFailure(Call<User> call, Throwable t) {
//nothing here
}
});
Well,
The issue was because I was using an emulator and try to call the localhost however, it turn out if you want call the localhost you have to use this ip 10.0.2.2
The execute works because I was running as unit test but when it runs enqueue I think it need to run on android platform.
refer to this
https://developer.android.com/studio/run/emulator.html#networkaddresses
How to get the Android Emulator's IP address?
You can try this full Answer Link
Here is the shortest code snippest.
private void emailLoginRequest() {
LoginService loginService = ApiFactory.createService(LoginService.class);
Call<JsonObject> call = loginService.login(edtEmail.getText().toString(),edtPassword.getText().toString(),mDeviceType,mDeviceToken);
call.enqueue(new Callback<JsonObject>() {
#Override
public void onResponse(Call<JsonObject> call, Response<JsonObject> response) {
hideProgressDialog();
if (response.isSuccessful()) {
LOGD(TAG, "onResponse 0: " + response.body().toString());
LoginResponse loginResponse = new Gson().fromJson(response.body().toString(), LoginResponse.class);
System.out.println("+++ get message >> " + loginResponse.getMessage());
int status = loginResponse.getStatus();
}else {
LOGD(TAG, "response fail 0: " + response.body());
}
}
#Override
public void onFailure(Call<JsonObject> call, Throwable t) {
hideProgressDialog();
LOGD(TAG, "onFailure: " + t.getMessage());
}
});
}
put your code as this:
userCall.enqueue(new Callback<User>() {
#Override
public void onResponse(Call<User> call, Response<User> response) {
Toast.makeText(this, "in response", Toast.LENGTH_SHORT).show();
}
#Override
public void onFailure(Call<User> call, Throwable t) {
Toast.makeText(this, "in response", Toast.LENGTH_SHORT).show();
}
});
Now based on method call you will get toast if its in response toast will be "In response" don't forget write youractivity name before this like : MainActivity.this
see this
retrofit can be called by 2 methods separately one is synchronous and another way is asynchronous.
enqueue is an asynchronous way where it does not wait for a response and proceed. here you need to handle Call separately to load UI later.
Execute is asynchronously call rest api and wait until get response and process it.
choice wisely

Use different models for deserialization in retrofit success and error callbacks

The API I am working with gives completely different responses for success and failure.
Success:
{
"token":"asdfasdfhkAADBSKJBJBJKBJBK^%&BJBLLKHKJBXZ",
"email":"sample#sample.com",
"role":"admin"
}
Failure:
{
"name": "NotAuthenticated",
"message": "Invalid login.",
"code": 401,
"className": "not-authenticated"
}
I am very new to retrofit and am using the below code to make the call.
LoginRequest request = new LoginRequest(mobileNumber, password);
ApiInterface apiService = ApiClient.getClient().create(ApiInterface.class);
Call<LoginResponse> call = apiService.authenticateUser(request);
call.enqueue(new Callback<LoginResponse>() {
#Override
public void onResponse(Call<LoginResponse> call, Response<LoginResponse> response) {
}
#Override
public void onFailure(Call<LoginResponse> call, Throwable t) {
}
});
As you can see, retrofit forces me to use the Sample ResponseObject for both success and failure. And hence I am not able to convert the failure response to a pojo.
I have looked at custom deserialization. But writing a custom deserializer for each request can quickly go out of control.
Please help out.
I think the best solution for this will be getting Response Body form retrofit and Serializing it by our self in GSON . I am also looking for other sort of solution.

Categories