I'm trying to send POST request from the android studio and I get some errors like:
E/ERROR:: method does not support a request body: GET
java.net.ProtocolException: method does not support a request body: GET
And I don't know how to resolve it. Can anyone help me?
This is my main class where I'm sending port request
public class Main2Activity extends AppCompatActivity {
public TextView content;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main2);
content = (TextView) findViewById(R.id.content);
new CheckConnectionStatus().execute("https://nonoperational-trad.000webhostapp.com/getuser.php");
}
class CheckConnectionStatus extends AsyncTask<String, Void, String> {
#Override
protected void onPreExecute() {
super.onPreExecute();
content.setText("");
}
protected String doInBackground(String...params) {
URL url = null;
try {
url = new URL(params[0]);
} catch (MalformedURLException e) {
e.printStackTrace();
}
try {
HttpURLConnection urlConnection =(HttpURLConnection) url.openConnection();
urlConnection.setDoInput(true);
Uri.Builder builder = (Uri.Builder) new Uri.Builder()
.appendQueryParameter("username", "d")
.appendQueryParameter("password","d");
OutputStream outputStream= urlConnection.getOutputStream();
BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(outputStream, "UTF-8"));
bufferedWriter.write(builder.build().getEncodedQuery());
bufferedWriter.flush();
bufferedWriter.close();
outputStream.close();
urlConnection.connect();
InputStream inputStream = urlConnection.getInputStream();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
String s = bufferedReader.readLine();
bufferedReader.close();
return s;
} catch (IOException e) {
Log.e("ERROR:", e.getMessage(), e);
e.printStackTrace();
}
return null;
}
protected void onPostExecute(String s){
super.onPostExecute(s);
content.setText(s);
}
}
}
build.gradle that I added - implementation 'com.squareup.okhttp3:okhttp:3.9.1'
This is the error message while sending the request!
E/ERROR:: method does not support a request body: GET
java.net.ProtocolException: method does not support a request body: GET
at com.android.okhttp.internal.huc.HttpURLConnectionImpl.getOutputStream(HttpURLConnectionImpl.java:262)
at com.android.okhttp.internal.huc.DelegatingHttpsURLConnection.getOutputStream(DelegatingHttpsURLConnection.java:218)
at com.android.okhttp.internal.huc.HttpsURLConnectionImpl.getOutputStream(HttpsURLConnectionImpl.java:26)
at com.example.dato.maptest.Main2Activity$CheckConnectionStatus.doInBackground(Main2Activity.java:65)
at com.example.dato.maptest.Main2Activity$CheckConnectionStatus.doInBackground(Main2Activity.java:42)
at android.os.AsyncTask$2.call(AsyncTask.java:333)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:245)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
Looks like the API that you are trying to call is a GET request. Hence you need to make a GET request (not a POST request).
Even though you have mentioned that you are using OkHttp for the API call, I do not see any sign of using it. I see that you have used basic HttpUrlConnection for making the server request.
Usually, I use Volley for making API calls. You can find how to use Volley for making an API call from the link provided. Here's I am trying to write some code, however, you may have to modify the code as per your need.
First, you need to add the following dependency in your build.gradle file.
dependencies {
// ... Your other dependencies go here
implementation 'com.android.volley:volley:1.1.1'
}
Then you just have to write the following code where you want to call this API.
String username = "d";
String password = "d";
RequestQueue queue = Volley.newRequestQueue(this);
String url ="https://nonoperational-trad.000webhostapp.com/getuser.php?username=" + username + "&password=" + password;
// Request a String response from the provided URL.
StringRequest stringRequest = new StringRequest(Request.Method.GET, url,
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
Toast.makeText(Main2Activity.this, response, Toast.LENGTH_LONG).show();
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Toast.makeText(Main2Activity.this, "Fail", Toast.LENGTH_LONG).show();
}
});
// Add the request to the RequestQueue.
queue.add(stringRequest);
I tried calling the API using Postman and got the following response.
Hope that helps!
Related
I am trying to send a raw body request Array, any idea how to implement the Body array string, in java android studio?
Web API .net framework c# working:
[Route("api/login_test")]
[HttpPost]
public object login_test([FromBody] string[] Username_Password])
{
string UsernameOrEmail_address, Password;
UsernameOrEmail_address = Username_Password[0];
Password = Username_Password[1];
return UsernameOrEmail_address + " " + Password;
}
Below what i am trying to achieve, this also as a reference,web api c# test on postman and working Java Async Task from android studio:
/**
* Async task class to get json by making HTTP call
*/
private class login_test extends AsyncTask<Void, Void, Void> {
HttpURLConnection conn = null ;
BufferedReader reader = null;
#Override
protected Void doInBackground(Void... voids) {
try {
URL url_login;
url_login = new URL(url_api + "login_test");
conn = (HttpURLConnection) url_login.openConnection();
conn.setRequestMethod("POST");
JSONArray jsonArray = new JSONArray();
jsonArray.put(0, username);
jsonArray.put(1, password);
OutputStreamWriter osw = new OutputStreamWriter(conn.getOutputStream());
osw.write(String.valueOf(jsonArray));
Log.i("Body to API", String.valueOf(jsonArray));
osw.flush();
osw.close();
}
}
}
I tried above, but it is not success because somehow it is not being written right, and i am getting exception as it fails
I found my issue, I had to a Content-Type as application/json
conn.setRequestProperty("Content-Type","application/json");
I want to make a GET request using Volley in Android Studio and in this request I want to include a body.
The problem is that when using the GET request, the body in the server is None (I am using Flask). On the other side, when using the POST method, the body reaches the server correctly. This is my code:
RequestQueue queue = Volley.newRequestQueue(getApplicationContext());
String url = Globals.WINGS_VEHICLES_URL;
JSONObject payload = new JSONObject();
try {
payload.put("user_id", Globals.USER_ID);
} catch (JSONException e) {
e.printStackTrace();
}
final String requestBody = payload.toString();
System.out.println(requestBody);
StringRequest stringRequest = new StringRequest(Request.Method.POST, url, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
System.out.println(response);
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
error.printStackTrace();
}
}){
#Override
public String getBodyContentType() {
return "application/json";
}
#Override
public byte[] getBody() {
return requestBody.getBytes();
}
};
stringRequest.setRetryPolicy(new DefaultRetryPolicy(0, 0, DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
queue.add(stringRequest);
Is this a Volley restriction, or am I doing something wrong? Assume that I am using a JSONObject as body, non empty.
please check this answer
HTTP GET with request body
and Use POST Http method to send Body!!
I'm trying to make a POST request to an api that I have created in Visual Studio. The api works, and I finally managed to find some code that allows me to connect to it (and it's not deprecated). The problem is that this code was made for a GET request while I need to make a POST. I created two boxes where I insert the data I want to pass (utente, password) and I created a button that takes the data from the boxex and convert them to string.
I tried already searching a lot of examples and tutorials that show how to make a POST request but the majority are very old and doesn't work anymore in Android Studio, or at least I can't make them work.
Now, this is the function that should be sending the data, I haven't touched the code since I don't really know what to modify except for the Request Method.
private StringRequest searchNameStringRequest(String utente, String password)
{
String url = "http://192.168.1.11:57279/api/utente";
return new StringRequest(Request.Method.POST, url,
new Response.Listener<String>()
{
#Override
public void onResponse(String response)
{
try
{
JSONObject result = new JSONObject(response).getJSONObject("list");
int maxItems = result.getInt("end");
JSONArray resultList = result.getJSONArray("item");
}
catch (JSONException e)
{
Toast.makeText(MainActivity.this, e.getMessage(), Toast.LENGTH_LONG).show();
}
}
},
new Response.ErrorListener()
{
#Override
public void onErrorResponse(VolleyError error)
{
Toast.makeText(MainActivity.this, "Food source is not responding (USDA API)", Toast.LENGTH_LONG).show();
}
});
}
Can someone explain me how to take the data and send it like a JSON Object that has
keys = user, password
values = utente, password (the values are from the two boxes mentioned before)
Thank to anyone who is willing to help me and I hope that asking for so much help isn't against the site rules.
I'm using Volley since is not so complicated and because it seems to work.
Using the GET method it show me the existing json with message cannot be converted to JSON object (I don't care about that, it's just a confirmation that it connects to the api)
Using the POST method it throws the ErrorResponse at the end (Food source is not responding)
EDIT: Added OnCreate method since I need a StringRequest return
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
queue = Volley.newRequestQueue(this);
Button invia = findViewById(R.id.submit);
final EditText utenteInserito = findViewById(R.id.utente);
final EditText passwordInserito = findViewById(R.id.password);
invia.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String utente = utenteInserito.getText().toString();
String password = passwordInserito.getText().toString();
queue.cancelAll(R.id.submit);
StringRequest stringRequest = searchNameStringRequest(utente, password);
stringRequest.setTag(R.id.submit);
queue.add(stringRequest);
}
});
}
EDIT: I have followed the suggested answer given but it doesn't seem to work
The resulting code is shown below but I get the OnErrorResponse, I don't think it's a problem with the api because trying with a GET response it gives me the exiting json array, so I think it's a problem with the code.
private StringRequest searchNameStringRequest(final String utente, final String password)
{
String url = "http://192.168.1.11:57279/api/utente";
StringRequest request = new StringRequest(Request.Method.POST, url, new Response.Listener<String>()
{
#Override
public void onResponse(String response)
{
System.out.println(response);
}
}, new Response.ErrorListener()
{
#Override
public void onErrorResponse(VolleyError error)
{
Toast.makeText(MainActivity.this,"Service Unavailable",Toast.LENGTH_SHORT).show();
error.printStackTrace();
}
})
{
#Override
protected Map<String, String> getParams()
{
Map<String,String> map = new HashMap<>();
map.put("user", utente.trim());
map.put("password",password.trim());
return map;
}
};
RequestQueue requestQueue = Volley.newRequestQueue(getApplicationContext());
requestQueue.add(request);
return request;
}
It's working following this question:
How to send a POST request using volley with string body?
Thanks to you all for your interest.
String url = "your url";
StringRequest request = new StringRequest(Request.Method.POST, url, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
System.out.println(response);
dialog.dismiss();
try {
// your logic when API sends your some data
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
dialog.dismiss();
Toast.makeText(context,"Service Unavailable",Toast.LENGTH_SHORT).show();
error.printStackTrace();
}
}){
//This is how you will send the data to API
#Override
protected Map<String, String> getParams(){
Map<String,String> map = new HashMap<>();
map.put("name",username.getText().toString());
map.put("password",password.getText().toString());
return map;
}
};
RequestQueue requestQueue = Volley.newRequestQueue(getApplicationContext());
requestQueue.add(request);
}
Here is a nice tutorial, I have tried it and it worked seamlessly.
Android Login and Registration with PHP, MySQL and SQLite
You can skip the sqlite and the phpMyAdmin part.
I need to make a call to the webservice in android java and another class calls it. I the end, showing the ws response in UI.
I've done the webservice. Only that part of the "asynchronous" is not working properly.
This is my webservice, receiving three strings:
public class WebServiceRestFull extends AsyncTask<String, String, String>
{
protected ProgressDialog dialog;
public String wsURL;
public String wsFunction;
public String wsInput;
public int codeHTTP;
public String messageHTTP;
public String strResponse;
public WebServiceRestFull(Context act)
{
dialog = new ProgressDialog(act);
}
#Override
protected void onPreExecute() {
dialog.setMessage("Wait please...");
dialog.show();
}
#Override
protected void onPostExecute(String result)
{
if (dialog.isShowing())
{
dialog.dismiss();
}
}
#Override
protected String doInBackground(String... params)
{
String url = wsURL + wsFunction;
String inputCoded = EncodeString(wsInput);
HttpURLConnection request;
URL urlToRequest = new URL(url);
request = (HttpURLConnection) urlToRequest.openConnection();
request.setDoOutput(true);
request.setDoInput(true);
request.setRequestProperty("Content-Type", "application/json");
request.setRequestMethod("POST");
OutputStreamWriter outputStreamWriter = new OutputStreamWriter(request.getOutputStream());
outputStreamWriter.write("\""+inputCoded+"\"");
outputStreamWriter.flush();
outputStreamWriter.close();
codeHTTP = request.getResponseCode();
messageHTTP = request.getResponseMessage();
InputStream is = request.getInputStream();
String resp = convertStreamToString(is);
strResponse = DecodeString(resp);
request.disconnect();
return strResponse;
}
catch (Exception ex)
{
ex.printStackTrace();
return "ERROR";
}
}
}
On the other side, in the "Android Activity" I call this asynchronous class as follows:
WebServiceRestFull web = new WebServiceRestFull(this);
web.wsURL = "http://someurl.com/rest/etc";
web.wsFunction = "login";
web.wsInput = "mike";
web.execute();
Thread.sleep(1000);
The problem is that this is not actually do an asynchronous call and the results usually are not received by the webservice .
Is there any simple way to do this or am I doing wrong in some side as the call to webservice or own webservice class ?
Sorry for my english.
Thanks!
Nothing is wrong with the way you created and excecuted this asynctask
Just please don't use Thread.sleep();
And the issue is clearly in the doInBackground() method which code we don't have here
Is your code complete? There is nothing on your class that make an http request, the rest seems to be fine.
Try to use Okhttp it's really simple. Check it here
That thread sleep will run in main thread which is not such good idea.Use post execute to run you callback and publish any results.
Am Using retrofit for my connection with server,My app has signin page and signout page During Login i get the value from text box and send using POST request to the server It works fine,
public void LoginUser(View v)
{RestAdapter adapter = new RestAdapter.Builder()
.setEndpoint(ROOT_URL)
.build();
WashAPI api = adapter.create(WashAPI.class);
api.LoginUser(
Email.getText().toString(),
Password.getText().toString(),
//Creating an anonymous callback
new Callback<Response>() {
#Override
public void success(Response result, Response response) {
//On success we will read the server's output using bufferedreader
//Creating a bufferedreader object
BufferedReader reader = null;
//An string to store output from the server
String output = "";
try {
//Initializing buffered reader
reader = new BufferedReader(new InputStreamReader(result.getBody().in()));
//Reading the output in the string
output = reader.readLine();
} catch (IOException e) {
e.printStackTrace();
}
Interface for signin
public interface WashAPI {
#FormUrlEncoded
#POST("/xxx/yyy/signin")
public void LoginUser(
#Field("email") String email,
#Field("password") String password,
Callback<Response> callback);
}
This works good
After login with my server API it returns me a token, At the time of signout i need to send the token so my session get experied.
code for signout
public void signout(View v)
{
Log.d("insidetoken",t);
RestAdapter adapter = new RestAdapter.Builder()
.setEndpoint(ROOT_URL)
.build();
SignoutAPI api = adapter.create(SignoutAPI.class);
api.signout(t,
new Callback<Response>() {
#Override
public void success(Response result, Response response) {
BufferedReader reader = null;
String output = "";
try {
reader = new BufferedReader(new InputStreamReader(result.getBody().in()));
output = reader.readLine();
} catch (IOException e) {
e.printStackTrace();
}
Interface for signout
public interface SignoutAPI {
#FormUrlEncoded
#POST("/xxx/yyy/zzz/signout")
public void signout(
#Field("token") String token,
Callback<Response> callback);
}
My code is same for both signin and sigout
but for signin it works and for signout it gives me RETROFIT ERROR : 500 INTERNAL SERVER ERROR
But Using POSTMAN It works fine
500 INTERNAL SERVER ERROR means that there is problem in the server side you should have to check it using postman.
I am damn sure that there will be problem in the web service response not of your code at android side.
As mentioned in the comments too, it appears you are doing something in the login service that is not being done in the sign out service.
To fix this, make sure in you sign out service, you are checking for a POST parameter named token.
Maybe you are giving token in wrong way
In my way It was "Bearer TOKEN" -> for Authorization in Header
In my case I changed my parameters to that
fun setProfileAvatar(token: String,#Part image: MultipartBody.Part) : Single<Message> {
return apiService.setProfileAvatar("Bearer ${token}",image)
}
You can enable logging in retrofit to show you server-side errors and messages.
use this link to understand how to enable it.
https://stackoverflow.com/a/33256827/9474700