Inner class Java - java

Good evening. I have some troubles with getting response.
I have two classes:
MyHttpClient with method get(), and String for response.
public class MyHttpClient {
private static final String BASE_URL = "http://pgu.com";
private static String response;
private static AsyncHttpClient client = new AsyncHttpClient();
public static void get(String url, RequestParams params, AsyncHttpResponseHandler responseHandler) {
client.get(getAbsoluteUrl(url), params, responseHandler);
}
private static String getAbsoluteUrl(String relativeUrl) {
return BASE_URL + relativeUrl;
}
public static String getResponse() {
return response;
}
public static void setResponse(String response) {
response = response;
}
}
In second class I'm using GET method. Html is printing in LogCat, but setResponse doesn't work. How can I get the response String as a field of MyHttpClient ?
public class MyHttpClientUsage {
public MyHttpClientUsage(){
}
public void getInfoAbout() throws HttpException{
RequestParams params = new RequestParams();
params.put("a", "Static");
params.put("content", "47");
MyHttpClient.get("", params, new AsyncHttpResponseHandler(){
#Override
public void onSuccess(String response) {
System.out.println(response);
//Write HTML in LogCat(work)
MyHttpClient.setResponse(response); //doesn't work
}
});
}
}

you need to use this.response = response in MyHttpClient as currently you are just resetting the parameter that you're sending into the method.
It's good practice to set your method parameters as final to avoid this.

Related

How to solve E/error: End of input at line 1 column 1 path $ in android studio

When I try to call rest API in the android studio I get an error that:
E/error: End of input at line 1 column 1 path $
I use firebase for the database and retrofit2 library.
But when I call the values a go to the firebase database and call the onFailure in call.enqueue() method.
public class APis {
public static final String URL = "http://192.168.178.43:8081/api/";
public static userService setuser() {
return client.getClient(URL).create(userService.class);
}
}
public interface userService {
#Headers("Content-Type: application/json")
#POST("signup")
Call<userlog> adduser(#Body userlog userlog);
}
public class userlog {
#SerializedName("email")
#Expose
private String emial_;
#SerializedName("password")
#Expose
private String password_;
#SerializedName("name")
#Expose
private String name_;
public userlog() {
}
public userlog(String emial_, String password, String name_) {
this.emial_ = emial_;
this.password_ = password;
this.name_ = name_;
}
public String getEmial_() {
return emial_;
}
public void setEmial_(String emial_) {
this.emial_ = emial_;
}
public String getPassword_() {
return password_;
}
public void setPassword_(String password_) {
this.password_ = password_;
}
public String getName_() {
return name_;
}
public void setName_(String name_) {
this.name_ = name_;
}
}
public void setPassword_(String password_) {
this.password_ = password_;
}
}
private void adduser_(userlog userll) {
service = APis.setuser();
Call<userlog> call = service.adduser(userll);
call.enqueue(new Callback<userlog>() {
#Override
public void onResponse(Call<userlog> call, Response<userlog> response) {
if (response.isSuccessful()) {
Toast.makeText(getApplicationContext(), "Success", Toast.LENGTH_SHORT).show();
/* userdetails.setUserid(firebaseAuth.getUid());
userdetails.setEmail_(emailId.getText().toString());
startActivity(new Intent(SignupActivity.this, MainnewActivity.class));*/
}
}
#Override
public void onFailure(Call<userlog> call, Throwable t) {
Log.e("error", t.getMessage());
Toast.makeText(getApplicationContext(), "not Successdd", Toast.LENGTH_SHORT).show();
}
});
}
when I call "adduser_(userll)" method, I get a notification that "not Successdd".
The problem related to retrofit, i think the problem because the response of the call come as null or empty
you can create NullConverterFactory.class :
public class NullConverterFactory extends Converter.Factory {
#Override
public Converter<ResponseBody, ?> responseBodyConverter(Type type, Annotation[] annotations, Retrofit retrofit) {
final Converter<ResponseBody, ?> delegate = retrofit.nextResponseBodyConverter(this, type, annotations);
return new Converter<ResponseBody, Object>() {
#Override
public Object convert(ResponseBody body) throws IOException {
if (body.contentLength() == 0) return null;
return delegate.convert(body);
}
};
}
}
and add to the create of the retrofit
baseUrl(Config.URL+"/")
.client(okHttpClient)
// -----add here-------
.addConverterFactory(new NullConverterFactory())
//---------------------
.addConverterFactory(GsonConverterFactory.create())
.build()

