Android Loopj's Async JsonObject reponse is cast to Objectid failed - java

I'm relatively new in Android & Restful API programming, so I might be making some stupid mistakes. However I am facing this from my response JsonObject:
Cast to ObjectId failed for value \"login\" at path \"_id\" for model \"User\"","name":"CastError","stringValue":"\"login\"","kind":"ObjectId","value":"login","path":"_id"}
I have tested my Rest API on Postman and everything returns just fine. The Restful API is written in Node.js and Express.
The Rest API is suppose to return a status, userid, and message to let the app know if the user logged in using the right username and password. The login works fine and it returns me a 200 which allows the app to login and keep it logged in using a session. However, I can't get anything from the response JsonObject to get the userid for my next step in displaying user information.
(Target Android API 23)
Code:
Restful.Java
public class RestClient {
private static final String BASE_URL = "http://10.0.2.2:8000/api/";
private static AsyncHttpClient client = new AsyncHttpClient();
public static void get(String url, RequestParams params, AsyncHttpResponseHandler responseHandler){
client.get(getAbsoluteUrl(url), params, responseHandler);
}
public static void post(String url, RequestParams params, AsyncHttpResponseHandler responseHandler){
client.post(getAbsoluteUrl(url), params, responseHandler);
}
private static String getAbsoluteUrl(String relativeUrl){
Log.d("URL: ", BASE_URL+relativeUrl);
return BASE_URL + relativeUrl;
}
}
LoginActivity.Java (Only the login part)
public void checkLoginDB(final RequestParams params, final String username){
prgDialog.show();
RestClient.post("user/login", params, new JsonHttpResponseHandler(){
#Override
public void onSuccess(int statusCode, Header[] headers, JSONArray response) {
Log.d("StatusCode: ", "Code "+ statusCode);
try {
if (statusCode == 200) {
Toast.makeText(getApplicationContext(), "Logged In!", Toast.LENGTH_LONG).show();
session.createLoginSession(username);
Log.d("Log: ", "what " + response);
navigatetoHomeActivity();
}
} catch (Exception e){
e.printStackTrace();
}
}
#Override
public void onFailure(int statusCode, Header[] headers, String responseString, Throwable throwable) {
Log.d("StatusCode: ", "Code "+ statusCode);
prgDialog.hide();
Toast.makeText(getApplicationContext(), "Failed!", Toast.LENGTH_LONG).show();
}
});
}
Restful API's Server.js
router.post('/user/login', function(req, res){
var username = req.body.username;
var password = req.body.password;
if(username.length > 0 && password.length > 3){
User.findOne({username: username, password: password}, function(err, user){
if(err)
res.json({statusCode: 0, message: "login error: " + err});
if(!user)
res.json({statusCode: 0, message: "Not Found"});
res.json({statusCode: 200, userid: user._id, message: "Login Sucessful"});
})
} else {
res.json({statusCode: 0, message: "Invalid Fields"});
}
});
app.use('/api', router)
User.js (Defined schema)
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var UserSchema = new Schema({
username: String,
password: String,
firstname: String,
lastname: String,
agentID: Number,
email: String,
phone: Number
});
module.exports = mongoose.model('User', UserSchema);

Whenever you want to Login the user and want user details in return use post() method.
in your code the second method is not post, so change client.get() to client.post()
like this public static void post(String url, RequestParams params, AsyncHttpResponseHandler responseHandler){
client.post(getAbsoluteUrl(url), params, responseHandler);
}

Related

CustomError throw from server not return in HttpErrorResponse in clientside

