Using Post in Retrofit - java

Can you anyone help me giving good example on how to use retrofit for posting large data from my local DB to mysql server.
Currently I am using async-http API and strangely there is always memory error coming up. I am looking for better API that wont give memory error while uploading huge text of data.
This is my setup:
List<TextDetails> unTextList = dbvalue.getTextData();
for (TextDetails td : unTextList)
{
String textID = td.getSerialNumber();
String textSMS = td.getText();
String textAddress = td.getFulladdress();
String textDate = td.getFulldate();
String textException = td.getExceptiontext();
textDetailsBackUpDataOnline(textID , textSMS, textAddress, textDate, textException);
}
private void textDetailsBackUpDataOnline(final String textID ,
String textSMS, String textAddress, String textDate, String textException)
{
final String uploadWebsite = url_backup_text_details;
RequestParams requestParams = new RequestParams();
requestParams.put("textSMS", textSMS);
requestParams.put("textAddress", textAddress);
requestParams.put("textDate", textDate);
requestParams.put("textException", textException);
Text_HttpClient.post(uploadWebsite, requestParams, new AsyncHttpResponseHandler()
{
#Override
public void onSuccess(int statusCode, org.apache.http.Header[] headers, byte[] responseBody)
{
Log.e("textID", "= how many times");
}
#Override
public void onFailure(int statusCode, org.apache.http.Header[] headers, byte[] errorResponse, Throwable e)
{
e.printStackTrace(System.out);
}
});
}
Text_HttpClient class has the following:
public class Text_HttpClient
{
private static AsyncHttpClient client = new AsyncHttpClient();
public static void get(String url, RequestParams params, AsyncHttpResponseHandler responseHandler)
{
client.get(url, params, responseHandler);
}
public static void post(String url, RequestParams requestParams, AsyncHttpResponseHandler responseHandler)
{
client.post(url, requestParams, responseHandler);
}
}

1) Write service interface:
public interface ArticleGetListService {
#FormUrlEncoded // Request will have "application/x-www-form-urlencoded" MIME type
#POST("/api/Article/ArticleGetList")
public void getArticleList(#Field("LanguageCode") String languageCode,
#Field("CategoryId") String categoryId,
#Field("Token") String token,
Callback<ArticleViewPojo> response); //POJO: The json retrieved from the server is added to this class.
}
Here my Rest service requires 3 Parameters, change it as your need.
2) Write POJO for converting JSON returned from Rest Api into java class object so you can use data.
Just copy your JSON into this site, choose JSON source type, annotation as Gson. It will generate POJO for your JSON automatically.
3)On your Main Activity
RestAdapter restAdapter = new RestAdapter.Builder()
.setLogLevel(RestAdapter.LogLevel.FULL)
.setEndpoint(baseUrl)
.build();
ArticleGetListService articleGetListService = restAdapter.create(ArticleGetListService.class);
Callback<ArticleViewPojo> callback = new Callback<ArticleViewPojo>() {
#Override
public void success(ArticleViewPojo model, Response response) {
//use model which is data returned to you
}
#Override
public void failure(RetrofitError error) {
//handle error
}
};
//START REST CALL
articleGetListService.getArticleList(languageCode, categoryId, token, callback);
//above parameters are those written in service interface at 1
//Whole Url is baseUrl+ArticleGetListService in above example

Related

How do i send Delete request using Volley with Json object as a parameter?