How to write retrofit function for the following

How can I write a retrofit function to receive the following api call. I have only called retrofit functions where we pass parameters directly in params and not in body form-data so I don't know how to do this.
Although it's not right at all, This is what I have tried :
This is my mainActivity-
private void login(String username, String password) {
Call<User> call = student_signin.apiInterface.studentLogin("json",username, password);
call.enqueue(new Callback<User>() {
#Override
public void onResponse(Call<User> call, Response<User> response) {
if (response.body().getError_code() == "401") {
Toast.makeText(student_signin.this, response.body().getError_message(), Toast.LENGTH_SHORT).show();
} else if (!response.body().getU_id().isEmpty()){
Toast.makeText(student_signin.this, "user signed in successfully", Toast.LENGTH_SHORT).show();
}
}
#Override
public void onFailure(Call<User> call, Throwable t) {
Toast.makeText(student_signin.this,t.getMessage(),Toast.LENGTH_LONG).show();
}
});
}
This is my APIinterface class-
public interface APIinterface {
#FormUrlEncoded
#POST("login")
Call<User> studentLogin(#Query("format") String format, #Field("username") String username, #Field("password") String password);
}
This is my APIclient class-
public class APIclient {
public static final String BASE_URL = "https://www.example.com/api/xyz/";
public static Retrofit retrofit = null;
public static Retrofit getApiClient()
{
if(retrofit==null)
{
// Gson gson = new GsonBuilder().setLenient().create();
retrofit = new Retrofit.Builder().baseUrl(BASE_URL).addConverterFactory(GsonConverterFactory.create()).build();
}
return retrofit;
}
}
And this is my model class-
public class User {
#Expose
#SerializedName("u_id")
private String u_id;
#Expose
#SerializedName("customer_id")
private String customer_id;
#Expose
#SerializedName("error_code")
private String error_code;
public String getU_id() {
return u_id;
}
public String getCustomer_id() {
return customer_id;
}
public String getError_code() {
return error_code;
}
}
Any help would be greatly appreciated and acknowledged.
#POST("/api/xyz/login")
fun getData(#Body params: JsonObject): JsonObject
client.getData(JsonObject().apply {
addProperty("advice_id", adviceId)
addProperty("content", content)
})
you can use this method to send the user name and password as pram in method getData() and revice the json as user list
#GET("/api/xyz/login")
Call<List<User>> getData(#Query("user_name") String userName,#Query("password") String password);

Volley attach access token to evey request using singleton

I am doing the following which perfectly works
//else proceed with the checks
JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(
Request.Method.GET,
checkauthurl,
null,
new Response.Listener<JSONObject>() {
#Override
public void onResponse(String response) {
//do stuff here
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
// do stuff here
}
}) {
#Override
public Map<String, String> getHeaders() throws AuthFailureError {
HashMap<String, String> headers = new HashMap<String, String> ();
TokenService tokenservice = new TokenService(ctx);
String accesstoken = tokenservice.getToken(ApiHelper.ACCESS_TOKEN_SHARED_PREF);
headers.put("Authorization", "Bearer " + accesstoken);
return headers;
}
};
// Access the RequestQueue through your singleton class.
ApiSingleton strngle = new ApiSingleton(ctx);
strngle.addToRequestQueue(jsonObjectRequest);
For every request, I have to add the request header. How can I set request headers directly in the singleton.
This is my singleton
private static ApiSingleton mInstance;
private RequestQueue mRequestQueue;
public static Context mCtx;
private ImageLoader mImageLoader;
public ApiSingleton(Context context) {
mCtx = context;
mRequestQueue = getRequestQueue();
//do stuff
}
public RequestQueue getRequestQueue() {
if (mRequestQueue == null) {
// getApplicationContext() is key, it keeps you from leaking the
// Activity or BroadcastReceiver if someone passes one in.
mRequestQueue = Volley.newRequestQueue(mCtx.getApplicationContext());
}
return mRequestQueue;
}
How do I avoid the above code duplication when attaching the bearer token in every request?
public class CustomJsonRequest extends JsonRequest<Object>{
public CustomJsonRequest(String url, String requestBody, Response.Listener<Object> listener,
Response.ErrorListener errorListener) {
super(url, requestBody, listener, errorListener);
}
public CustomJsonRequest(int method, String url, String requestBody, Response.Listener<Object> listener,
Response.ErrorListener errorListener) {
super(method, url, errorListener);
}
#Override
protected Response<Object> parseNetworkResponse(NetworkResponse response) {
return Response.success(Object, HttpHeaderParser.parseCacheHeaders(response));
}
#Override
public Map<String, String> getHeaders() throws AuthFailureError {
Map<String, String> headers = new HashMap<String, String> ();
TokenService tokenservice = new TokenService(ctx);
String accesstoken = tokenservice.getToken(ApiHelper.ACCESS_TOKEN_SHARED_PREF);
headers.put("Authorization", "Bearer " + accesstoken);
return headers;
}
}
You can extend JsonRequest class and override getHeaders() method.
Pass instance of CustomJsonRequest object when you are adding volley requests in queue.
VolleyUtils.getInstance().addToRequestQueue(customJsonRequest);
You can write a "Factory" with a method that takes your checkauthurl and ctx and returns you an instance of the JsonObjectRequest. Your factory could implement some logic for re-use of objects that have the same auth Url if that makes sense in your case.
You can sub-class JsonObjectRequest and provide your checkauthurl and ctx as a parameter to the constructor. Similarly, you can implement a scheme to re-use the objects
The factory would be the suggested approach if you want Dependency Injection.
I would recommend against pre-allocating the Token and using it in multiple requests. Tokens expire. If the TokenService is written well, it should know when tokens will expire and refresh as needed (if possible).
Make an AppController.java file and mention this file name as android:app in manifest tag.
public class AppController extends Application {
public static final String TAG = AppController.class.getSimpleName();
private RequestQueue mRequestQueue;
private static AppController mInstance;
private ImageLoader mImageLoader;
#Override
public void onCreate() {
super.onCreate();
mInstance = this;
}
public static synchronized AppController getInstance() {
return mInstance;
}
public RequestQueue getRequestQueue() {
if (mRequestQueue == null) {
mRequestQueue = Volley.newRequestQueue(getApplicationContext());
}
return mRequestQueue;
}
public ImageLoader getImageLoader() {
getRequestQueue();
if (mImageLoader == null) {
mImageLoader = new ImageLoader(this.mRequestQueue, new LruBitmapCache());
}
return this.mImageLoader;
}
public <T> void addToRequestQueue(Request<T> req, String tag) {
req.setTag(TextUtils.isEmpty(tag) ? TAG : tag);
getRequestQueue().add(req);
}
public <T> void addToRequestQueue(Request<T> req) {
req.setTag(TAG);
getRequestQueue().add(req);
}
public void cancelPendingRequests(Object tag) {
if (mRequestQueue != null) {
mRequestQueue.cancelAll(tag);
}
}
}
Do the networking code
StringRequest strReq = new StringRequest(Request.Method.POST, AppConfig.URL_BUYER_LOGIN,
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
}
}) {
#Override
protected Map<String, String> getParams() {
}
};
// Adding request to request queue
AppController.getInstance().addToRequestQueue(strReq, tag_string_req);
}

