Get JSON with Cookie Android - java

If I log in on my website I get a cookie. That cookie is one year valid and I want it to implement in my Android application. With that cookie I can get JSON data and it works in Postman with the Interceptor extension.
But in Android I can't get it working. I tried it on many different ways:
Retrofit2:
public void GetCaregiver(){
CookieInterceptor interceptor = new CookieInterceptor();
interceptor.setSessionCookie("eyJpdiI6IjVcL1d6MEhLaGNZV3V2MFdVdFRtRVN3PT0iLCJ2YWx1ZSI6IldZWU42cUZQblcwejlDMk5LVllYOENXSThmVk9UUFIzaStxclZoUTFIRGlMazFlUzdjVDhFcTVxRllwMERncFFLZTVNQlQ0VUQ2SG5BSUE3TzJcL0Vrdz09IiwibWFjIjoiNDk3YmY3ZmE0NzA2Nzk1NzMwNTM0NDViOGNjNDllN2ZmZmYyNmNhNTdjNWYwOWYwYTIzZmI2YmI5OTc3OWZjNiJ9");
OkHttpClient okHttpClient = new OkHttpClient.Builder()
.addInterceptor(interceptor)
.build();
Gson gson = new GsonBuilder()
.setLenient()
.create();
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(zorggemakURL)
.callFactory(okHttpClient)
.addConverterFactory(GsonConverterFactory.create(gson))
.build();
RESTInterface service = retrofit.create(RESTInterface.class);
Call<List<Caregiver>> call = service.getCaregivers();
call.enqueue(new Callback<List<Caregiver>>() {
#Override
public void onResponse(Call<List<Caregiver>> call, retrofit2.Response<List<Caregiver>> response) {
Log.d("Response", response.toString());
}
#Override
public void onFailure(Call<List<Caregiver>> call, Throwable t) {
Log.d("Response", t.toString());
}
});
}
Volley:
public void GetCaregiver() {
// the request
String url = zorggemakURL + "api/user/overview";
JsonObjectRequest request = new JsonObjectRequest(Request.Method.GET,
url,
null,
new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
// response
Log.d("Response", response.toString());
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
// TODO Auto-generated method stub
Log.d("ERROR", "error => " + error.toString());
}
}) {
#Override
public String getBodyContentType() {
return "application/x-www-form-urlencoded";
}
#Override
public Map<String, String> getHeaders() throws AuthFailureError {
Map<String, String> headers = new HashMap<String, String>();
headers.put("Accept", "application/json");
String creds = String.format("%s:%s", "orlandosmits", "test123");
String auth = "Basic " + Base64.encodeToString(creds.getBytes(), Base64.DEFAULT);
headers.put("Cookie", cookie);
headers.put("Authorization", auth);
return headers;
}
};
Volley.newRequestQueue(context).add(request);
}
I will always get the HTML page back and not the JSON data. Anyone have an idea?

