Volley JsonObjectRequest Put is not working - java

I am making JsonObjectRequest with Put method but it is not working and getting "{"detail":"Method \"GET\" not allowed."}" error message.
It is working fine on Postman. See attached screenshots for more information.
I didn't modify JsonObjectRequest. I copy this code from google sample code from here "http://developer.android.com/training/volley/request.html".
I don't think this could be a bug in Volley. Please go through my code and let me know what I am doing wrong.
JsonObjectRequest jsObjRequest = new JsonObjectRequest
(Request.Method.PUT, url, null, new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
hideDialog();
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
// TODO Auto-generated method stub
hideDialog();
}
})
{
#Override
public Map getHeaders() throws AuthFailureError {
Map headers = new HashMap();
headers.put("Authorization", "Token " + dm.readString("auth_token"));
return headers;
}
};
AppController.getInstance().addToRequestQueue(jsObjRequest);
Edit: I know in the screenshot it shows 400 bad request. It is because i need to pass 2 params ie {"dg_id":"80","delivery_ids":["90936"]}. With this params also i am getting the same error in Volley.
Sample auth_token Value: MTIzNDU2NzIzNDM6ZGVsaXZlcnlndXk=
Sample Body value: {"dg_id":"80","delivery_ids":["90936"]}

Add "/" at end of DELETE, PUT interface url,do check out the following snippet.
If a client issues a GET request to "/testdir/" (i.e., at the
directory).......It is interesting to take note that if a client issue
a GET request to "/testdir" (without specifying the directory path
"/"), the server returns a "301 Move Permanently" with a new
"Location" of "/testdir/", as follows.

Related

How to access Volley response in another Class or Scope?

Hi there I am struggling to understand how exactly Volley request works. I have done similar things in NodeJs and the process seemed more intuitive.
String url = "http://my-json-feed";
JsonObjectRequest jsonObjectRequest = new JsonObjectRequest
(Request.Method.GET, url, null, new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
//All I want is to use the response outside this scope
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
// TODO: Handle error
}
});
MySingleton.getInstance(this).addToRequestQueue(jsonObjectRequest);
//Example: How can I access the response here or in any other class?
In NodeJS this same process looks similar to this (with the help of node-fetch)
const response = await fetch(url);
const json = await response.json();
console.log(json);
And I can basically access json from anywhere in the same file or I can return it from the current function and use it anywhere where I call that function. I want to ask how can I do something similar in Java?

Unable to create file on Onedrive through Microsoft Graph Rest API

I am creating an Android app that uploads basic text files to a user's onedrive by using the Microsoft Graph API.
I have discovered by using https://developer.microsoft.com/en-us/graph/graph-explorer to create files using a PUT request with the link "https://graph.microsoft.com/v1.0/me/drive/root:/Test.txt:/children", With the header "Content-Type" "text/plain", and filling the request body with the text to go into the text file. Using the graph explorer, this works without any issues, however when testing my code with all of these things, it always gives me an error 400.
public void saveOpportunityToServer (final String textToSave, String fileName)
{
try
{
StringRequest request = new StringRequest(Request.Method.PUT, "https://graph.microsoft.com/v1.0/me/drive/root:/" + fileName + ":/content",
new Response.Listener<String>() {
#Override
public void onResponse(String response)
{
Log.d ("PAST QUOTES SAVE", "Created file on server");
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error)
{
Log.e ("PAST QUOTES SAVE", "Failed to create file on server: " + error.toString());
}
})
{
#Override
public byte[] getBody() throws AuthFailureError {
return textToSave.getBytes();
}
#Override
public Map<String, String> getHeaders() throws AuthFailureError {
HashMap<String, String> headers = new HashMap<String, String>();
headers.put ("Authorization", "Bearer " + mAccessToken);
headers.put ("Content-Type", "text/plain");
return headers;
}
};
serverRequest.getInstance().addToRequestQueue(request, "Create past quote file request");
}catch (Exception e){
Log.e ("PAST QUOTES SAVE", "Failed to create file on server");
}
}
Where serverRequest is an instance of Volley.RequestQueue.
If the function "getBody()" in String Request is left untouched, or the "textToSave" string is empty, the server responds with a success, creates the requested file, but as expected, the file is empty.
Does anyone have a solution, or at least a reason for why the plain text isn't being accepted?
Edit: Request & Response Headers and Body
Headers:
"Authorization" "Bearer [AccessToken]"
"Content-Type" "text/plain"
Body:
"This is a test"
I'm certain the authorization is working, but I guess there is a chance that the server is not properly interpreting the content-type header, however it works on the mentioned website, so I am not sure why it wouldn't in my program.
The response is an empty Error 400, which is stated as a Malformed Request by Microsoft, which leads me to believe the above, however I cant see a way to fix it.
Finally, I found where the issue is.
Due to how volley works, you cannot simply add a "Content-Type" header to the "getHeaders()" function. To change the body content type, you must override a separate function, "geyBodyContentType()"
Here is my final request code, for anyone wondering in the future how to solve this problem.
StringRequest request = new StringRequest(Request.Method.PUT, "https://graph.microsoft.com/v1.0/me/drive/root:/ " + fileName + ":/content",
new Response.Listener<String>() {
#Override
public void onResponse(String response)
{
Log.d ("PAST QUOTES SAVE", "Created file on server");
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error)
{
Log.e ("PAST QUOTES SAVE", "Failed to create file on server: " + error.toString());
}
})
{
#Override
public byte[] getBody() throws AuthFailureError {
return textToSave.getBytes();
}
#Override
public Map<String, String> getHeaders() throws AuthFailureError {
HashMap<String, String> headers = new HashMap<String, String>();
headers.put ("Authorization", "Bearer " + mAccessToken);
return headers;
}
#Override
public String getBodyContentType ()
{
return ("text/plain");
}
};