Hi I am pretty new to Spring and Angular.I am building a spring java server and an angular client. Basically , i want the Client to be able to catch the exception throw out from the server. I defined a CustomExeption.java class and have an CustomRestExcepotionHandler.java on serverside. Right now I am not sure where should i throw out the exception in the server for the client to catch.
I was following the tutorial : https://www.baeldung.com/global-error-handler-in-a-spring-rest-api
Now it returns me with 500 Internal Server Error error message to the client side in HttpErrorResponse.
I want it to return my customexception message. Could someone help me to see if server side code has any problem. why did the HttpErrorResponse not catching the CustomException throw out? Thanks!
public class ApiError {
private HttpStatus status;
private String message;
private List<String> errors;
public ApiError(HttpStatus status, String message, List<String> errors) {
super();
this.status = status;
this.message = message;
this.errors = errors;
}
public ApiError(HttpStatus status, String message, String error) {
super();
this.status = status;
this.message = message;
errors = Arrays.asList(error);
}
public HttpStatus getStatus() {
// TODO Auto-generated method stub
return status;
}
public String getMessage() {
// TODO Auto-generated method stub
return message;
}
}
---
--------------------ExceptionHandler
#ControllerAdvice
public class CustomRestExceptionHandler extends ResponseEntityExceptionHandler {
#Override
protected ResponseEntity<Object> handleExceptionInternal(Exception ex, Object body, HttpHeaders headers,
HttpStatus status, WebRequest request) {
ApiError apiError =
new ApiError(status, ex.getMessage(), ex.getMessage());
return handleExceptionInternal(
ex, apiError, headers, apiError.getStatus(), request);
}
protected ResponseEntity<Object> handleResponseStatusException(ResponseStatusException ex,Object body, HttpHeaders headers,
HttpStatus status, WebRequest request ){
ApiError apiError =
new ApiError(status, ex.getMessage(), ex.getMessage());
return handleExceptionInternal(
ex, apiError, headers, apiError.getStatus(), request);
}
}
public ResponseEntity<AtlasJWT> signInUser(String userName, String password) {String userId = "(uid=" + userName + ")";
if (ldapTemplate.authenticate("", userId, password)) {
log.info("ldapTemplate.authenticate returned true");
Optional<AtlasUser> optLoggedInUser = userRepository.findByUsername(userName);
AtlasJWT atlasJwtToken = jwtTokenProvider.createAtlasJwtToken(optLoggedInUser.get());
if (optLoggedInUser.isPresent()) {
log.info("Atlas JWT: {}", atlasJwtToken);
return new ResponseEntity<AtlasJWT>(atlasJwtToken, HttpStatus.OK);
} else {
//ApiError error = new ApiError(HttpStatus.BAD_REQUEST,"No such User found in the Atlas Database","No such User found in the Atlas Database");
throw new CustomException("No such User found in the Atlas Database",HttpStatus.FORBIDDEN);
}
} else {
//ApiError error = new ApiError(HttpStatus.FORBIDDEN,"Invalid username/password supplied","Invalid username/password supplied");
throw new CustomException("Invalid username/password supplied", HttpStatus.FORBIDDEN);
}
}
my Client side login Component is like below:
login(username: string, password: string) {
console.log('Inside AuthenticationService. Username: ', username);
// const body = `username=${encodeURIComponent(username)}&password=${encodeURIComponent(password)}&grant_type=password`;
const body = {
'username': username,
'password': password
};
const httpOptions = {
headers: new HttpHeaders({
'Content-Type': 'application/json',
})
};
console.log('Invoking server authentication for username', username);
return this.http.post<AtlasJWT>('/auth/api/signin', body, httpOptions).pipe(catchError(this.handleError));
}
private handleError(err: HttpErrorResponse) {
// in a real world app, we may send the server to some remote logging infrastructure
// instead of just logging it to the console
let errorMessage = '';
if (err.error instanceof ErrorEvent) {
// A client-side or network error occurred. Handle it accordingly.
errorMessage = err.message;
// console.log(err);
} else {
// The backend returned an unsuccessful response code.
// The response body may contain clues as to what went wrong,
errorMessage = `Server returned code: ${err.status}, error message is: ${err.message}`;
console.log(err);
}
console.error(errorMessage);
return throwError(errorMessage);
}
I feel like this helped. Added the annotation of #ResponseBody And #ResponseStatus.
And i also try this code , added in my controller class.both working
#ExceptionHandler(CustomException.class)
public HttpEntity<String> exceptionHandler(CustomException custEx ) {
return new HttpEntity<String>(custEx.getMessage()) ;
}

Android how to get user Facebook information when user is already logged in

