Could someone give me an advice , how can I get just one headers . Because I'm getting all of header , I can't choose just one. This is my code:
LoginService loginService =
RetrofitClient.createService(LoginService.class, userEmail, userPassword);
loginService.basicLogin(new Callback<User>()
{
#Override
public void success (User user, Response response){
List<retrofit.client.Header> tokens = response.getHeaders();
Log.e(LOG_TAG, "x-auth-token is" + xAuthToken));
Toast.makeText(getApplicationContext(), "Your are in", Toast.LENGTH_SHORT).show();
Intent intent = new Intent(getApplicationContext(), BetweenActivity.class);
startActivity(intent);
}
If you want to use the first token, you can use:
retrofit.client.Header firstToken;
if (tokens.size() > 0) {
firstToken = tokens.get(0);
}
If you want to iterate through the tokens to find a specific one, you can use:
retrofit.client.Header token = null;
for (retrofit.client.Header tmpToken : tokens) {
if (tmpToken.foo()) {
token = tmpToken;
break;
}
}
Related
I am trying to put in a delete account option in my application, however when I try to delete the account I am not getting a respsonse from the web server.
Instead I get the error:
org.json.JSONException: End of input at character 0 of
I have tried to change the request method to DELETE however I am not too familiar with android and databases so I am not sure if that would work.
I am not sure whether the problem lies with the php or the java code, when I run the debugger in android studio the String response returns:
response: ""
php:
<?php
if($_SERVER['REQUEST_METHOD']=='POST'){
$id = $_POST['id'];
require 'conn.php';
$sql = "DELETE * FROM Patients WHERE patientID='$id'";
if(mysqli_query($conn, $sql)){
$result['success'] = "1";
$result['message'] = "success";
echo json_encode($result);
mysqli_close($conn);
} else {
$result["success"] = "0";
$result["message"] = "Error!";
echo json_encode($result);
mysqli_close($conn);
}
}
?>
Java delete method:
private void deleteAccount() {
final String name = this.name.getText().toString().trim();
final String lName = this.lName.getText().toString().trim();
final String dob = this.dob.getText().toString().trim();
final String email = this.email.getText().toString().trim();
final String password = this.password.getText().toString().trim();
final String passwordConf = this.cPassword.getText().toString().trim();
final String id = getID;
StringRequest stringRequest = new StringRequest(Request.Method.POST, URL_DELETE,
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
try {
JSONObject jsonObject = new JSONObject(response);
String success = jsonObject.getString("success");
if(success.equals("1")){
Toast.makeText(EditAccount.this, "Account Deleted", Toast.LENGTH_SHORT).show();
}
} catch (JSONException e) {
Toast.makeText(EditAccount.this, "Error: "+e.toString(), Toast.LENGTH_SHORT).show();
e.printStackTrace();
}
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Toast.makeText(EditAccount.this, "Error: "+error.toString(), Toast.LENGTH_SHORT).show();
}
})
{
#Override
protected Map<String, String> getParams() throws AuthFailureError {
Map<String,String> params = new HashMap<>();
params.put("id", id);
return params;
}
};
RequestQueue requestQueue = Volley.newRequestQueue(this);
requestQueue.add(stringRequest);
}
}
I expect the toast to pop up and say account deleted but instead I get the error message stated at the top.
p.s. this is just a prototype so I am not worried about security at the moment.
Thanks!
Whatever the issue might be, I am going to take a guess and say if($_SERVER['REQUEST_METHOD']=='POST') is the root of your issue.
Your request may be sent wrong to the server and the method is not recognized as POST which would explain a "" response since you do not offer an alternative to what should happen at the condition failing.
Send a bad request response (400) back and you will have the ability to troubleshoot this issue in your Java code... PHP is fine.
if($_SERVER['REQUEST_METHOD']=='POST') { /* ... */ }
else {
http_response_code(400);
// exit('Bad request method.');
// or for a json response:
echo json_encode([
'success' => "0",
'message' => "Bad Request Method used."
]);
}
Also, I have to say... Security should always be a concern... It does not take but a few more lines of code to filter the user request, and make your query a bit more secure via prepared statements. It's more of an issue of habits; one day you might forget a query here or there.
I am making http requests to my REST server. As a response I get the JSON body. But I need to get also a parameter from the response header, as I keep the user token in it. I have looked at a lot of posts on Stack Overflow for similar questions, but I they don't seem to have helped me. I want to make a JSON request, and get the body and headers form the response. How can I do it? Here is my code:
Please don't mark the question as duplicate, as I have not found any example where I can retrieve both: the response header and the response body. For the existing questions, users get only the headers
JsonObjectRequest req = new JsonObjectRequest(AppConfig.URL_LOGIN, new JSONObject(params),
new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
System.out.println(response.toString());
hideDialog();
try {
JSONObject jObj = response;
String uid = jObj.getString("_id");
String name = jObj.getString("fullName");
String email = jObj.getString("email");
// Inserting row in users table
db.addUser(name, email, uid);
Toast.makeText(getApplicationContext(), "User successfully registered. Try login now!", Toast.LENGTH_LONG).show();
Intent intent = new Intent(
LoginActivity.this,
MainActivity.class);
startActivity(intent);
finish();
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
NetworkResponse networkResponse = error.networkResponse;
String toastError = "Response code: " + networkResponse.statusCode;
Toast.makeText(getApplicationContext(),
toastError, Toast.LENGTH_LONG).show();
hideDialog();
}
});
You can't do that using JsonObjectRequest. You should extend the Request class and implement parseNetworkResponse() method which provides access to low-level NetworkResponse object. Downside is of course that you have to re-implement JSON parsing as well, but this is not really a big deal.
Something like:
public class HeaderAwareJsonRequest extends Request<Pair<JSONObject,Map>> {
protected Response.Listener<Pair<JSONObject,Map>> listener;
public HeaderAwareJsonRequest( int method, String url, Response.Listener<Pair<JSONObject,Map>> listener, Response.ErrorListener errorListener ) {
super( method, url, errorListener );
this.listener = listener;
}
#Override
protected Response<Pair<JSONObject,Map>> parseNetworkResponse( NetworkResponse response ) {
try{
String jsonString = new String( response.data, HttpHeaderParser.parseCharset( response.headers ) );
// pair contains the json body and headers
Pair pair = new Pair( new JSONObject( jsonString ), response.headers );
return Response.success( pair, HttpHeaderParser.parseCacheHeaders( response ) );
}catch( Exception e ){
return Response.error( new ParseError( e ) );
}
}
}
then in the calling code:
HeaderAwareJsonRequest req = new HeaderAwareJsonRequest(
Request.Method.GET,
AppConfig.URL_LOGIN,
new Response.Listener<Pair<JSONObject,Map>>() {
#Override
public void onResponse(Pair<JSONObject,Map> response) {
JSONObject jObj = response.first;
Map headers = response.second;
String someHeader = headers.get( "aaaaa" );
...
}
},
new Response.ErrorListener() {...}
);
I am trying to follow a online tutorial to create this login, but I receive this error. I tried this on localhost but it doesn't work on a server. Can anybody tell me what is my mistake please. Here's my code:
private void checkLogin(final String email, final String password) {
// Tag used to cancel the request
String tag_string_req = "req_login";
pDialog.setMessage("Logging in ...");
showDialog();
StringRequest strReq = new StringRequest(Method.POST,
AppConfig.URL_LOGIN, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
Log.d(TAG, "Login Response: " + response.toString());
hideDialog();
try {
JSONObject jObj = new JSONObject(response);
boolean error = jObj.getBoolean("error");
// Check for error node in json
if (!error) {
// user successfully logged in
// Create login session
session.setLogin(true);
// Now store the user in SQLite
String uid = jObj.getString("uid");
JSONObject user = jObj.getJSONObject("user");
String name = user.getString("name");
String email = user.getString("email");
String created_at = user
.getString("created_at");
// Inserting row in users table
db.addUser(name, email, uid, created_at);
// Launch main activity
Intent intent = new Intent(LoginActivity.this,
MainActivity.class);
startActivity(intent);
finish();
} else {
// Error in login. Get the error message
String errorMsg = jObj.getString("error_msg");
Toast.makeText(getApplicationContext(),
errorMsg, Toast.LENGTH_LONG).show();
}
} catch (JSONException e) {
// JSON error
e.printStackTrace();
Toast.makeText(getApplicationContext(), "Json error: " + e.getMessage(), Toast.LENGTH_LONG).show();
}
}
It means either the response is not in JSON format or the client side did not get any response at all. Try to following steps.:-
1.Before using the URL in the application check it in a web browser if you are getting the desired response or not. If there is any server side error it will be displayed in the web browser.
2. Now check the serve side response with a JSON validator to check if the response is a valid JSON or not
3.If your server side is then use logcat or toast message to print your response and check the response.
I just found out the way to solve it. It's the codes in the DB_Functions.php file that caused the problem. I have changed the code a bit then it works now. Thanks so much you guys for the help.I have also attached the code in case someone ran into the same problem. Good luck guys
public function getUserByEmailAndPassword($email, $password) {
$result = mysqli_query($this->conn,"SELECT * FROM users WHERE email = '$email'") or die(mysqli_connect_errno());
// check for result
$no_of_rows = mysqli_num_rows($result);
if ($no_of_rows > 0) {
$result = mysqli_fetch_array($result);
$salt = $result['salt'];
$encrypted_password = $result['encrypted_password'];
$hash = $this->checkhashSSHA($salt, $password);
Ok, I've figured this one out already, but I wanted to put it out there in case anyone else is running into issues. Basically, what I needed to do was have post as a Facebook user's owned page (i.e. I'm John Doe and I'm an admin for page Rum Ham; I want to post to the Rum Ham page).
So, basically the answer looks like this
First, you need to log the user in with this line
LoginManager.getInstance().logInWithPublishPermissions(this, Arrays.asList("publish_actions", "manage_pages", "publish_pages"));
Then, you need to fetch the access token of the page we wish to publish to
Bundle params = new Bundle();
//ok so access token here is "app_ID|app_secret"
params.putString("access_token", accessToken);
params.putString("fields", "id");
GraphRequest request = new GraphRequest(null, "me", params, HttpMethod.GET, new GraphRequest.Callback() {
public void onCompleted(GraphResponse response) {
FacebookRequestError error = response.getError();
if (error != null) {
Log.e("Error", error.getErrorMessage());
} else {
JSONObject values = response.getJSONObject();
try {
//so I have to get the user ID first
String id = values.getString("id");
Bundle p = new Bundle();
p.putString("access_token", accessToken);
//yay nest the graph requests
//once we get the id we can get their pages
GraphRequest pagesRequest = new GraphRequest(null, "/" + id + "/accounts", p, HttpMethod.GET, new GraphRequest.Callback() {
public void onCompleted(GraphResponse response) {
FacebookRequestError error = response.getError();
if (error != null) {
Log.e("Error", error.getErrorMessage());
} else {
//ok so here, we're getting the pages back in a few JSON wrappers
JSONObject values = response.getJSONObject();
JSONArray array = null;
try {
array = values.getJSONArray("data");
//ok, so here we're just iterating through the pages a user has, obviously you can handle this accordingly..
for (int i = 0; i < array.length(); i++) {
//ok, here's how to actually get the token
String access_token = array.getJSONObject(i).getString("access_token")
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}
});
GraphRequest.executeAndWait(pagesRequest);
} catch (Exception e) {
e.printStackTrace();
}
}
}
});
GraphRequest.executeAndWait(request);
}
Ok, so once we've got the access token page, here's where the real f***kery comes into play that Facebook refuses to tell you about in their reference pages.
So, forget anything you've read about needing to submit your app for review with them. All I had to do was create a new access token like so
//create a new access token, facebook refers to this as a page access token
AccessToken token = new AccessToken("page_access_token", AccessToken.getCurrentAccessToken().getUserId(), Arrays.asList("publish_actions", "manage_pages", "publish_pages"), null, AccessTokenSource.FACEBOOK_APPLICATION_SERVICE,
AccessToken.getCurrentAccessToken().getExpires(), AccessToken.getCurrentAccessToken().getLastRefresh());
//then we simply update our current access token
AccessToken.setCurrentAccessToken(token);
Now, we're still not done yet. Finally, we need to actually make the API call to create the post:
Bundle params = new Bundle();
params.putString("message", "Contents of message");
//here, token is our newly created AccessToken object
GraphRequest request = new GraphRequest(token, "/pageid/feed", params, HttpMethod.POST, new GraphRequest.Callback() {
public void onCompleted(GraphResponse response) {
FacebookRequestError error = response.getError();
if (error != null) {
Log.e("Error", error.getErrorMessage());
} else {
//do your own processing here for success
}
}
});
GraphRequest.executeAndWait(request);
}
}
And that's pretty much it. Hopefully this helps someone!
I'm writing an android application which uses rest services for user regitration and more but running into trouble with my login service. for some reason the requestparams i put into my service call on android side are not being found within my rest service.
could anny 1 tell me what i'm doing wrong or link to a guide which explains how to solve this problem?
Relevant android functions:
public void loginUser(View view) {
// Get username and password values
String username = usernameEdit.getText().toString();
String password = passwordEdit.getText().toString();
// Instantiate Http Request Param Object
RequestParams params = new RequestParams();
// Check if username & password is not null
if(Utility.isNotNull(username) && Utility.isNotNull(password)) {
// Http parameters
params.put("username", username);
params.put("password", password);
invokeWS(params);
} else {
Toast.makeText(getApplicationContext(), "Vul een gebruikersnaam en of " +
"wachtwoord in", Toast.LENGTH_LONG).show();
}
}
// Method that performs RESTful webservice invocations
public void invokeWS(RequestParams params) {
// Make RESTful webservice call using AsyncHttpClient object
AsyncHttpClient client = new AsyncHttpClient();
client.post("http://10.0.2.2:8080/NTR_application/rest/session", params, new AsyncHttpResponseHandler() {
// When the response returned by REST has Http response code '200'
#Override
public void onSuccess(String response) {
Toast.makeText(getApplicationContext(), "You are successfully logged in!" + response, Toast.LENGTH_LONG).show();
// Gets an JSON object with user Data
// Write user Data to SQLite
User user = new Gson().fromJson(response, User.class);
db.addUser(user);
// Navigate to Home screen
navigatetoHomeActivity();
}
// When the response returned by REST has Http response code other than '200'
#Override
public void onFailure(int statusCode, Throwable error,
String content) {
Toast.makeText(getApplicationContext(), "ERROR!" + content + error + statusCode, Toast.LENGTH_LONG).show();
}
});
}
and the rest services which is called :
#Path("/session")
public class UserService {
private Controller controller = new Controller();
#POST //Post so you can't see the information in the browser history easily
#Produces(MediaType.APPLICATION_JSON)
public Response authenticate(#QueryParam("username") String username, #QueryParam("password") String password){
User user = null;
try {
user = controller.authenticate(username, password);
} catch (NoSuchAlgorithmException | SQLException e) {
System.out.println("Authentication caught an exception; failed for: " + username);
e.printStackTrace();
}
if (user != null){
String json = new Gson().toJson(user);
return Response.status(200).entity(json).build();
} else {
return Response.status(401).entity("Username and/or password is incorrect").build();
}
}
}
Mistake was obvious once i saw it, since i use a #POST i need to use #FormParam instead of #QueryParam.
tutorial i used to write these methods used #GET to login which is insecure.