Not able to convert JSON to Java class (call WebApi from Android app)

im working on my school project and im new in android programming but i have some programming experiance in c# and .net.
This is my code:
public class ProizvodiAPI {
public class ProizvodiVM implements Serializable
{
public Integer proizvodID;
public String naziv;
public String sifra;
public BigDecimal cijena;
public Byte[] slikaThumb;
public String jedinicaMjere;
public String vrstaProizvoda;
}
public class ProizvodiLista implements Serializable
{
public List<ProizvodiVM> proizvodi;
}
public static void GetAllProizvode(final MyRunnable<ProizvodiLista> onSuccess)
{
RequestQueue queue = Volley.newRequestQueue(MyApp.getContext());
String url = "Proizvodi/GetProizvodiVM";
// Request a string response from the provided URL.
StringRequest stringRequest = new StringRequest(Request.Method.GET, Config.urlApi + url,
new Response.Listener<String>()
{
#Override
public void onResponse(String response)
{
final Gson gson = MyGson.build();
final ProizvodiLista model = gson.fromJson(response, ProizvodiLista.class);
onSuccess.run(model);
}
}, new Response.ErrorListener()
{
#Override
public void onErrorResponse(VolleyError error)
{
Toast.makeText(MyApp.getContext() , "That didn't work", Toast.LENGTH_LONG).show();
}
});
// Add the request to the RequestQueue.
queue.add(stringRequest);
}
}
Program crashes here:
final ProizvodiLista model = gson.fromJson(response, ProizvodiLista.class);
Is the problem with deserializing json, if it is, shoud i change the Java class and what to change ?
Here is my C# class in Web Api:
public class Proizvodi
{
public int ProizvodID { get; set; }
public string Naziv { get; set; }
public string Sifra { get; set; }
public decimal Cijena { get; set; }
public byte[] SlikaThumb { get; set; }
public string JedinicaMjere { get; set; }
public string VrstaProizvoda { get; set; }
}
Based on the response you are receiving, it is a JSONArray and not a simple JSONObject. Deserialize it properly.

