Retrofit 2.0 how to delete? - java

I am using retrofit 2.0 and I am implementing a delete feature in my Android app, however, I cannot make it successfully, can someone give me a suggestion?
I tried both:
#DELETE("books/{id}") void deleteBook(#Path("id") int itemId);
#DELETE("books/{id}") void deleteBook(#Path("id") int bookId, Callback<Response> callback);
I get error java.lang.IllegalArgumentException: Service methods cannot return void. for method LibraryService.deleteBook.
I also gave a try on this:
Response deleteBook(#Path("id") int bookId);
Call<Response> deleteBook(#Path("id") int bookId);
no matter I use okhttp3.Response or retrofit2.Response, I will get the error: '*.Response' is not a valid response body type. Did you mean ResponseBody?
Can someone give me a successful delete example? I googled online but cannot find enough information. Thanks a lot.

Do it this way as you noted last:
Call<ResponseBody> deleteBook(#Path("id") int bookId);
Make sure you make the call off the UI-thread via AsyncTask or some other threading mechanism. Not sure if you've used RxJava + Retrofit 2 before, but it is nice.
The ResponseBody object will return the results from the call. It is what I use for some REST API requests that don't return an entity object, and all I care about is looking at the response code.
Call<ResponseBody> deleteRequest = mService.deleteBook(123);
deleteRequest.enqueue(new Callback<ResponseBody>() {
#Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
// use response.code, response.headers, etc.
}
#Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
// handle failure
}
});
Or, Jake Wharton suggests
Use Void which not only has better semantics but is (slightly) more efficient in the empty case and vastly more efficient in a non-empty case (when you just don't care about body).
So you have:
Call<Void> deleteBook(#Path("id") int bookId);
Usage:
deleteRequest.enqueue(new Callback<Void>() {
#Override
public void onResponse(Call<Void> call, Response<Void> response) {
// use response.code, response.headers, etc.
}
#Override
public void onFailure(Call<Void> call, Throwable t) {
// handle failure
}
});
This is better if all you care about is the response code and no body to the response
EDIT 2: Left out the proper Callback definition. Fixed :)

Related

GWT - How to return a String value from RequestBuilder after receiving a response?

I'm unable to figure out how to return a String value from RequestBuilder's sendRequest() method after receiving a response. I referred to a similar question where the suggestion was to use Callback<String, String> callback but I can't figure out how to implement this. The GWT documentation for Callback does not have any examples.
What I have is a class Requester with the method generateRequest() that should make a request with RequestBuilder and return a String when called. The processResponse() method takes the response, parses it and returns a String which I'm storing in output. How can I return this output String when generateRequest() is called from another class?
public String generateRequest() {
RequestBuilder builder = new RequestBuilder(RequestBuilder.GET, URL.encode(url.getUrl()));
builder.setHeader("Authorization", authHeader);
String title = null;
try {
builder.sendRequest(null, new RequestCallback() {
public void onError(Request request, Throwable exception) {
GWT.log(exception.getMessage());
}
public void onResponseReceived(Request request, Response response) {
String output = processResponse(response);
}
});
} catch (RequestException e) {
GWT.log(e.getMessage());
}
return title;
}
I think you might be misunderstanding something.
You cannot simply return a String because the call is async (i.e. you can't return the String because the String is simply not available yet, at the time you wish to return it).
You could simply wait there until the call result is ready, but this is really terrible practice; that's why you're seeing people suggesting callbacks.
Imagine, this is the code:
statement01;
statement02;
String result = generateRequest(...);
statement04UsingResult;
statement05;
then this will not work, because result will not be available before statement04UsingResult is executed. The Request has not finished yet. (as Andrej already mentioned)
To solve this, split your code:
statement01;
statement02;
generateRequest(...);
create an new void method, wich accepts the result as parameter:
public void newMethod(String result) {
statement04UsingResult;
statement05;
}
and call from inside the onResponseRevieve-method:
builder.sendRequest(null, new RequestCallback() {
public void onError(Request request, Throwable exception) {
GWT.log(exception.getMessage());
}
public void onResponseReceived(Request request, Response response) {
newMethod(processResponse(response));
}
});
Hope that helps.

method in the class returns null instead of a string retrieved via async call

Utils.java
/**
* Created by faiz on 15/08/17.
*/
package com.example.android.whereabouts;
import android.util.Log;
import java.io.IOException;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
public class Utils {
private String apiresponse;
private OkHttpClient okHttpClient;
public Utils(String url){
okHttpClient = new OkHttpClient();
Request request = new Request.Builder().url(url).build();
okHttpClient.newCall(request).enqueue(new Callback() {
#Override
public void onFailure(Call call, IOException e) {
Log.e("exception",e.toString());
}
#Override
public void onResponse(Call call, okhttp3.Response response) throws IOException {
apiresponse = response.body().string();
Log.e("onResponse",apiresponse);
}
});
}
public String getData(){
if(apiresponse != null)
return apiresponse ;
else
return "error";
}
}
When i instantiate this class in my main activity and try to Log return value of getData method, it logs "error" instead of the value of variable apiresponse .
Its obvious that that it takes some time to get response from the server and getData call gets executed before the server returns a response.
So how to make sure getData gets called after onResponse has been executed.
Instead of getting a callback in Utility, You can implement that in your Activity so that call back will come to ur activity and you can update in UI without any issue.
public Utils(String url, Callback callback){
okHttpClient = new OkHttpClient();
Request request = new Request.Builder().url(url).build();
okHttpClient.newCall(request).enqueue(callback);
}
in your actvity, you can call like,
public void getdata() {
new Utils("[url]", new Callback() {
#Override
public void onFailure(Call call, IOException e) {
Log.e("exception",e.toString());
}
#Override
public void onResponse(Call call, okhttp3.Response response) throws IOException {
apiresponse = response.body().string();
Log.e("onResponse",apiresponse);
// here you can show in UI.
}
})
}
or you can create a separate custom interface and you can do same after getting the response from the server.
You can implement a callback mechanism and call the callback method from inside the onResponse(Call call, okhttp3.Response response) method.
Here is an example. You should define this in the Utils class -
public interface Callback {
void getData(String data);
}
private Callback callback;
In the constructor pass in the activity reference when you instantiate the Utils class.
// In the activity
utilsInstance = new Utils(url, this);
// In your Utils class
public Utils(String url, Callback activityCallback) {
callback = activityCallback
}
In your activity, you need to implement this interface -
public class RetrofitActivity implements Utils.Callback {
#Override
public void getData(String data) {
// do stuff
}
}
And in your OnResponse() method, you'll call this method like so -
#Override
public void onResponse(Call call, okhttp3.Response response) throws IOException {
apiresponse = response.body().string();
callback.getData(apiresponse);
Log.e("onResponse",apiresponse);
}
I found two workarounds which I'll share here and I request the people who answered this question to share their thoughts on this.(I appreciate the answers shared on this question..thanks to you all )
Note: Its more of a "clean code question" than "how to get this thing to work question"
Solution 1:
We can wait till the onResponse method gets called in getData() like this
while(true)
if(apiresponse!=null)
return(apiresponse);
to make sure this is not an indefinite while loop we set the variable apiresponse to something in both onResponse and OnFailure methods(either one will surely get executed) to break the loop.
this one seems to work but its pretty naive to me to use infinite loop and break it.
Solution 2:
Writing an AsyncTask and the Executing Utils class in the doInBackground method of that async task.
(I think the second approach makes sense as it falls under standard practices of android so it makes the thing work and also satisfies the best practices).
Another thing: an obvious question to some would be that when you're ready to write the whole async task inside the activity, then why is it an issue to write the Utils.java code directly inside the activity. My response to that is , despite of writing the asynctask in the activity, its better because it saves me from manually handling Handlers to create another thread inside onResponse to update the UI and it also falls under standard practices . So I think this approach makes more sense overall.
Step 1 : In Utils method pass calling activity as below
public Utils(CallingActivity activity , String url)
{
Request request = new Request.Builder().url(url).build();
okHttpClient.newCall(request).enqueue(activity);
}
Step 2 : Implement Callback of OkHttpClient in your calling activity.
Step 3 : Override onFailure() and onResponse() of OkHttpClient and call Utils(this,url) in calling activity.

How do I properly set the annotation and query in Retrofit 2.0+?

URL query string "q={city}" must not have replace block
I can't get this to work, I've tried several other variants but still get some form of exception.
public interface WeatherInterface {
#GET("/weather?q={city}")
Call<WeatherModel> getWeather(#Query("city") String city);
}
/////
public interface WeatherInterface {
#GET("/weather")
Call<WeatherModel> getWeather(#Query("q") String city);
}
And so on.
WeatherActivity.class
Call<WeatherModel> call = weatherInterface.getWeather("""CITYNAME""");
call.enqueue(new Callback<WeatherModel>() {
#Override
public void onResponse(Call<WeatherModel> call, Response<WeatherModel> response) {
if(response.isSuccessful()) {
**///FIRST VARIANT FAILS HERE**
city.setText(response.body().getName());
}
**///SECOND VARIANT FAILES RESPONSE**
else Log.d("No response", "RESPONSE");
}
#Override
public void onFailure(Call<WeatherModel> call, Throwable t) {
Log.d("fail", "fail");
}
});
EDIT:
Log.d(call.request().url().toString(), "CALL REQUEST URL");
I should share my solution too probably, I just logged the call url.
I forgot the to add my API KEY in the url. I shamefully withdraw my question.
U can use this sample take example:
public interface GitHubClient {
#GET("/users/{user}/repos")
Call<List<GitHubRepo>> reposForUser(
#Path("user") String user
);
}
For more samples just visit this website

How can i get JSON from php in android

i could not found codes. I want to this;
for example
JSONObject result = function("url",paramsArrayList);
txt.setText(result.getString["result1"]);
i want to use so basic, please help me, what should i use? Thanks...
To send and receive data from php, you need to implement HTTP client in android side. I would strongly recommed you to use Retrofit, A type-safe HTTP client for Android and Java.
http://square.github.io/retrofit/
//delcare API interface
public interface TaskService {
#GET("/tasks")
Call<List<Task>> getTasks();
}
//Asynchronous Request
TaskService taskService = ServiceGenerator.createService(TaskService.class);
Call<List<Task>> call = taskService.getTasks();
call.enqueue(new Callback<List<Task>>() {
#Override
public void onResponse(Call<List<Task>> call, Response<List<Task>> response) {
if (response.isSuccessful()) {
// tasks available
} else {
// error response, no access to resource?
}
}
#Override
public void onFailure(Call<List<Task>> call, Throwable t) {
// something went completely south (like no internet connection)
Log.d("Error", t.getMessage());
}
}

Create a Custom Completion/Callback Handler to return Objects after a HTTP Request is Completed

I am an iOS Developer starting to learn Android. In Swift, creating a completion handler is very simple, but I still can't find a way to do it in Java.
I am sorry if this question is too noob for StackOverflow people.
Problem
I am creating a class to handle all my Http Request which is done using Retrofit.
I make this function is my RequestHelper.java
public static void checkEmailAvailability(String email) {
MyWebServiceAPI serviceAPI = retrofit.create(MyWebServiceAPI.class);
Call<APIResults> call = serviceAPI.checkEmailAvailability(getAuthenticationHeader(), RequestBody.create(MediaType.parse("text/plain"), email));
call.enqueue(new Callback<APIResults>() {
#Override
public void onResponse(retrofit.Response<APIResults> response, Retrofit retrofit) {
//Parse Response Json
//Get some value and place it inside an object
//ANDI WOULD LIKE RETURN SOME BOOLEAN VALUE AND SOME OTHER STRING
}
#Override
public void onFailure(Throwable t) {
//I WOULD LIKE A BOOLEAN VALUE HERE
}
});
}
I call it like this from my MainActivity
RequestHelper.checkEmailAvailability("user#user.com");
Now the function is still void but I would like for it to return something after the on the onResponse and onFailure method.
Any thoughts please?
You should pass the Callback object as a parameter to the checkEmailAvailability().
And implement the interface when you call the method from your MainActivity,and use the response parameter in the onXXX() method as the data returned to update UI.

Categories

Resources