How to call List Item in SharePoint Using REST API in Android?

I'm want to consume share point rest API service to call from Android previously i use to call share point web service through the graph API but while generating token from graph API its not support in below URL, does any one have any solution about this problem.
https://mysharepoint.sharepoint.com/sites/MySite/_api/web/lists/getbytitle('Announcements')/Items
JsonObjectRequest request = new JsonObjectRequest(Request.Method.GET, MSGRAPH_URL,
parameters,new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
/* Successfully called graph, process data and send to UI */
Log.d(TAG, "Response: " + response.toString());
updateGraphUI(response);
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.d(TAG, "Error: " + error.toString());
}
}) {
#Override
public Map<String, String> getHeaders() throws AuthFailureError {
Map<String, String> headers = new HashMap<>();
headers.put("Authorization", "Bearer " + authResult.getAccessToken());
return headers;
}
};
Log.d(TAG, "Adding HTTP GET to Queue, Request: " + request.toString());
request.setRetryPolicy(new DefaultRetryPolicy(
3000,
DefaultRetryPolicy.DEFAULT_MAX_RETRIES,
DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
queue.add(request);
I already tried with MSAL library but its does not work with this token.
Update: i used to call graph api for janrating token but i got 401 error with this above mention URL.
You are calling a SharePoint API, so you will need a SharePoint token instead of a Graph token. These are two separate APIs with different authentications.
To get a SharePoint token you will need to register an App in SharePoint itself or use the users username + password if available in your app.
Also see:
https://spshell.blogspot.com/2015/03/sharepoint-online-o365-oauth.html
https://shareyourpoint.net/2017/01/25/operations-using-rest-in-sharepoint-online-authorization/
For Graph, use an URL like this to get your list items:
https://graph.microsoft.com/v1.0/sites/{site-id}/lists/{list-id}/items?expand=fields(select=Column1,Column2)
You will probably need to do several calls to get your site ID and list ID first.
https://learn.microsoft.com/en-us/graph/api/listitem-list?view=graph-rest-1.0

send json to Laravel using postman and android

i am trying to send json using postman to Lavavel but i facing this error.
enter image description here
this is my json code:
{
"email":"test#test.com",
"password":"testtest"
}
and this is Laravel codes :
Route::get('/r','test#store');
and
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use DB;
use Log;
class test extends Controller
{
public function store(Request $request)
{
$email = $request->input('email');
$password = $request->input('password');
Log::info('test');
Log::info($email);
Log::info($password);
DB::table('login')->insert([
['email' => $email],
['password' => $password]
]);
}
}
also i trying using android for send data using volley and so checked Laravel logs :
Column 'email' cannot be null (this is Laravel logs)
and on android Logs:
E/Volley: [299] BasicNetwork.performRequest: Unexpected response code 500 for http://192.168.1.4:8000/r
D/error: com.android.volley.ServerErro
my android code is :
public class ApiService {
private final Context context;
public ApiService(Context context){
this.context=context;
}
public void loginUser(String email, String password, final OnLoginResponse onLoginResponse){
JSONObject requestJsonObject=new JSONObject();
try {
requestJsonObject.put("email",email);
requestJsonObject.put("password",password);
JsonObjectRequest request=new JsonObjectRequest(Request.Method.GET, "http://192.168.1.4:8000/r",requestJsonObject , new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
Log.d("response",response.toString());
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.d("error",error.toString());
}
}) {
#Override
public Map getHeaders() throws AuthFailureError {
HashMap headers = new HashMap();
headers.put("Content-Type", "application/json");
return headers;
}
};
request.setRetryPolicy(new DefaultRetryPolicy(18000,DefaultRetryPolicy.DEFAULT_MAX_RETRIES, DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
Volley.newRequestQueue(context).add(request);
} catch (JSONException e) {
Log.e(TAG, "loginUser: "+e.toString());
}
}
public interface OnLoginResponse{
void onResponse(boolean success);
}
}
I hope this helps people trying to search on how to send JSON data to laravel not only specific to android applications but to all. The goal of this solution is to identify whether you can send a JSON data to laravel or not.
First of all you have to download postman from https://www.getpostman.com/ to test if your API is really working or not.
Create a post request using postman. Be sure that you follow the example data below
Be sure that you set your Routes that would associate to the controller
This is the controller part that will show the JSON data you sent if it was successfully accepted or not.
And also, if ever you are trying to send POST data to laravel, by default they provided a CSRF Token which is applicable for the forms if you are going to use the MVC of laravel. For the meantime, we are going to take this down and comment it out. Just go to app/http/kernel.php
and now you'll get the following result from the code earlier
$json = json_decode($request['json']);
echo $json->{'email'};
echo "\n";
echo $json->{'password'};
We tested that we were able to send data to laravel. I hope this truly helps.
Wen you want to send data, you will want to use POST or PUT method on your postman, specially if you are sending a body, that means that you are sending data. Get method is used to retrieve data from a service.
Take a look into CRUD functions for more information.
Your postman should look something like this
Last in your android code try to change this line
JsonObjectRequest request=new JsonObjectRequest(Request.Method.GET, "http://192.168.1.4:8000/r",requestJsonObject , new Response.Listener<JSONObject>() {
to use Request.Method.POST

Invalid JSON formatting in Volley post request

I am trying to pass
data={"process" : "ExampleProcess", "phone" : "123456"}
As a post request in volley, thus far I have managed to create a(very basic) method that will send
the required information out to the server, but I am getting a failed response.
I added logs to the program for which I can see
ERROR:: com.android.volley.ParseError: org.json.JSONException: End of input at character 2 of
But I believe it has to do with the way I am trying to send my information over. Upon debugging I also came to realize that I was getting an error indicating
Method threw 'java.lang.NullPointerException' exception. Cannot evaluate org.json.JSONObject.toString();
For which I do not know what to do, even if I change the:
total.put("data", data.toString());
to
total.put("data", data);
The error will persist. At this point I have no clue as to how can I go about sending the correct JSON post request to my URL(which has been taken out from the example btw)
public void volleyConnector(String url) {
final JSONObject data = new JSONObject();
final JSONObject total = new JSONObject();
try {
data.put("process", "ExampleProcess");
data.put("phone" , "123456789");
total.put("data", data.toString());
} catch(JSONException e) {
Log.v("JSON ERROR: ", e.toString());
}
JsonObjectRequest jsonObjectRequest = new JsonObjectRequest( url, total, new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
Log.v("--------------","---------------------------");
Log.v("RESPONSE: ", "-----> " + response.toString());
Log.v("<----- BTW------>", total.toString());
Log.v("--------------","---------------------------");
}
}, new Response.ErrorListener(){
#Override
public void onErrorResponse(VolleyError error) {
Log.v("--------------","---------------------------");
Log.v("RESPONSE: " , "xXxX FAIL X_____X FAIL XxXx");
Log.v("|>>>ERROR: ", error.toString());
//Log.v("|>>>ERROR: ", error.getLocalizedMessage());
Log.v("<----- BTW------>", total.toString());
Log.v("--------------","---------------------------");
} // end of onErrorREsponse
}){
#Override
public Map<String, String> getHeaders() throws AuthFailureError {
HashMap<String, String> headers = new HashMap<String, String>();
headers.put("Content-Type", "application/json; charset=utf-8");
return headers;
}
};
Volley.newRequestQueue(this).add(jsonObjectRequest);
} // end of volley connector method
My complete error log(upon the failed request) reads:
V/RESPONSE:: xXxX FAIL X_____X FAIL XxXx
V/|>>>ERROR:: com.android.volley.ParseError: org.json.JSONException: End of i
V/<----- BTW------>: {"data":"{\"process\":\"ExampleProcess\",\"phone\":\"123456789\"}"}
I am not too sure as to what is going on and I am not getting anywhere by reading the docs and debugging with Android studio. As far as I am concerned, one of the parameters is a JSONObject and I am passing in one albeit it might be wrongly formatted.
Any help/pointers will be greatly appreciated.
You are doing correct but try code once by making one small change in your code that is-
JSONObject data= new JSONObject();
data.accumulate("username", "mobileGps");
data.accumulate("password", "9565551236");
JSONObject total= new JSONObject();
total.put("data",data);
json = jsonObjectNew.toString();
And pass this "json" to method and check once. Looking same but try once.

Categories