How can I make two simultaneous Http Requests with Loopj AsyncHttpLibrary in Android?

I am using Loopj AsyncHttpLibrary for an android application. My purpose is to show a page containing some questions and corresponding answers. The Rest API, that I am coding against, serves questions and answers at different endpoints as:
http://example.com/docs/{id}/questions
http://example.com/docs/{id}/answers
What I'm doing right now is to make an async http request for "questions", then in the success callback of the first request, I do the second request to fetch "answers". Here is my cleaned code:
MyApiClient.getQuestions(docId, new JsonHttpResponseHandler() {
#Override
public void onSuccess(JSONObject questionsResponse) {
MyApiClient.getAnswers(docId, new JsonHttpResponseHandler() {
#Override
public void onSuccess(JSONObject answersResponse) {
.... Do stuff ....
}
});
}
});
where MyApiClient is a static wrapper for the AsyncHttpLibrary as recommended in the library's documentation, it looks like this:
public class MyApiClient {
private static final String BASE_URL = "http://example.com/";
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);
}
public static void getQuestions(long docId, AsyncHttpResponseHandler responseHandler) {
get("docs/" + String.valueOf(docId) + "/questions" , null, responseHandler);
}
public static void getAnswers(long docId, AsyncHttpResponseHandler responseHandler){
get("docs/" + String.valueOf(docId) + "/answers" , null, responseHandler);
}
private static String getAbsoluteUrl(String relativeUrl) {
return BASE_URL + relativeUrl;
}
}
Is there a way to start both requests without one waiting for the other to execute?
I also need to be able use both http results in the same context (populating ui).
After some struggling, I found it was not that hard to hold a state of the network operations in my activity class. I ended up using two boolean vars: "fetchedQuestions" and "fetchedAnswers", which are reset to 'false ' before initializing network requests. Both requests are sent simultaneously and in their success methods, I check if the other request is finalized or not.
Here is the code (using Loopj AsyncHttpClient library)
public class MyActivity extends Activity {
private boolean fetchedQuestions;
private boolean fetchedAnswers;
private JSONObject questions;
private JSONObject answers;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
refresh();
}
private void refresh(){
fetchedQuestions = false;
fetchedAnswers = false;
long docId = 1;
MyApiClient.getQuestions(docId, new JsonHttpResponseHandler() {
#Override
public void onSuccess(JSONObject questionsResponse) {
questions = questionsResponse;
fetchedQuestions = true;
if (fetchedAnswers)
populatePage();
}
});
MyApiClient.getAnswers(docId, new JsonHttpResponseHandler() {
#Override
public void onSuccess(JSONObject answersResponse) {
answers = answersResponse;
fetchedAnswers = true;
if (fetchedQuestions)
populatePage();
}
});
}
private void populatePage(){
// do stuff with "questions" and "answers"
}
}
where MyApiClient is defined as
public class MyApiClient {
private static final String BASE_URL = "http://example.com/";
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);
}
public static void getQuestions(long docId, AsyncHttpResponseHandler responseHandler) {
get("docs/" + String.valueOf(docId) + "/questions" , null, responseHandler);
}
public static void getAnswers(long docId, AsyncHttpResponseHandler responseHandler){
get("docs/" + String.valueOf(docId) + "/answers" , null, responseHandler);
}
private static String getAbsoluteUrl(String relativeUrl) {
return BASE_URL + relativeUrl;
}
}
Hope this helps:
public class SampleActivity extends Activity{
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
new GetQuestionsThread().execute();
new GetAnswersThread().execute();
}
public class GetQuestionsThread extends AsyncTask<Void, Void, String> {
public GetQuestionsThread() {
}
#Override
protected String doInBackground(Void... params) {
//make post
return request;
}
#Override
protected void onPostExecute(LString result) {
// do something with result
}
}
public class GetAnswersThread extends AsyncTask<Void, Void, String> {
public GetAnswersThread() {
}
#Override
protected String doInBackground(Void... params) {
//make post
return request;
}
#Override
protected void onPostExecute(LString result) {
// do something with result
}
}
}

Categories

Resources