I got it working.
Final code:
public void GetCaregiver() {
OkHttpClient okHttpClient = new OkHttpClient.Builder()
.addInterceptor(new HeaderInterceptor()).build();
Gson gson = new GsonBuilder()
.setLenient()
.create();
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(zorggemakURL)
.callFactory(okHttpClient)
.addConverterFactory(GsonConverterFactory.create(gson))
.build();
RESTInterface service = retrofit.create(RESTInterface.class);
Call<List<Caregiver>> call = service.getCaregivers();
call.enqueue(new Callback<List<Caregiver>>() {
#Override
public void onResponse(Call<List<Caregiver>> call, retrofit2.Response<List<Caregiver>> response) {
List<Caregiver> caregivers = response.body();
String test = "";
}
#Override
public void onFailure(Call<List<Caregiver>> call, Throwable t) {
Log.d("Response", t.toString());
}
});
}
HeaderInterceptor class:
public class HeaderInterceptor implements Interceptor {
#Override
public Response intercept(Chain chain)
throws IOException {
Request request = chain.request();
request = request.newBuilder()
.addHeader("Cookie", "laravel_session=eyJpdiI6Im54UEpmbW9qdlc0a01FdG1uSGdNU3c9PSIsInZhbHVlIjoieGNuck96K0V2UWU1aG1vVE9DRDRQeWNQbEJ0UldEdWt2TUxFWjByVGVxckZ1a1NhcnE5dXMxTDBqTGtrcExQVEwzWkNQcTNSeHpUVXpFU3A5NHYxdEE9PSIsIm1hYyI6IjhlMzY0ODllYzEwOTFkNTYzZDU2ZmY1NTM5YTUyNmE0MTVlY2JmMjJkZDk0YmFiZmVhNDJmZDNkZmMwMTg5YWIifQ%3D%3D")
.build();
Response response = chain.proceed(request);
return response;
}

Related

Unable to Refresh Bearer Token using Retrofit

I'm using Retrofit and OkHttp in my Project and i want to refresh token when the server gives 401 error code and store the new token in shared preference and make the same call again without notifing the user. Token type is bearer and expires every hour.
But the output that i desired is not coming, when the token expires the authenticator does nothing.
ApiInterface.java
public interface ApiInterface {
#FormUrlEncoded
#POST("auth/login")
Call<ResponseBody> login(#FieldMap HashMap<String, Object> map);
#FormUrlEncoded
#POST("auth/register")
Call<ResponseBody> register(#FieldMap HashMap<String, Object> map);
#FormUrlEncoded
#POST("auth/forgotpassword")
Call<ResponseBody> forgotPassword(#FieldMap HashMap<String, Object> map);
#POST("auth/refresh")
Call<ResponseBody> refreshToken(#Header("Authorization") String token);
#POST("auth/GetAllInterests")
Call<ResponseBody> getAllInterest();
#POST("auth/AddUserProfile")
#Multipart
Call<ResponseBody> addUserProfile(
#Part("display_name") RequestBody display_name,
#Part("children_age_show") RequestBody children_age_show,
#Part("address") RequestBody address,
#Part("no_of_children") RequestBody no_of_children,
#Part("children_age") RequestBody children_age,
#Part("date_of_birth") RequestBody date_of_birth,
#Part("interests") RequestBody interests,
#Part List<MultipartBody.Part> images
);
#POST("auth/GetUserProfile")
Call<ResponseBody> getUserProfile();
#FormUrlEncoded
#POST("auth/ChangePassword")
Call<ResponseBody> changePassword(#FieldMap HashMap<String, Object> map);
#POST("auth/logout")
Call<ResponseBody> logout();
}
ApiClient.java
public class ApiClient {
private static Retrofit retrofit = null;
private static ApiInterface apiInterface = null;
public static Retrofit getRetrofit(Context context) {
OkHttpClient client = new OkHttpClient.Builder()
.addInterceptor(new Interceptor() {
#Override
public Response intercept(Chain chain) throws IOException {
Request request = chain.request();
if (AppPreference.getPreference(context, AppPersistence.keys.AUTH_TOKEN) != null) {
request = request.newBuilder()
.addHeader("Authorization", AppPreference.getPreference(context, AppPersistence.keys.AUTH_TOKEN))
.build();
}
return chain.proceed(request);
}
})
.authenticator(new TokenAuthenticator(context))
.build();
if (retrofit == null) {
retrofit = new Retrofit.Builder()
.baseUrl(Constants.BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.client(client)
.build();
}
return retrofit;
}
public static ApiInterface getApiInterface(Context context) {
if (apiInterface == null) {
getRetrofit(context);
apiInterface = retrofit.create(ApiInterface.class);
}
return apiInterface;
}
}
TokenAuthenticator.java
public class TokenAuthenticator implements Authenticator {
Context context;
public TokenAuthenticator(Context context) {
this.context = context;
}
#Override
public Request authenticate(Route route, Response response) throws IOException {
Log.d("Authenticator", "Authenticator Called");
if (response.code() == 401) {
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(Constants.BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build();
Log.d("Authenticator", "Requesting for New Token");
ApiInterface apiInterface = retrofit.create(ApiInterface.class);
retrofit2.Response<ResponseBody> response1 = apiInterface
.refreshToken(AppPreference.getPreference(context, AppPersistence.keys.AUTH_TOKEN))
.execute();
if (response1.isSuccessful()) {
try {
String body = response1.body().string();
JSONObject jsonObject = new JSONObject(body);
if (jsonObject.getBoolean("status")) {
String newToken = "Bearer " + jsonObject.getJSONObject("Data").getString("access_token");
AppPreference.setPreference(context, AppPersistence.keys.AUTH_TOKEN, newToken);
Log.d("Authenticator", "New Token Generated");
return response.request().newBuilder()
.header("Authorization", newToken)
.build();
}
} catch (Exception e) {
Log.e("TokenAuthenticator", e.getMessage(), e);
}
}
Toast.makeText(context, response1.body().string(), Toast.LENGTH_SHORT).show();
}
return null;
}
}
Please try the below way
(1) HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
OkHttpClient.Builder httpClient = new OkHttpClient.Builder();
try {
httpClient.addInterceptor(new Interceptor() {
#Override
public Response intercept(Interceptor.Chain chain) throws IOException {
Request request = chain.request();
// try the request
Response response = chain.proceed(request);
if (response shows expired token) {
// get a new token (I use a synchronous Retrofit call)
// create a new request and modify it accordingly using the new token
Request newRequest = request.newBuilder().build();
// retry the request
return chain.proceed(newRequest);
}
// otherwise just pass the original response on
return response;
}
});
} catch (Exception e) {
e.printStackTrace();
}
String baseUrl = "";
Retrofit retrofit = new Retrofit.Builder()
.client(okHttpClient)
.baseUrl(baseUrl)
.addConverterFactory(GsonConverterFactory.create())
.build();
apiService = retrofit.create(ApiService.class);
(2) public class TokenAuthenticator implements Authenticator {
private final ApiService apiservice;
public TokenAuthenticator(TokenServiceHolder tokenServiceHolder) {
this.tokenServiceHolder = tokenServiceHolder;
}
#Override
public Request authenticate(Proxy proxy, Response response) throws IOException {
newtoken = apiservice.refreshToken().execute();
return response.request().newBuilder()
.header(AUTHORIZATIONKEY, newtoken)
.build();
}
#Override
public Request authenticateProxy(Proxy proxy, Response response) throws IOException {
// Null indicates no attempt to authenticate.
return null;
}
}
Hope it may help you

POST request with Volley with headers and body (java, android studio)

I am trying to send a POST request with Volley in Android Studio. However, I would like to set some headers and a body. How can I do this?
In this case, the headers are id and key. Where should I add the body? I have tried to follow the numerous questions about these that are written in StackOverflow. However, it still seems like the headers and the body is not properly sent.
try {
RequestQueue requestQueue = Volley.newRequestQueue(this);
String URL = "https://url.of.the.server";
JSONObject jsonBody = new JSONObject();
jsonBody.put("Content-Type", "application/json");
jsonBody.put("id", "oneapp.app.com");
jsonBody.put("key", "fgs7902nskagdjs");
final String requestBody = jsonBody.toString();
StringRequest stringRequest = new StringRequest(Request.Method.POST, URL, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
Log.i("VOLLEY", response);
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.e("VOLLEY", error.toString());
}
}) {
#Override
public String getBodyContentType() {
return "application/json; charset=utf-8";
}
#Override
public byte[] getBody() throws AuthFailureError {
try {
return requestBody == null ? null : requestBody.getBytes("utf-8");
} catch (UnsupportedEncodingException uee) {
VolleyLog.wtf("Unsupported Encoding while trying to get the bytes of %s using %s", requestBody, "utf-8");
return null;
}
}
#Override
public Map<String, String> getHeaders() throws AuthFailureError {
Map<String, String> params = new HashMap<String, String>();
params.put("Content-Type", "application/json");
params.put("id", "oneapp.app.com");
params.put("key", "fgs7902nskagdjs");
return params;
}
#Override
protected Response<String> parseNetworkResponse(NetworkResponse response) {
String responseString = "";
if (response != null) {
responseString = String.valueOf(response.statusCode);
// can get more details such as response.headers
}
return Response.success(responseString, HttpHeaderParser.parseCacheHeaders(response));
}
};
Log.d("string", stringRequest.toString());
requestQueue.add(stringRequest);
} catch (JSONException e) {
e.printStackTrace();
}
Thank you very much for your help.
You are correctly setting the headers, you could try this
try {
RequestQueue requestQueue = Volley.newRequestQueue(this);
String URL = "https://url.of.the.server";
StringRequest stringRequest = new StringRequest(Request.Method.POST, URL, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
Log.i("VOLLEY", response);
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.e("VOLLEY", error.toString());
}
}) {
#Override
public String getBodyContentType() {
return "application/json; charset=utf-8";
}
#Override
public byte[] getBody() throws AuthFailureError {
try {
// request body goes here
JSONObject jsonBody = new JSONObject();
jsonBody.put("attribute1", "value1");
String requestBody = jsonBody.toString();
return requestBody.getBytes("utf-8");
} catch (UnsupportedEncodingException uee) {
VolleyLog.wtf("Unsupported Encoding while trying to get the bytes of %s using %s", requestBody, "utf-8");
return null;
}
}
#Override
public Map<String, String> getHeaders() throws AuthFailureError {
Map<String, String> params = new HashMap<String, String>();
params.put("Content-Type", "application/json");
params.put("id", "oneapp.app.com");
params.put("key", "fgs7902nskagdjs");
return params;
}
#Override
protected Response<String> parseNetworkResponse(NetworkResponse response) {
String responseString = "";
if (response != null) {
responseString = String.valueOf(response.statusCode);
// can get more details such as response.headers
}
return Response.success(responseString, HttpHeaderParser.parseCacheHeaders(response));
}
};
Log.d("string", stringRequest.toString());
requestQueue.add(stringRequest);
} catch (JSONException e) {
e.printStackTrace();
}
For example, if request body is
{
name: "name1",
email: "email1"
}
getBody method would be
#Override
public byte[] getBody() throws AuthFailureError {
JSONObject jsonBody = new JSONObject();
jsonBody.put("name", "name1");
jsonBody.put("email", "email1");
String requestBody = jsonBody.toString();
return requestBody.getBytes("utf-8");
}

Retrofit OkHttp HttpLoggingInterceptor show correctly response, but retrofit show not correctly response

I'm trying to upload a photo to the server.
My problem is that I can not get a link to this picture, which the server returns to me.
public class RetrofitClient {
public static Retrofit createService(
String username, String password) {
String authToken = Credentials.basic(username, password);
return createService(authToken);
}
public static Retrofit createService(final String authToken) {
AuthenticationInterceptor interceptor = null;
if (!TextUtils.isEmpty(authToken))
interceptor = new AuthenticationInterceptor(authToken);
Gson gson = new GsonBuilder()
.setLenient()
.create();
HttpLoggingInterceptor logging = new HttpLoggingInterceptor();
logging.setLevel(HttpLoggingInterceptor.Level.BODY);
final OkHttpClient client = new OkHttpClient.Builder()
.addInterceptor(interceptor)
.addInterceptor(logging)
.retryOnConnectionFailure(true)
.readTimeout(30, TimeUnit.SECONDS)
.connectTimeout(30, TimeUnit.SECONDS).build();
return new Retrofit.Builder()
.baseUrl(AppConstant.BASE_URL+"/")
.client(client)
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.addConverterFactory(GsonConverterFactory.create(gson))
.addConverterFactory(ScalarsConverterFactory.create())
.build();
}
public static RetroInterface getApiServices(String user_name, String passowrd) {
return createService(user_name, passowrd).create(RetroInterface.class);
}
}
RetroInterface.java
....
#Multipart
#POST("parents/profile/images")
Call<String>
uploadParentProfilePicture2(#Part MultipartBody.Part filePart);
....
Profile.java
....
MultipartBody.Part filePart = MultipartBody.Part.createFormData("file", file.getName(), RequestBody.create(MediaType.parse("image/*"), file));
RetroInterface retroInterface = RetrofitClient.getApiServices(getEmail(), getPassword());
Call<String> call = retroInterface.uploadParentProfilePicture(filePart);
call.enqueue(new Callback<String>() {
#Override
public void onResponse(#NonNull Call<String> call, #NonNull Response<String> response) {
Log.d("ldsfjjlk", "response: " + response.body());
}
#Override
public void onFailure(#NonNull Call<String> call, #NonNull Throwable t) {
Log.d("ldsfjjlk", "Throwable: " + t.getLocalizedMessage());
}
});
....
HttpLoggingInterceptor response :
"parents/654/profile/images/1530979485020.jpg"
It is right!
My log:
"parents"
What is this?
Something wrong with Retrofit?
Also I tried to replace
Call<String> to Call<ResponseBody> but:
response.body.string() == null
What did I miss?

Retrofit image upload returns bad request 400

I'm using retrofit and I need to upload and image, but I'm getting status code 400.
Here's the code.
This is the interface.
public interface SupportInterface {
//Get request for sending photo in chat
#Multipart
#POST("/api/upload-image")
Call<ResponseBody> getChatPhoto(#Header("Content-Type") String json,
#Header("Authorization") String token,
#Header("Cache-Control") String cache,
#Part("type") String type,
#Part("user_id") String userId,
#Part MultipartBody.Part image_path);
}
I'm using headers + I need to send user_id and type too. So I'm using #Part. I done right yes?
Here's the retrofit in initialization part.
public class ApiClient {
private static ApiClient instance;
OkHttpClient.Builder client = new OkHttpClient.Builder()
.readTimeout(10, TimeUnit.SECONDS)
.connectTimeout(10, TimeUnit.SECONDS)
.writeTimeout(10, TimeUnit.SECONDS);
client.addInterceptor(new Interceptor() {
#Override
public Response intercept(#NonNull Chain chain) throws IOException {
Request request = chain.request();
request = request.newBuilder()
.header("Cache-Control", "public, max-age=0")
.build();
return chain.proceed(request);
}
});
supportopApi = new Retrofit.Builder()
.baseUrl(endpoint)
.client(client.build())
.addConverterFactory(GsonConverterFactory.create())
.build()
.create(SupportopApi.class);
}
public Call<ResponseBody> getChatImage(MultipartBody.Part multipartBody) {
return supportopApi.getChatPhoto("application/json", There is my accessToken,
"no-cache", "5", This is userID, multipartBody);
}
}
If I done here something wrong please tell me.
And here's the main part.
public void getChatImage() {
File file = new File("/storage/emulated/0/Download/s-l640.jpg");
RequestBody reqFile = RequestBody.create(MediaType.parse("multipart/form-data"), file);
MultipartBody.Part multiPartFile = MultipartBody.Part.createFormData("image", file.getName(), reqFile);
Call<ResponseBody> chatImageCall = apiClient.getChatImage(multiPartFile);
chatImageCall.enqueue(new Callback<ResponseBody>() {
#Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
if (response.isSuccessful()) {
try {
Log.d(TAG, response.body().string());
} catch (IOException e) {
e.printStackTrace();
}
} else {
Toast.makeText(context, "Response is not successful: " + response.errorBody(), Toast.LENGTH_SHORT).show();
}
}
#Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
Toast.makeText(getActivity(), "An error occurred", Toast.LENGTH_SHORT).show();
}
});
}
I'm getting here bad request 400.
#Header("Content-Type") String json
You declare your content type is JSON but actually you pass to server the multipart (form data)
So I think you're trying to do:
#Header("Accept") String json
(accept JSON from server)

Sending multiple requests using OkHTTP android

I am sending multiple images using OkHTTP. Since all the requests are asynchronous, I cannot run my final call until all the requests are done. How can I achieve this in OkHTTP?
I need to run my RunFinalRequest() after all the images have been sent. What I tried is, I put the my RunFinalRequest() on OnResponse() but it sometimes doesn't go through even though there is a response. Is there a better way to do it?
Here is my code:
public void SendALL(){
OkHttpClient client = new OkHttpClient();
client.dispatcher().setMaxRequestsPerHost(50);
final MediaType MEDIA_TYPE = MediaType.parse("image/png");
for (int i = 0; i < images.size(); i++){
File sourceFile = new File(images.get(i).getImageURI());
RequestBody requestBody = new MultipartBody.Builder()
.setType(MultipartBody.FORM)
.addFormDataPart("image", sourceFile.getName(), RequestBody.create(MEDIA_TYPE, sourceFile))
.addFormDataPart("name", images.get(i).getJobID())
.build();
Request request = new Request.Builder()
.url("xxxxxxxxxxx")
.post(requestBody)
.build();
client.newCall(request).enqueue(new Callback() {
#Override
public void onFailure(Call call, IOException e) {
}
#Override
public void onResponse(Call call, Response response) throws IOException {
}
});
}
if(signatures.size() > 0){
File sourceFile = new File(Uri.parse(signatures.get(0).getImageURI()).toString());
String newJobID = signatures.get(0).getJobID().concat("-signature");
RequestBody requestBody = new MultipartBody.Builder()
.setType(MultipartBody.FORM)
.addFormDataPart("image", sourceFile.getName(), RequestBody.create(MEDIA_TYPE, sourceFile))
.addFormDataPart("name", newJobID)
.build();
Request request = new Request.Builder()
.url("XXXXXXXXXXX")
.post(requestBody)
.build();
client.newCall(request).enqueue(new Callback() {
#Override
public void onFailure(Call call, IOException e) {
}
#Override
public void onResponse(Call call, Response response) throws IOException {
}
});
}
RunFinalRequest();
You may try following mechanism:
private int uploadedImageCount;
...
public void sendAll() {
uploadedImageCount = 0;
OkHttpClient client = new OkHttpClient();
client.dispatcher().setMaxRequestsPerHost(50);
MediaType MEDIA_TYPE = MediaType.parse("image/png");
for (int i = 0; i < images.size(); i++) {
File sourceFile = new File(images.get(i).getImageURI());
RequestBody requestBody = new MultipartBody.Builder()
.setType(MultipartBody.FORM)
.addFormDataPart("image", sourceFile.getName(), RequestBody.create(MEDIA_TYPE, sourceFile))
.addFormDataPart("name", images.get(i).getJobID())
.build();
Request request = new Request.Builder()
.url("xxxxxxxxxxx")
.post(requestBody)
.build();
client.newCall(request).enqueue(new Callback() {
#Override
public void onFailure(Call call, IOException e) {
onImageUploadFailed();
}
#Override
public void onResponse(Call call, Response response) throws IOException {
if (response.isSuccessful()) {
onImageUploaded();
} else {
onImageUploadFailed();
}
}
});
}
if (signatures.size() > 0) {
File sourceFile = new File(Uri.parse(signatures.get(0).getImageURI()).toString());
String newJobID = signatures.get(0).getJobID().concat("-signature");
RequestBody requestBody = new MultipartBody.Builder()
.setType(MultipartBody.FORM)
.addFormDataPart("image", sourceFile.getName(), RequestBody.create(MEDIA_TYPE, sourceFile))
.addFormDataPart("name", newJobID)
.build();
Request request = new Request.Builder()
.url("XXXXXXXXXXX")
.post(requestBody)
.build();
client.newCall(request).enqueue(new Callback() {
#Override
public void onFailure(Call call, IOException e) {
}
#Override
public void onResponse(Call call, Response response) throws IOException {
}
});
}
}
public void onImageUploaded() {
uploadedImageCount++;
if (uploadedImageCount == images.size()) {
runFinalRequest();
}
}
public void onImageUploadFailed() {
// Handle failure case. You may detect failed image and try to resend
}

Categories

Resources