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
Related
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!
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
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.
I am using:
Andorid Studio.
Okhttp 2.4.0 with AsyncTask. But I can't cancel a request.
Connected to server on wi-fi. And if server is off then okHttp keeps trying to connect, and I can't cancel it.
time outs is working but i want to cancel before timeouts
private OkHttpClient client = new OkHttpClient();
client.setConnectTimeout(30000, TimeUnit.MILLISECONDS);
after execute I press special cancel button in my api
public void onCancelClick(View v){
BaseApplication.getInstance().server.cancel();
synchProducts.cancel(true);
}
first line must stoped okHttp, second line stoped class extended AsyncTask
private static final String myTag = "AsyncCall";
public void cancel(){
client.cancel(myTag);
}
backGround in AsyncTask class
#Override
protected String doInBackground(Void... params) {
publishProgress(1);
String responseStr = sendProductHeaders();
//this performed after timeouts, and spit to my cancel okHttp
publishProgress(2);
if (responseStr != null && !isCancelled()){
ProductsList productsForSend = parseProducts(responseStr);
//correctly stoped thread
I didn't forget to use .tag in the builder request
public Response post(String url, String json) {
RequestBody body = RequestBody.create(JSON, json);
Request request = new Request.Builder()
.tag(myTag)
.url(url)
.post(body)
.build();
return call(request);
}
"call" is my method which makes the okHttp call
private Response call(Request request){
try {
return client.newCall(request).execute();
} catch (IOException e) {
Log.e("Aync call", "IO exception " + e.getMessage());
}
return null;
}
"Tags" is true, code in okHttp Library realy fires call.cancel();
for (Call call : executedCalls) {
if (Util.equal(tag, call.tag())) {
call.cancel();
}
}
method which is running Async
public void onRefreshProducts(View v){
progressLayout.setVisibility(View.VISIBLE);
progressBar.setProgress(0);
synchProducts = new SynchProducts(activityCallBack);
synchProducts.execute();
}
"activityCallBack" is the interface I use when I call to my activity from AsyncTask class
i don't want to use okHttp enqueue, but I can't insert a friendly progress bar in my app.
Thanks!
Try updating the library to okhttp 2.5.0 and use the cancel() method. The ChangeLog for 2.5.0 mentions the following:
Call canceling is more reliable. We had a bug where a socket being connected wasn't being closed when the application used Call.cancel().
Hopefully it will fix the issue.
so here is my issue: I am working on a mobile App, that requires a login. I am programming in Android Studio / Java. Got a quite good experience in Java but i've never done networking.. There is a .asp script on a server that processes the login, which i need to send the login data to. The best way to solve this i think is a HTTP - Request, because if you enter the url of the script into the browser, followed by the query string containing the login data, you already get a response.
http://sampleurl.info/actions/checklogin.asp?userName=klingenhaeger&password=droid&device=android
returns a Json String containing a profile token and a timestamp and the profile name.Like:
{"profil_token":"qn2hJcRQixYjG7yyW956g1407921902","profil_name":"Marc Klingenhäger","timestamp":"1407921902"}
This profile token is then attached to every url the user requests, and in that way the user gains permission to all the websites.
I read that you can do the same thing with a http GET request, but me and my coworker worked on this
(such a simple thing) for nine ours and didn't get our code working...
We tried out heaps of snippets, this is our most simple attempt:
In the Main activity, on clicking the button that leads to the login, LoginActivity.class is called using a Intent.
Intent intent = new Intent(this, LoginActivity.class);
startActivity(intent);
After entering the user data, the user clicks the login button, and the method attemptLogin(); gets called.
public void attemptLogin() {
if (mAuthTask != null) {
return;
}
// Reset errors.
mEmailView.setError(null);
mPasswordView.setError(null);
// Store values at the time of the login attempt.
String email = mEmailView.getText().toString();
String password = mPasswordView.getText().toString();
boolean cancel = false;
View focusView = null;
// Check for a valid password, if the user entered one.
if (!TextUtils.isEmpty(password) && !isPasswordValid(password)) {
mPasswordView.setError(getString(R.string.error_invalid_password));
focusView = mPasswordView;
cancel = true;
}
// Check for a valid email address.
if (TextUtils.isEmpty(email)) {
mEmailView.setError(getString(R.string.error_field_required));
focusView = mEmailView;
cancel = true;
} else if (!isEmailValid(email)) {
mEmailView.setError(getString(R.string.error_invalid_email));
focusView = mEmailView;
cancel = true;
}
if (cancel) {
// There was an error; don't attempt login and focus the first
// form field with an error.
focusView.requestFocus();
} else {
// Show a progress spinner, and kick off a background task to
// perform the user login attempt.
showProgress(true);
mAuthTask = new UserLoginTask(email, password);
mAuthTask.execute((Void) null);
}
}
So after some error detection, the class userLoginTask (subclass of AsyncTask) is initialized to handle the networking stuff, because initializing the http request in the main thread seems to cause an exception. We didn't manage to code a HTTP - Request here so far.. (thats the main problem)
public class UserLoginTask extends AsyncTask {
private final String mEmail;
private final String mPassword;
UserLoginTask(String email, String password) {
mEmail = email;
mPassword = password;
}
#Override
protected Boolean doInBackground(Void... params) {
// TODO: attempt authentication against a network service.
try {
// Simulate network access.
Thread.sleep(2000);
} catch (InterruptedException e) {
return false;
}
for (String credential : DUMMY_CREDENTIALS) {
String[] pieces = credential.split(":");
if (pieces[0].equals(mEmail)) {
// Account exists, return true if the password matches.
return pieces[1].equals(mPassword);
}
}
// TODO: register the new account here.
return true;
}
#Override
protected void onPostExecute(final Boolean success) {
mAuthTask = null;
showProgress(false);
if (success) {
finish();
} else {
mPasswordView.setError(getString(R.string.error_incorrect_password));
mPasswordView.requestFocus();
}
}
#Override
protected void onCancelled() {
mAuthTask = null;
showProgress(false);
}
}
So my question is basically, how can i initialize a HTTP - Request in the UserLoginTask class. Any Ideas? Thanks in advance! :)
Falco
The easiest way is to use a URL object and open a stream to your HTTP server.
The server response can be read through this stream:
String url = "http://sampleurl.info/actions/checklogin.asp?userName=klingenhaeger&password=droid&device=android";
try {
URL u = new URL(url);
InputStream is = u.openStream(); // Opens streaming connection to url
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
StringBuffer result = new StringBuffer(); // Buffer to store saved data
String input = null;
while((input = reader.readLine()) != null) {
// Read data until the end of the stream
result.append(input);
}
// Do something with result here
} catch (IOException e) {
e.printStackTrace();
}
When you have retrieved the data as a string, you can parse the JSON to get the profile_token
Use Android's Volley http://developer.android.com/training/volley/index.html and issue an HTTP POST request, sending username / password.
I advise hashing the password (MD5 or something else - depends on what the back-end handles to decrypt).
Google suggests using HttpUrlConnection.
An example that should do what you want is very simple, especially when using GET. First, construct an URL from String. Your response is InputStream, which you parse to JSONObject and obtain your token.
URL url = new URL("http://sampleurl.info/actions/checklogin.asp?userName=klingenhaeger&password=droid&device=android");
//later:
URL url = new URL("http://sampleurl.info/actions/checklogin.asp?token=abcde");
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
try {
InputStream in = new BufferedInputStream(urlConnection.getInputStream());
readStream(in);
finally {
urlConnection.disconnect();
}
}
This is recommended approach, since it does not require any external libraries, and it can easily be converted to use POST instead of GET and HTTPS instead of HTTP.