My put method is working fine, but just changing the put request to Delete then its not working,, I tried even by sending its header. but still not working. I even tried Json object to set the parameter. Thanks in advance.
StringRequest stringRequest = new StringRequest(Request.Method.DELETE, url, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
Log.d("blalala", response);
String qtyReserved1 = response.toString();
Toast.makeText(mContext, "ok" + qtyReserved1, Toast.LENGTH_SHORT).show();
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Toast.makeText(mContext, "not ok" + username + Integer.toString(inventoryId), Toast.LENGTH_SHORT).show();
}
})
{
#Override
protected Map<String, String> getParams() throws AuthFailureError {
Map<String, String> params = new HashMap<>();
params.put("screen_name", username);
params.put("inventory_id", Integer.toString(inventoryId));
params.put("pending", "true");
return params;
}
#Override
public String getBodyContentType() {
return "application/json";
}
};
MySingleton.mySingletonInstance(mContext.getApplicationContext()).addToRequestque(stringRequest);
Volley library don't send body when you using DELETE method. You can try other library. I am providing you an example by using loopj library
Add dependency in your gradle
compile 'com.loopj.android:android-async-http:1.4.9'
Request your web Api
RequestParams requestParams = new RequestParams();
requestParams.put("screen_name", "mariyam.shimaanath");
requestParams.put("inventory_id", 19);
requestParams.put("pending", true);
String url="192.168.4.31/api/canteen/cart";
new AsyncHttpClient().delete(url, requestParams, new AsyncHttpResponseHandler() {
#Override
public void onSuccess(int statusCode, Header[] headers, byte[] responseBody) {
String rs = new String(responseBody);
// do whatever you want
}
#Override
public void onFailure(int statusCode, Header[] headers, byte[] responseBody, Throwable error) {
}
});
After lots of research, thank God I'm managed to solve the problem,, Not exactly solved the problem had in Delete request in Volley. But, I had to changed the method i need to request from server side. I changed the request to post method, I know it might not be good practice and solution, but now i managed to delete from sever. thats what i need.

Return from an over ridden method of return type void in an inner class

I am trying to develop an app in Android Studio. I'm stuck in this situation.
I'm using an AsyncHttp client to get a list of table names from a MySQL database. I'm calling the below function from the UI activity to populate the values in the Spinner. But I'm unable to return the values.The value is retrieved in the inner class and inside an overridden method whose return type is void. Please look at the code to understand further.
public void fetchAvailableLocations ()
{
AsyncHttpClient httpClient = new AsyncHttpClient();
RequestParams requestParams = new RequestParams();
String _URL = ""; // Enter URL here
byte[] retreivedBytes;
httpClient.post(_URL, requestParams, responseHandler, new AsyncHttpResponseHandler() {
#Override
public void onSuccess(int i, cz.msebera.android.httpclient.Header[] headers, byte[] bytes) {
retrievedBytes = bytes; //This is where I'm stuck
}
#Override
public void onFailure(int i, cz.msebera.android.httpclient.Header[] headers, byte[] bytes, Throwable throwable) {
//make toasts
}
});
}
One solution I thought of is to create a static field in the UI activity, make a callback function which takes the bytes as the parameter and assigns the static field to the bytes parameter and then call it from the onSuceed method. But this route looks ugly. Is there a simpler way ?
I'm kinda new to Android Programming so please help.
Instead of extending use inheritance:
public class fetchAvailableLocationsClass implements AsyncHttpResponseHandler {
public void fetchAvailableLocations() {
AsyncHttpClient httpClient = new AsyncHttpClient();
RequestParams requestParams = new RequestParams();
String _URL = ""; // Enter URL here
byte[] retreivedBytes;
httpClient.post(_URL, requestParams, responseHandler, this);
#Override
public void onSuccess ( int i, cz.msebera.android.httpclient.Header[] headers, byte[] bytes)
{
retrievedBytes = bytes; //This is where I'm stuck
}
#Override
public void onFailure ( int i, cz.msebera.android.httpclient.Header[] headers,
byte[] bytes, Throwable throwable){
//make toasts
}
}
}

Retrofit: sending POST request

