I am developing an Android app using Parse.com website. In which whatever user sends data that must be received by receiver, but here I have to use REST api. I succeeded to send data to Parse website but now I have to Push that data with the help of REST api only. I am confused with REST api. Help to solve it.
You can use a library for that. I would suggest this one https://github.com/kodart/Httpzoid
It has clean API and type-safe data.
Here is a simple usage example
Http http = HttpFactory.create(context);
http.post("http://example.com/users")
.data(new User("John"))
.execute();
Or more complex with callbacks
Http http = HttpFactory.create(context);
http.post("http://example.com/users")
.data(new User("John"))
.handler(new ResponseHandler<Void>() {
#Override
public void success(Void ignore, HttpResponse response) {
}
#Override
public void error(String message, HttpResponse response) {
}
#Override
public void failure(NetworkError error) {
}
#Override
public void complete() {
}
}).execute();
It is fresh new, but looks very promising.
Related
Before I get the obligatory "you shouldn't be testing real network responses for XYZ reasons!", it should be noted that I am not asking whether or not I should.
I am asking specifically how I would go about doing so, if I wanted to.
After a few hours of struggle I've successfully managed a proper response from Volley, and have that test going.
The problem I'm having now, is that call.enque(...) seems to hang on the RobolectricTestRunner. Unlike Volley, I can't peek in and see whats going on in there (for Volley, the challenge was not realizing that Looper.getMainLooper doesn't get properly created.)
So, all I am doing is trying to make a simple request to the server via Retrofit. The issue, as I said, is that the entire system hangs at call.enqueue, and there is no error or response ever (even when my await is longer). The network call works fine with volley, but I am getting this snag here with Retrofit. Here's the code if you want to try it. And of course, the function works fine when the app is running.
//in NetworkManager.class
public void someCall(HashMap properties, NetworkResponseListener listener){
this.okHttpClient = new OkHttpClient.Builder().cache(new Cache(appContext, 35 * 1024 * 1024)).build();
this.retrofit = new Retrofit.Builder().baseUrl(httpPath + apiHost).client(okHttpClient).build();
this.myService = retrofit.create(MyService.class);
Call call = myService.someRequest(properties);
call.enqueue(new Callback<ResponseBody>() {
#Override
public void onResponse(Call<ResponseBody> call, retrofit2.Response<ResponseBody> response) {
listener.onSuccess(response);
}
#Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
listener.onError(t);
}
});
}
Service:
interface MyService {
#GET("/api/SomeEndpoint/")
Call<ResponseBody> someRequest(#QueryMap Map<String, Object> params);
}
Test:
#Test
public void testSomeCall() throws Exception {
//Network class has setup OkHttpClient/Service/Retrofit already
NetworkResponseListener listener = new NetworkResponseListener() {
#Override
public void onSuccess(Response response) {
this.response = response;
}
#Override
public void onError(Throwable error) {
//
}
};
NetworkManager.someCall(this.properties, listener);
await().atMost(30, TimeUnit.SECONDS).until(ResponseReceived());
}
Everyone's response on stackoverflow has been 'don't test real network responses', which is really not helpful.
Solution is pretty much exactly the same as for volley.
Retrofit2 will default to the platform callback executor, which will not be correctly instantiated in a test.
Solution is simple. If you wish to test retrofit with real network calls, you must change the callbackExector. Here's what I ended up doing:
retrofit = new Retrofit.Builder().baseUrl(baseUrl)
.client(okHttpClient).callbackExecutor(Executors.newSingleThreadExecutor())
Network tests are running successfully.
I have written a Retrofit code which has a Yii2 backend. The problem is: when I call the web-service on backend, it works perfectly. However, when I try to call the web-service from android device; it throws a response code of 404. Here is what I have done:
I am targeting a url which looks like: http://192.168.0.104/root-web/web/index.php?r= and it had an end-point: root/register
public interface RegisterAPIService {
#POST("practice/register")
Call<RegisterModel> registerUser(#Body RegisterDetails registerDetails);
}
The code in my activity looks like this..
RegisterDetails registerDetails = new RegisterDetails(email, mobile, password);
RegisterAPIService registerAPIService = retrofit.create(RegisterAPIService.class);
Call<RegisterModel> call =registerAPIService.registerUser(registerDetails);
call.enqueue(new Callback<RegisterModel>() {
#Override
public void onResponse(Response<RegisterModel> response) {
Log.d("Message", "code..."+response.code() + " message..." + response.message()+" body..."+response.body());
}
#Override
public void onFailure(Throwable t) {
}
});
} else {
// Error
}
}
I am getting 404 for the above code. I am trying to send my parameters in the form of a POST request. Please guide me through it.
You should call your development machine from the device, by its ip address, based on how they are connected. Also you can use Android Reverse Tethering tools for your operating system. for further study and options you can take a look at the answers to this question
It would be great if you share some knowledge with me! Here is my problem - we have an Android app. and a server. For some of the calls the client needs to send a previously obtained token from the server which is legit for a limited amount of time. If it happens that the token is not valid any more, an error is returned from the sever, a new token needs to be obtained and we need to retry the request.
But how can I handle such behavior with Retrofit? Any thoughts?
Thank you in advance!
How about you try and make a request with a callback, if the callback is a failure and the error message is that the token needs to be obtained, then you do a request to get the new token for example:
connectionInterface.getSomeStuff(object, new Callback<ObjectPOJO>() {
#Override
public void success(ObjectPOJO objectPOJO, Response response) {
//success
}
#Override
public void failure(RetrofitError error) {
if (error.getLocalizedMessage().equals("Token expire error")
connectionInterface.getToken();
}
Then in your retrofit getToken callback, if it is a success you will redo the getSomeStuff method and if it is a failure, you let the user know. For example:
connectionInterface.getToken(token, new Callback<token>() {
#Override
public void success(token token, Response response) {
//success and token has been added
//add the token to your request somehow...
connectionInterface.updateToken(token);
connectionInterface.getSomeStuff();
}
#Override
public void failure(RetrofitError error) {
//error let user know
}
Let me know if you have any other question. I think this will be the easiest way of doing it.
I am developing a communication's system between an Android App and a Server.
I am using Retrofit API for the Android's communication with the Server.
When I do a GET (from Android side) to get info from the Server, I use a CallBackTask method like this:
public void testGet()
{
RestAdapter restAdapter = new RestAdapter.Builder()
.setEndpoint(UserApi.SERVER)
.build();
final UserApi svc = restAdapter.create(UserApi.class);
if (svc != null) {
CallableTask.invoke(new Callable<Test>() {
#Override
public Test call() throws Exception {
Test g = svc.getTest();
System.out.println("getVdd() = "+g.getVdd()+"+ getResp() = "+g.getResp());
return g;
}
}, new TaskCallback<Test>() {
#Override
public void success(Test result) {
Intent i = new Intent(getApplicationContext(),SplashRapidoActivity.class);
startActivity(i);
}
#Override
public void error(Exception e) {
Toast.makeText(
getApplicationContext(),
"Unable to connect, please try again.",
Toast.LENGTH_SHORT).show();
}
});
}
}
Where the Test.class is a POJO class with variables and his getters and setters:
public class Test {
String vdd;
String resp;
public Test()
{
}
public void setVdd(String vdd) {
this.vdd = vdd;
}
public String getVdd() {
return vdd;
}
public void setResp(String resp)
{}
public String getResp()
{
return resp;
}
}
So, my question is, which is the best ERROR RESPONSE i could send from the server if there aren't valid values for the Test.class in the server?
Actually there is no "the best error response". It depends on your requirements. But there is widely used architecture called REST and Retrofit was designed in according with REST interaction. REST basically is just a set of rules which clients and servers understand without any documentation.
So if you want to retrieve(GET) some object/data from server by REST you can either receive it with status 200 or receive status 404 with appropriate description of error(or without it) inside body.
Here some more to read.
The best error response is one that make sense to you as a developer. I wouldn't mess with the default HTTP status/error codes. Instead I would send a specific response from the server. For example, keep the HTTP response code at 200 but in the data you send to the app set it to "ERROR: no values." or whatever you prefer. Then, in your Android app, check the response to see if it contains values or an error. Something like
if(resp.startsWith("ERROR:")){
// Do error handling //
} else {
// Normal code //
}
I've seen answer to both of these questions, however, when I tried to put them together, I couldn't make it work. The problem itself is pretty simple: I want to get a string from one site and use it in a post request. That means I can only make the post request after I've finished parsing the GET request. The main ideas I'm using are these ones:
How to return response header field to main method using Google Volley for HTTP GET request in Android / Java?
Can I do a synchronous request with volley?
However the synchronous request is blocked and doesn't go on, and the first one is Async.
I believe this to be a simple thing to do, but still, I haven't be able to do it...
Thanks for any help!
Why not do something like this:
// send first request
requestQueue.add(firstRequest, null, new Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
// ** code to parse response **
// send second request
requestQueue.add(secondRequest, null, new Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
// ** code to parse response **
}
}, new ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
// ** code to handle errors **
}
}));
}
}, new ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
// ** code to handle errors **
}
}));