How can I get users facebook information when he is already logged in? I think I am doing everything fine but its not working..
1st. I am getting the accessToken and checking if it exists. If it does exist I try to get user data.
AccessToken accessToken = AccessToken.getCurrentAccessToken();
if (accessToken != null) {
String userData = getUserDataFromFacebook(accessToken, headerTitle);
headerTitle.setText(userData);
}
2nd. I try to get the user data the same way as i would get it at the first facebook login.
getUserDataFromFacebook:
private String getUserDataFromFacebook(AccessToken accessToken, final TextView headerTitle) {
Log.v("LoginActivity", "I am here"); // this log works
GraphRequest.newMeRequest(
accessToken,
new GraphRequest.GraphJSONObjectCallback() {
#Override
public void onCompleted(JSONObject object, GraphResponse response) {
Log.v("LoginActivity", "RESPONSE: " + response); //this log doesn`t work.
// Application code
try {
Log.v("LoginActivity", "I am here"); //this log doesn`t work
name = object.getString("name");
} catch (JSONException e) {
e.printStackTrace();
}
}
});
return name;
}
The biggest problem is that the the onCompleted method is not called and I cant access any of the information. I have no idea why..
P.S. I am terrible at Java and this is my first android application.
You're not actually executing the request.
GraphRequest request = GraphRequest.newMeRequest(
accessToken,
new GraphRequest.GraphJSONObjectCallback() {
#Override
public void onCompleted(
JSONObject object,
GraphResponse response) {
// your logic
}
});
Bundle parameters = new Bundle();
parameters.putString("fields", "id,name,link");
request.setParameters(parameters);
request.executeAsync();
Keep in mind this is an Async call so you can't return the name from the function like you've tried to do. Instead you'll have to implement a callback mechanism.
Try this code as it is it will help you to get data from facebook.
make sure you already set permission for data on FacebookLoginButton.
private void getUserDataFromFacebook() {
GraphRequest request = GraphRequest.newMeRequest(
AccessToken.getCurrentAccessToken(),
new GraphRequest.GraphJSONObjectCallback() {
#Override
public void onCompleted(JSONObject object, GraphResponse response) {
Log.e(" Response", response.toString());
String res = (String) object.toString();
Log.e("Response", res);
Gson gson = new Gson();
if (res.length() > 0) {
//do your work here with your res
} else {
Utils.showDialog(SelectFacebookAlbumActivity.this, "",
"Error in getting data");
}
}
});
Bundle parameters = new Bundle();
parameters.putString("fields", "id,name");
request.setParameters(parameters);
request.executeAsync();
}
Let us know it it works for you.

E/Volley: [217] BasicNetwork.performRequest: Unexpected response code 415 [duplicate]

Server side:
import flask
import flask.ext.sqlalchemy
import flask.ext.restless
app = flask.Flask(__name__)
app.config['DEBUG'] = True
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:////tmp/test.db'
SQLALCHEMY_TRACK_MODIFICATIONS=True
db = flask.ext.sqlalchemy.SQLAlchemy(app)
class Person(db.Model):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.Unicode, unique=True)
birth_date = db.Column(db.Date)
class Computer(db.Model):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.Unicode, unique=True)
vendor = db.Column(db.Unicode)
purchase_time = db.Column(db.DateTime)
owner_id = db.Column(db.Integer, db.ForeignKey('person.id'))
owner = db.relationship('Person', backref=db.backref('computers',
lazy='dynamic'))
db.create_all()
manager = flask.ext.restless.APIManager(app, flask_sqlalchemy_db=db)
manager.create_api(Person, methods=['GET', 'POST', 'DELETE'])
manager.create_api(Computer, methods=['GET'])
app.run(host='0.0.0.0', port=5000, debug=True)
Client Side :
Using volley post
RequestQueue queue = Volley.newRequestQueue(this);
StringRequest postRequest = new StringRequest(Request.Method.POST, url,
new Response.Listener<String>()
{
#Override
public void onResponse(String response) {
// response
Log.d("Response", response);
}
},
new Response.ErrorListener()
{
#Override
public void onErrorResponse(VolleyError error) {
// error
Log.d("Error.Response", String.valueOf(error));
}
}
) {
#Override
protected Map<String, String> getParams()
{
Map<String, String> params = new HashMap<String, String>();
params.put("name", "Anything");
return params;
}
};
queue.add( postRequest );
}
Output from log:
04-29 11:42:24.556 1890-1946/? I/Icing: Indexing done F3642025687382E430F3465743F12480D56AAC66
04-29 11:43:32.123 3147-3196/? E/Volley: [157] BasicNetwork.
performRequest: Unexpected response code 415 for http://IP:5000/api/person
04-29 11:43:32.132 3147-3147/? D/Error.Response: com.android.volley.ServerError
04-29 11:45:19.365 1298-1311/? I/UsageStatsService: User[0] Flushing usage stats to disk
provide the right content type as follows
// Optional Parameters to pass as POST request
JSONObject js = new JSONObject();
try {
js.put("name","anything");
} catch (JSONException e) {
e.printStackTrace();
}
// Make request for JSONObject
JsonObjectRequest jsonObjReq = new JsonObjectRequest(
Request.Method.POST, url, js,
new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
Log.d(TAG, response.toString() + " i am queen");
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
VolleyLog.d(TAG, "Error: " + error.getMessage());
}
}) {
/**
* Passing some request headers
*/
#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;
}
};
// Adding request to request queue
Volley.newRequestQueue(this).add(jsonObjReq);
}
415 is the error code for wrong media type. You are sending the body or your post request in plain text when the server expects json. Find out what type of content you should send and make the post body to that type.
#Override
public byte[] getBody() {
return 'your json string'.getBytes();
}
#Override
public String getBodyContentType() {
return "application/json; charset=utf-8";
}
if you are using Kotlin, here is the snippet I implemented
val jsonBody = JSONObject()
jsonBody.put("email", email)
jsonBody.put("password", password)
val requestBody = jsonBody.toString()
val registerRequest =
object : StringRequest(Method.POST, URL_REGISTER, Response.Listener { response ->
print(response)
complete(true)
}, Response.ErrorListener { error ->
Log.d("Error", "not possible to register at this time . $error")
complete(false)
}) {
override fun getBodyContentType(): String {
return "application/json; charset=utf-8";
}
override fun getBody(): ByteArray {
return requestBody.toByteArray()
}
}
Volley.newRequestQueue(context).add(registerRequest)
}