This is declaration of my POST request:
#POST("/api/geo/getLoc")
public void getFriendsLocation(#Field("Id") int Id, #Field("Number") String Number, #Field("FriendNumber") String FriendNumber, Callback<JsonElement> response);
This is how i try to send and handle this request:
String ENDPOINT = "http://52.88.**.***";
FriendModel ff = new FriendModel();
ff.setFriendNumber("380935275259");
ff.setId(516);
ff.setNumber("380936831127");
RestAdapter adapter = new RestAdapter.Builder()
.setEndpoint(ENDPOINT)
.build();
WayfAPI api = adapter.create(WayfAPI.class);
api.getFriendsLocation(ff.getId(), ff.getNumber(), ff.getFriendNumber(), new Callback<JsonElement>() {
#Override
public void success(JsonElement jsonElement, Response response) {
String strObj = jsonElement.toString();
}
#Override
public void failure(RetrofitError error) {
}
});
Error:
retrofit.RetrofitError: WayfAPI.getFriendsLocation: #Field parameters can only be used with form encoding. (parameter #1)
What's wrong with my request ?
I guess you forget #FormUrlEncoded annotation in your method declaration. It should be like this:
#FormUrlEncoded
#POST("/api/geo/getLoc")
public void getFriendsLocation(#Field("Id") int Id, #Field("Number") String Number, #Field("FriendNumber") String FriendNumber, Callback<JsonElement> response);

Best way to model Android REST connection

I am making an Android app that connects to a web service via REST API and I have a dilemma with the design of the internal architecture.
Now I have class Client.java whose purpouse is make connect with the server (ConnectionMethod is Enum that contains GET|POST values):
public class Client {
private AsyncHttpClient client = new AsyncHttpClient(); //I use com.loopj.AsyncHttpClient to connect
private ConnectionMethod method;
private RequestParams params = new RequestParams();
private AsyncHttpResponseHandler responseHandler = new JsonHttpResponseHandler(){
#Override
public void onSuccess(int statusCode, Header[] headers, JSONObject response) {
//Actions when connection success
}
#Override
public void onFailure(int statusCode, Header[] headers, JSONObject response, Throwable error) {
//Actions when connection fails
}
};
public Client (RequestParams params, ConnectionMethod method) {
this.params = params;
this.method = method;
}
public void addParameters (Map<String, String> parameters) {
for (Map.Entry<String, String> entry : parameters.entrySet()) {
this.params.put(entry.getKey(), entry.getValue());
}
}
public ServerResponse connect () {
RequestHandle handle;
if (this.method==ConnectionMethod.POST) {
handle = postRequest();
}
else {
handle = getRequest();
}
//How can I treat here different type of responses homogeneously?
}
private RequestHandle getRequest () {
return client.get(Constants.getEndpoint(), this.params, this.responseHandler);
}
private RequestHandle postRequest () {
return client.post(Constants.getEndpoint(), this.params, this.responseHandler);
}
}
A sample method that requests info from the server is this:
public static void login (String login, String password) {
//This classes should be static or dynamic?
Map<String, String> map = new HashMap<String, String>();
map.put("login", login);
map.put("password", password);
map.put("method", "site_login");
Client c = new Client();
c.addParameters(map);
c.getRequest();
}
All server responses are JSON: {status:0, result:array/int/string} when response is correct and {status:-1, message:string} when response is incorrect.
Additionaly I want to make classes to model components from JSON result (User.java, Message.java...) and intermediate methods between UI and API to implement the logic of the app and classes.
What is the best way to design an homogeneous connection system that manages automatically correct/fail response and independent of model (user, message...)?
There is a bunch of frameworks which can make this whole process much easier.
For example Retrofit is very simple framework for mapping java classes to REST calls. It comes with gson which will automatically deserialize response from json to plain java objects.
It also allows use callbacks as well as rxJava Observables. It allows to handle errors as well.
You can check sample app: https://github.com/JakeWharton/u2020
You are describing tools that already exist. My favorite happens to be Retrofit but there are others out there. Retrofit can handle the success and fail responses and even map JSON directly to a POJO.
My API client
public class ApiClient {
private static ApiInterface sApiInterface;
public static ApiInterface getApiClient(Context context) {
//build the rest adapter
if (sApiInterface == null) {
final RestAdapter restAdapter = new RestAdapter.Builder()
.setEndpoint("example.com")
.build();
sApiInterface = restAdapter.create(ApiInterface.class);
}
return sApiInterface;
}
public interface ApiInterface {
#GET("/program/{id}")
void getProgram(#Path("id") int id, RetrofitCallback<Program> callback);
}
My RetrofitCallback
public class RetrofitCallback<S> implements Callback<S> {
private static final String TAG = RetrofitCallback.class.getSimpleName();
#Override
public void success(S s, Response response) {
}
#Override
public void failure(RetrofitError error) {
Log.e(TAG, "Failed to make http request for: " + error.getUrl());
Response errorResponse = error.getResponse();
if (errorResponse != null) {
Log.e(TAG, errorResponse.getReason());
if (errorResponse.getStatus() == 500) {
Log.e(TAG, "Handle Server Errors Here");
}
}
}
}
My model
public class Program {
#Expose
private doublea.models.Airtime Airtime;
#Expose
private String id;
#Expose
private String title;
#SerializedName("short_name")
#Expose
private String shortName;
#SerializedName("full_description")
#Expose
private String fullDescription;
#SerializedName("short_description")
#Expose
private String shortDescription;
#Expose
private doublea.models.Image Image;
#SerializedName("image")
#Expose
private String imageName;
#Expose
private List<Host> hosts = new ArrayList<Host>();
#Expose
private List<Category> categories = new ArrayList<Category>();
#Expose
private List<Airtime> airtimes = new ArrayList<Airtime>();
/** Getters and Setters */
public Program() {
}
How it is used.
private void executeProgramApiCall(int programId) {
ApiClient.getApiClient(this).getProgram(programId, new RetrofitCallback<Program>() {
#Override
public void success(Program program, Response response) {
super.success(program, response);
addDataToAdapter(program);
}
});
}

Getting response out of AsyncHttpClient

Im using this lib: http://loopj.com/android-async-http/ to make all my requests && The biggest thing currently making my code messy is that I havent been able to successfully get my Async Http Request Responses out of onSuccess() so that the data is available to the rest of the class freely. Up till this point I have been parsing all my request responses inside the curlys of my responsehandlers onSuccess(){}
I came across this post on Stack:How to get the result of OnPostExecute() to main activity because AsyncTask is a separate class?
but have yet to get it to work with this lib.
import com.loopj.android.http.*;
public class TwitterRestClient {
private static final String BASE_URL = "http://api.twitter.com/1/";
private static AsyncHttpClient client = new AsyncHttpClient();
public static void get(String url, RequestParams params, AsyncHttpResponseHandler responseHandler) {
client.get(getAbsoluteUrl(url), params, responseHandler);
}
public static void post(String url, RequestParams params, AsyncHttpResponseHandler responseHandler) {
client.post(getAbsoluteUrl(url), params, responseHandler);
}
private static String getAbsoluteUrl(String relativeUrl) {
return BASE_URL + relativeUrl;
}
}
import org.json.*;
import com.loopj.android.http.*;
class TwitterRestClientUsage {
public void getPublicTimeline() throws JSONException {
TwitterRestClient.get("statuses/public_timeline.json", null, new JsonHttpResponseHandler() {
#Override
public void onSuccess(JSONArray timeline) {
// Pull out the first event on the public timeline
JSONObject firstEvent = timeline.get(0);
String tweetText = firstEvent.getString("text");
// Do something with the response
System.out.println(tweetText);
}
});
}
}
I do not know if this helps, but I have had to face the same problem (I am quite the novice at java and android). Used an interface. http://www.gdgankara.org/2013/03/25/android-asynchronous-http-client-a-callback-based-http-client-library-for-android-and-android-smart-image-view/
Try this:
public static void get(String url, RequestParams params, AsyncHttpResponseHandler responseHandler) {
client.get(getAbsoluteUrl(url), params, responseHandler);
String response = new String(responseHandler);
Log.i("RESPONSE", response);
}

Categories