I am having a minimal Spring-based Restful server with the following hopefully public method
#RequestMapping("/regUser")
public #ResponseBody String addUser( #RequestParam(value="name", required=true) String username,
#RequestParam(value="email", required=true) String email,
#RequestParam(value="newsletter", required=true) String newsletter){
User newUser = new User();
newUser.setEmail(email);
newUser.setUsername(username);
newUser.setReceiveNewsletter(true);;
System.out.println("+++++++++++++++");
System.out.println("USER: " + username + " | email: " + email + " | newsletter: " + newsletter);
System.out.println("+++++++++++++++");
userRepo.save(newUser);
return "true";
}
When I open the link in the browser and provide the needed parameters using GET in the URL everything is working perfectly fine. So I assume the problem will be in the following Android part.
I want to call the method above from my Android Device. The user has to enter the needed information in three EditText and press a button for sending everthing to the Restful server.
#Override
protected UserWrapper doInBackground(String... params) {
try{
final String url = params[0];
RestTemplate tmpl = new RestTemplate();
tmpl.getMessageConverters().add(new MappingJackson2HttpMessageConverter());
UserWrapper greet = tmpl.getForObject(url, UserWrapper.class);
for(User usr : greet.getUsers()){
Log.d("User", "Post - Name: " + String.valueOf(usr.getUsername()));
Log.d("User", "Post - eMail: " + String.valueOf(usr.getEmail()));
}
return greet;
}catch(Exception ex){
ex.printStackTrace();
}
return null;
}
This is my Code for sending everything to the server. I did this in an AsyncTask because not blocking the main UI Thread in Android if the server takes a little bit longer.
So, what is happening?
First of all I got the message:
Error, required field name is not present.
If I switch form requiered = true to requiered = false, I got the short message "true" and the server reports the following short message:
+++++++++++++++
USER: null | email: null | newsletter: null
+++++++++++++++
How can I send the needed parameters using POST to the server?
Thanks to all of you trying to help!
What if you create a Map of params, then call your restfull service.
Map<String, String> params = new HashMap<String, String>();
//add params
params.put("name", "the name");
params.put("email", "the email");
params.put("newsletter", "the newsletter");
//call service method
String result = tmpl.getForObject(url, String.class, params);
Based on the suggestions, I've found another tutorial which is doing exactly what I wanted to to
http://johnathanmarksmith.com/spring/java/javaconfig/programming/spring%20java%20configuration/spring%20mvc/web/rest/resttemplate/2013/06/18/how-to-use-spring-resttemplate-to-post-data-to-a-web-service/
Using this tutorial everything is working the way I wanted it to work!
Related
I am integrating Facebook login integration. After login, I need to get the name, email, and profile pic of the user. I am getting the details but the profile pic is not showing up in my image view android.
GraphRequest request = GraphRequest.newMeRequest(
currentAccessToken, new GraphRequest.GraphJSONObjectCallback() {
#Override
public void onCompleted(JSONObject object, GraphResponse response) {
Log.d("TAG", object.toString());
Log.d("res", object.toString());
Log.d("res_obj", response.toString());
try {
String id = object.getString("id");
try {
URL profile_pic = new URL("https://graph.facebook.com/" + id + "/picture?width=50&height=50");
Log.i("profile_pic", profile_pic + "");
String f_name = object.getString("first_name");
String l_name = object.getString("last_name");
String name = f_name + " " + l_name;
String email = object.getString("email");
String image = profile_pic.toString();
Log.d("data", email + name + image);
updateUI(name,email,image);
} catch (MalformedURLException e) {
Log.e(TAG,"pic res"+e.getMessage()) ;
}
} catch (JSONException e) {
e.printStackTrace();
}
}
});
Bundle parameters = new Bundle();
parameters.putString("fields", "first_name,last_name,email,id,picture");
request.setParameters(parameters);
request.executeAsync();
// here I am getting all the details but the image not uploading and also I am getting exception like this.
{HttpStatus: 400, errorCode: 100, subErrorCode: 33, errorType:
GraphMethodException, errorMessage: Unsupported get request. Object
with ID '502053987890832' does not exist, cannot be loaded due to
missing permissions, or does not support this operation. Please read
the Graph API documentation at
https://developers.facebook.com/docs/graph-api}
I think the documentation is quite explicit what problem is:
Querying a User ID (UID) now requires an access token. Refer to the requirements table to determine which token type to include in UID-based requests.
Which takes you to the explanation. Reading this it seems you need to use user access token. The docs tell you how to get the access token here.
Regretfully Facebook API docs does not make it too explicit how to add the access token, assuming all its users are aware of OAuth 2.0 specifics. Still, you can simply add header Authorization with a value Bearer <you-access-token> to your request and this will authorize your access.
I am trying to connect my libGDX(java) android project with a mySQL database through a server side PHP scripting in order to implement a login process using POST method (this includes a username and password).
Therefore, i am facing unexpectable problems. For your info i am using XAMPP and APACHE web server locally.
What i am facing! Some times the PHP script sends back the following response string, as if not recognizing the POST parameters (despite the fact that POST message includes them and contain values (string)!!):
<b>Notice</b>: Undefined index: username in <b>C:\xampp\htdocs\login\login.php</b> on line <b>5</b><br />
<br />
<b>Notice</b>: Undefined index: password in <b>C:\xampp\htdocs\login\login.php</b> on line <b>6</b><br />
Some other, the debugger (on Android studio) which is enabled to show me the debugging logs, stops displaying any log after pressing 2-5 times the btnclickLogin() (is shown below), which implements the login activity.
This sounds to me that http connection hangs up and maybe the click button's listener does not respones any more!!!
The more strange one, is that SOMETIMES the same code, returns "success" and everything works fine.
The android code is the next
private void btnclickLogin() {
//Getting values from edit texts
Gdx.app.setLogLevel(Application.LOG_DEBUG);
final String username = usernamefld.getText().toString().trim();
final String password = passwordfld.getText().toString().trim();
Map<String, String> parameters = new HashMap<String, String>();
parameters.put("username", username);
parameters.put("password", password);
Gdx.app.debug("Login process started.", "Username=/" + username + "/ Password=/" + password + "/");
HttpRequestBuilder requestBuilder = new HttpRequestBuilder();
HttpRequest httpRequest;
httpRequest = requestBuilder.newRequest().method(Net.HttpMethods.POST).url("http://192.168.1.2/login/login.php").content(HttpParametersUtils.convertHttpParameters(parameters)).build();
httpRequest.setHeader("Content-Type", "application/x-www-form-urlencoded");
httpRequest.setTimeOut(6000);
Gdx.net.sendHttpRequest(httpRequest, new HttpResponseListener() {
#Override
public void handleHttpResponse(Net.HttpResponse httpResponse) {
String status = httpResponse.getResultAsString().trim();
Gdx.app.debug("Return result by the server=", status);
if(status.contains("success"))
game.setScreen(new StartingScreen(game));
}
#Override
public void failed(Throwable t) {
String status = "failed";
Gdx.app.debug("Connection failed due to the next error:", t.getMessage());
}
#Override
public void cancelled() {
}
});
httpRequest.reset();
Gdx.app.debug("Exiting", "From login button function");
}
PHP scripts are
For login.php
<?php
if($_SERVER['REQUEST_METHOD']=='POST'){
//Getting values
session_start();
$username = $_POST['username'];
$password = $_POST['password'];
//Creating sql query
$sql = "SELECT * FROM users WHERE username='$username' AND password='$password'";
//importing dbConnect.php script
require_once('dbConnect.php');
//executing query
$result = mysqli_query($con,$sql);
//fetching result
$check = mysqli_fetch_array($result);
//if we got some result
if(isset($check)){
//displaying success
echo "success";
}else{
//displaying failure
echo "failure";
}
mysqli_close($con); }?>
For dbConnect.php
<?php
define('HOST',"localhost");
define('USER',"root");
define('PASS',"");
define('DB',"userlogging");
$con = mysqli_connect(HOST,USER,PASS,DB) or die('Connection failed: ' . $conn->connect_error);
$con->set_charset("utf8"); ?>
Please give a hand to overcome this problem and make the http connection "stable"!!
Thanks a lot.
Mishra sorry for the latest of my reply.
Yes, actually i have placed a print_r to see the values that come up to PHP script and found that both parameters were missing.
After so much searches on the internet and alternative solutions that found, i have not found out why does it happen. So, i replaced the HttpRequestBuilder.
Finally, in order to have a complete working code, i used the next and everything works fine now.
final String username = usernamefld.getText().toString().trim();
final String password = passwordfld.getText().toString().trim();
Map<String, String> parameters = new HashMap<String, String>();
parameters.put("username", username);
parameters.put("password", password);
final HttpRequest httpRequest = new HttpRequest(Net.HttpMethods.POST);
httpRequest.setHeader("Content-Type", "application/x-www-form-urlencoded");
httpRequest.setHeader("Upgrade", "HTTP/1.1, HTTP/2.0, SHTTP/1.3, IRC/6.9, RTA/x11");
httpRequest.setUrl(LOGIN_URL);
httpRequest.setContent(HttpParametersUtils.convertHttpParameters(parameters));
httpRequest.setTimeOut(6000);
Thanks again for your help.
I am using the below code to log into Facebook. Once i get the code, using that i get access token and then query graph api and get some basic details.
#RequestMapping(value = "/fblogin")
public String inititateFBlogin(ModelMap model) {
System.out.println("in FB login ");
String fbAuthURL = fbConnectionService.getFBAuthUrl();
return "redirect:"+fbAuthURL;
}
public String getFBAuthUrl() {
String fbLoginUrl = "";
try {
fbLoginUrl = "http://www.facebook.com/dialog/oauth?" + "client_id="
+ FBConnection.FB_APP_ID + "&redirect_uri="
+ URLEncoder.encode(FBConnection.REDIRECT_URI, "UTF-8")
+ "&scope=email";
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return fbLoginUrl;
}
But to logout , i am hitting the URL in below format.
//https://www.facebook.com/logout.php?next=[YourAppURL]&access_token=[ValidAccessToken]
#RequestMapping(value = "/fblogout", method=GET)
public String fbLogOut(ModelMap model) {
String fbLogoutURL = "https://www.facebook.com/logout.php?confirm=1&next=";
String appURL = "http://localhost:15005/abc";
String accessToken = accessTokenFB ;
String logOutURL = fbLogoutURL+appURL+"&access_token="+accessToken;
return "redirect:"+logOutURL;
}
But looks like the above FB url always redirects to the FB homepage.
Is there any way that i can log out by simply calling any FB service through java, I would rather avoid going down to the javascript SDK.
Many thanks.
You can logout an access token by sending a DELETE (instead of GET/POST) request to /me/permissions
https://developers.facebook.com/docs/facebook-login/permissions/requesting-and-revoking
https://developers.facebook.com/docs/graph-api/reference/user/permissions/
curl -X DELETE https://graph.facebook.com/me/permissions?access_token=ABC
I'm using Spring MVC for add & update form.
Don't know why cannot redirect back to same form to show error message while submitted BindingResult (form validation, wrong input etc..) got any errors.
This happen when using PUT method(update things), not POST method (add things)...
Please anyone suggestion what should I do.
Thanks in advance.
Error in the browser I received:
HTTP Status 405 - HTTP method PUT is not supported by this URL
type Status report
messageHTTP method PUT is not supported by this URL
descriptionThe specified HTTP method is not allowed for the requested resource.
GlassFish Server Open Source Edition 4.1.1
Console nothing show up... just the log I make showing which field of input got error.
Here the methods inside controller:
//Add - no problem can show validation error message in the JSP form
#RequestMapping(value = "/userDetail", method = RequestMethod.POST)
public String saveUserDetail(#Valid UserDetail userDetail,
Errors errors) {
if (errors.getErrorCount() > 0) {
log.info("User attempt create user: " + userDetail.toString());
for (FieldError error : errors.getFieldErrors()) {
log.info(error.getField() + ": " + error.getDefaultMessage());
}
//redirect to same page to show error return infor (NotEmpty etc...)
return "/user/inputUserDetail"; //same structure for PUT method below, but not working show me 405 error
} else {
try {
userDetailService.addUserDetail(userDetail);
} catch (Exception e) {
log.error("Failed to add new UserDetail: " + userDetail.toString());
}
return "redirect:/user/userDetails";
}
}
//Update - need UserDetail model attribute
#RequestMapping(value = "/userDetail", method = RequestMethod.PUT)
public ModelAndView updateUserDetail(#Valid UserDetail userDetail,
Errors errors, Map<String, Object> map) {
if (errors.getErrorCount() > 0) {
log.info("User attempt update user: " + userDetail.toString());
for (FieldError error : errors.getFieldErrors()) {
log.info(error.getField() + ": " + error.getDefaultMessage());
}
//I want to redirect to same form but show validation of previous inputted got error (NotEmpty, Email, typeMissMatch etc...)
//Below tested all failed
//Use this when return type is String
//return "/user/inputUserDetail"; //405 error
//return inputUserDetail(map); //405 error, direct call another method in same controller to show update form
//return "redirect:/user/userDetail/" + userDetail.getUdId(); //ok, but this one is redirect, no current errors bind to the update form
//Use this when return type is ModelAndView
map.put(BindingResult.MODEL_KEY_PREFIX + "userDetail", errors);
map.put("userDetail", userDetail);
ModelAndView mv = new ModelAndView();
mv.addObject(new RedirectView("FaddistWardrobe/user/userDetail"));
mv.addAllObjects(map);
return mv;
} else {
try {
//update user detail
userDetailService.updateUserDetail(userDetail);
} catch (Exception e) {
log.error("Failed to update UserDetail: " + userDetail.toString());
}
//This one okay can perform while form data correct
//If return String like above method, result same, both ok
return new ModelAndView("redirect:/user/userDetails");
}
}
The mapping I follow REST url style PUT method for update user, don't know it is possible cannot call internal JSP while using PUT method? Or any configuration I miss out for PUT method setup?
This webapp already configured org.springframework.web.filter.HiddenHttpMethodFilter...
Appreciate & welcome any suggestions, I just started to learn Spring MVC...
Hope someone help... Thanks again.
The problem is trying to perform like PUT => Redirect => PUT
(1) Above code okay when try to add correct data because it perform like PUT => Redirect => GET
(2) Fail due to trying display error in the same page using PUT method
Solution is change to PUT => Redirect => GET as below coding:
//Update - need UserDetail model attribute
#RequestMapping(value = "/userDetail", method = RequestMethod.PUT)
public String updateUserDetail(#Valid UserDetail userDetail,
Errors errors, Map<String, Object> map,
final RedirectAttributes redirectAttributes) {
if (errors.getErrorCount() > 0) {
//log.info("User attempt update user: " + userDetail.toString());
for (FieldError error : errors.getFieldErrors()) {
log.info(error.getField() + ": " + error.getDefaultMessage());
}
//redirect to same page to show error return infor (NotEmpty etc...)
redirectAttributes.addFlashAttribute("userDetail", userDetail);
redirectAttributes.addFlashAttribute(BindingResult.MODEL_KEY_PREFIX + "userDetail", errors);
return "redirect:/user/userDetail/error";
} else {
try {
//update user detail
userDetailService.updateUserDetail(userDetail);
} catch (Exception e) {
String tmp = e.getLocalizedMessage();
String tmp2 = e.toString();
//log.error("Failed to update UserDetail: " + userDetail.toString());
}
return "redirect:/user/userDetails";
}
}
//Display form with validation error after update fail (PUT -> Redirect -> GET)
#RequestMapping(value = "/userDetail/error", method = RequestMethod.GET)
public String inputUserDetail_error() {
//Here will auto retrieve previous redirectAttributes data and put into the JSP page.
return "/user/inputUserDetail";
}
Just use redirectAttributes store temporary model and when the user after redirected, can retrieved back previous model and use it.
Hope able help other fresh to SpringMVC with this solution.
Thanks.
my application suppose to connect a web service and active some of his functions.
first, the application activate a "Login" function that gets as arguments username and password, the function search the user name and the password in a database and returning me if im logged in or not. and creating a session vars for me like:
Session["Username"] = User.Username;
Session["FullName"] = User.FullName;
and more...
and than i want to active another webservice function - UpdateProfile
that change my profile values on the database.
so, my application has a class with some private classes (asynctasks)
and every asynctask is responsible for one function in the webservice.
for example - the login asynctask:
private class LoginAsyncTask extends AsyncTask<String, String, User>
{
private String METHODNAME = "Login";
private String SOAPACTION = "http://tempuri.org/Login";
and more...
in this login asynctask i parse the comming back cookies like this:
cookies is a HashMap<String, String>();
try
{
//respHeaders = trans.call(SOAPACTION, envelope, null);
reshttpHeaders = trans.call(SOAPACTION, envelope, null);
}
catch (Exception e)
{
//connection error.
e.printStackTrace();
return null;
}
cookies.clear();
if (reshttpHeaders!=null) {
for (int i = 0; i < reshttpHeaders.size(); i++) {
HeaderProperty hp = (HeaderProperty)reshttpHeaders.get(i);
String key = hp.getKey();
String value = hp.getValue();
if (key!=null && value!=null) {
if (key.equalsIgnoreCase("set-cookie")){
String cookieString = value.substring(0,value.indexOf(";") );
cookies.put(cookieString.substring(0, cookieString.indexOf("=")),cookieString.substring(cookieString.indexOf("=")+1) );
break;
}
}
}
}
and than, in another asynctask called UpdateProfileAsynctask
im sending this cookie like this:
List<HeaderProperty> httpHeaders = new ArrayList<HeaderProperty>();
for (String cookie:cookies.keySet()) {
httpHeaders.add(new HeaderProperty("Cookie", cookie + "=" + cookies.get(cookie)));
}
try
{
//trans.call(SOAPACTION, envelope, reqHeaders);
trans.call(SOAPACTION, envelope, httpHeaders);
}
when i try to catch this packets with wireshark i see that the cookie that i get is:
Set-Cookie: ASP.NET_SessionId=kmwn4l2qzc0k1anfk1du4ty1; path=/; HttpOnly\r\n
and my cookie that i send is:
Cookie: ASP.NET_SessionId=kmwn4l2qzc0k1anfk1du4ty1\r\n
The problem is that the webservice dont recognize me (the second request is in the 20 minutes period).
this part of the code in the webservice running:
if (Session["Username"] == null)
return "Cant Update profile now, Your connection seems to be timeout";
and i get this message all time. but its stange that sometimes its working :/
thanks.
I fix my problems after reading your questions, thank you.
My code is like the folloiwng:
HeaderProperty headerPropertySessionId = new HeaderProperty("Cookie", "key1=value1");
List headerPropertyList = new ArrayList();
headerPropertyList.add(headerPropertySessionId);