Android: how to create post xml-rpc request with custom http header & content type

I want to creat xml-rpc POST request, and pass 2 parameters "application_name" & "key", and change content type to "application/x-www-form-urlencoded" like my code below.
try {
XMLRPCClient oneTimeKeyClient = new XMLRPCClient(new URL(URL_REQUEST_SAMPLE), XMLRPCClient.FLAGS_DEFAULT_TYPE_STRING);
oneTimeKeyClient.setCustomHttpHeader("X-HTTP-METHOD-OVERRIDE", "POST");
// oneTimeKeyClient.setCustomHttpHeader("Content-Type", "application/x-www-form-urlencoded");
HashMap<String, String> oneTimeKeyParam = new HashMap<>();
oneTimeKeyParam.put("application_name", "hello_app");
oneTimeKeyParam.put("key", "bb5eb953d3b41dcf59f4669d98f8e14782ed83133be772956b");
Vector<Object> params = new Vector<Object>();
params.add(oneTimeKeyParam);
oneTimeKeyClient.callAsync(new XMLRPCCallback() {
#Override
public void onResponse(long id, Object response) {
try {
result = ((Map) response).get(NAME_ONE_TIME_KEY).toString();
} catch (Exception e) {
Timber.e("onParseError %s", e.getMessage());
DialogUtil.showLoginErrorDialog(getSupportFragmentManager());
}
}
#Override
public void onError(long id, XMLRPCException error) {
Timber.e("onError %s", error.getMessage());
DialogUtil.showLoginErrorDialog(getSupportFragmentManager());
}
#Override
public void onServerError(long id, XMLRPCServerException error) {
Timber.e("onServerError %s", error.getMessage());
DialogUtil.showLoginErrorDialog(getSupportFragmentManager());
}
}, "", params);
} catch (Exception e) {
Timber.e("onError %s", e.getMessage());
DialogUtil.showLoginErrorDialog(getSupportFragmentManager());
}
I got error " onServerError APPLICATION_NAME must record not exists."
I using aXMLRPC library https://github.com/gturri/aXMLRPC .
Which library do you recommend ?
Can I use Retrofit to make xml-rpc request ?
Thanks for any help
You just use retrofit like this:
#FormUrlEncoded
#POST("onetime_key")
Observable<OneTimeKeyRes> requestOneTimeKey(#Field("application_name") String applicationName, #Field("key") String key);
You must add SimpleXmlConverter:
Retrofit retrofit = new Retrofit.Builder()
.client(builder.build())
.baseUrl(YOUR_BASE_URL)
.addConverterFactory(SimpleXmlConverterFactory.create())
.build();

facebook like returns Error finding the requested story

I want to use FB SDK to do a like on a postId.
The post is in a 3rd part fb page.
Usually it works. But when I try to do like few days after the post was created I get this response:
Error finding the requested story
here is my code:
Request request = new Request(session,
takeFromPublicMacrosOrServer(currentOffer.fbPostId)
+ "/likes", null, HttpMethod.POST,
new Request.Callback() {
#Override
public void onCompleted(Response response) {
// Request complete
if (response.getError() == null) {
UnlockRequestToServer unlockRequestToServer = new UnlockRequestToServer(
mOffersListActivity,
PublicMacros.TYPE_UNLOCK_FB_LIKE,
currentOffer.fbPostId);
} else {
final String errorMsg = "error: "
+ response.getError().toString();
Log.e(MyLogger.TAG, errorMsg);
mToaster.showToastInUiThread(errorMsg);
}
String re = response.toString();
}
});
request.executeAsync();

Categories

Resources