I have a weird situation that may be because I missed something that I didn't realized or know.
I am creating a simple login UI using Angular and call the Web API created in java.
The java web API function is as follows
#RequestMapping(value = "/logon", method = RequestMethod.POST, produces = {"application/json"})
#ResponseBody
public String logon(
#RequestParam(value = "userID", required = true) String userID,
#RequestParam(value = "password", required = true) String password,
HttpServletRequest request)
Now if I use the http.post as follows
login(username: string, password: string) {
return this.http.post(this.url+"/security/logon/",
JSON.stringify({ userID: username, password: password }) )
Then I get the following error in the Google Chrome browser:
POST http://localhost:8080/logon/ 400 (Required String parameter 'userID' is not present)
But if I change the code as follows:
login(username: string, password: string) {
var usrpwd = "userID=" + username + "&password=" + password;
return this.http.post(this.url+"/security/logon?"+usrpwd, usrpwd )
It work perfectly.
Am I missing something? Why the second parameter of http.post that should be the parameter passed not seems to be working?
Thanks in advance for any reply or feedback.
You are defining your endpoint url with two mandatory parameters, and such parameters must be in the url (check here), so when you make a request to your endpoint, the url must be :
http://localhost:8080/logon?userID=yourUserId&password=yourUserPassword
In the first implementation you are not adding the query parameters to the url so the request is made to the url http://localhost:8080/logon/ as it doesn't have the required parameters, your web tier is returning the 400 http code, which implies a bad request (because again, your url doesn't contains the required parameters).
constructor(private http:HttpClient){
}
login(usrName,usrPwd){
let body = {userName:usrName, userPwd:usrPwd};
this.http.post("http://localhost:5000/security/login", body)
.subscribe(
res => console.log(res),
error => console.log(error)
)
}
Related
I am getting a following GET request
http://localhost:8080/flamingo-json/en/web/Mobile/our-program/Tiers-recognition-Redesigned/rewards-program-new.html
For the above url I have defined the following Mapping in spring rest controller
#GetMapping(value = "/flamingo-json/{language}/{platform}/{page:.+}")
#ResponseBody
public String getAboutUs(#PathVariable(value = "language", required = false) String language,#PathVariable String platform,
#PathVariable String page){
logger.info("Serving " + page + " page for the request");
return aboutUsService.getPageFromDb(page, language, platform);
but I am unable to get "Mobile/our-program/Tiers-recognition-Redesigned/rewards-program-new.html" value in the Path variable 'page' and I am getting 404.
if you want to jump to other page, delete the annotation #ResponseBody;if you want to get the value(like json) from this request,change the annotation to #PostMapping. hope the ans works.
I am trying to send port request with username and password:
signUp(username, password): Observable<String> {
return this.http.post<String>("http://localhost:8080/signUp", {
params: { username: username, password: password }
});
}
To a spring service that has this method:
#CrossOrigin(origins = "http://localhost:4200")
#RequestMapping(value="/signUp", method=RequestMethod.POST)
public ResponseEntity<String> signUp(#RequestParam ("username") String username, #RequestParam("password") String password) throws IOException {
//not important
return new ResponseEntity<String>("Added successfully.", HttpStatus.OK);
}
When I send it, in angular I get http 400 error. In spring service I see this message:
2020-03-13 19:32:38.486 WARN 13200 --- [nio-8080-exec-3] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved [org.springframework.web.bind.MissingServletRequestParameterException: Required String parameter 'username' is not present]
I know that there are values sent from Angular application in that http request (I checked with hardcoded). Can someone help me solve it? Thanks in advance.
Seems like there is a confusion between #RequestBody and #RequestParam - they're two entirely different things.
#RequestBody Indicates that the API is expecting a request payload
and
#RequestParam expects one or more params to be passed in to the API
url when it is invoked.
Now, the backend expects a request parameter to be passed in when it is invoked. For eg: /signUp/username=abc, so from the UI you need to pass in this key-value pair i.e
http.post<String>(`http://localhost:8080/signUp?username=${username}&password=${password}`)
The 400 bad request originates as you are passing in a request body rather than a request parameter. An alternate solution is to change the backend to accept a request payload - you would then need to use #RequestBody.
A possible solution could be this request:
signUp(username, password): Observable<String> {
return this.http.post<String>("http://localhost:8080/signUp", {
username: username, password: password
});
}
...with a class for the request body in your backend:
public class SignUp {
private String username;
private String password;
// constructor, getters and setters or lombok #Data
}
...and then in your controller:
#RequestMapping(value="/signUp", method=RequestMethod.POST)
public ResponseEntity<String> signUp(#RequestBody SignUp signUp) {
// signUp.getUsername()...
return new ResponseEntity<String>("Added successfully.", HttpStatus.OK);
}
I have the below post request and of which below is the controller code
#RestController
#RequestMapping(/flow", consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
#Override
#ResponseStatus(HttpStatus.OK)
#PostMapping("{abcCode}/token")
public TokenResponse createToken(#PathVariable("abcCode") String abcCode,
#RequestParam("grant_type") String grantType,
#RequestParam String code,
#RequestParam("redirect_uri") String redirectUri,
#RequestParam String clientId) {
LOG.info(
"Received call for createIdToken for abcCode: {} , clientId: {} , grantType: {} ,code: {} , redirectUri: {}",
abcCode, clientId, grantType, code, redirectUri);
}
Now the problem is that when I test the same above controller through postman by choosing the body type as application form-encoded then it is working fine but when I choose the body type as none in postman and just pass the above request parameters as query one then also it works which ideally it should not please advise how can I overcome from the same
http://localhost:19080/testService/flow/token?grant_type=authorization_code&code=3272&redirect_uri=http://www.abchui.com&clientId=ATS
it should not work for the above URL
From spring sources:
public static final String APPLICATION_FORM_URLENCODED_VALUE = "application/x-www-form-urlencoded";
According to docs, when using url-form-encoded data pass as query params.
Try to change form mime type.
I am trying to learn Spring Framework for creating RESTful web service for my future projects. So far I have tried using GET and consume it with no problem using a simple Ajax request. I have also tried using query strings to input parameters.
As of now I am trying to create an endpoint that receives a POST request. I've been researching for some days now but to no avail (some tuts are too complicated for a beginner like me).
Here is my simple code:
Java Spring
#RequestMapping(value = "/test", method = RequestMethod.POST)
#ResponseBody
public String testString(String jsonString)
{
System.out.println(jsonString);
return jsonString;
}
Ajax
var data = {"name":"John Doe"}
$.ajax({
url: "http://localhost:8080/springrestexample/test",
method:"POST",
data:data,
dataType:'text',
success: function( data ) {
alert(data);
},
error: function( xhr, status, errorThrown ) {
alert("Error:" + errorThrown + status);
}
});
I have tried debugging tomcat and it seems like I am not passing any value on the testString. Do I need to add something on my java code?
#RequestMapping only maps your method to some url.
To access data you need #RequestParam annotation to get data, eg:
#RequestMapping(value = "/test", method = RequestMethod.POST)
#ResponseBody
public String testString(#RequestParam("name") String jsonString)
{
System.out.println(jsonString);
return jsonString;
}
Look at this manual for more examples.
Since you are passing data into body from your ajax request, so you need to retrieve from the
#RequestBody
Add this annotation before the arguments like this way;
public String testString(#RequestBody String jsonString) {
System.out.println(jsonString);
return jsonString;
}
And you are done :)
I have some trouble figuring out how to create a login form in angularjs using springboot.
I can register a user and send the data to the database but the problems begin when i want to login.
in angularjs i have a function like this
function Login(username, password, callback) {
$http.post('/api/authenticate', { username: username, password: password })
.success(function (response) {
callback(response);
});
}
What i managed to do but probably is't right:
#RequestMapping(value = "/authenticate/{id}",method = RequestMethod.GET)
public User getUser(#PathVariable Integer id) {
return repo.findOne(id);
}
This gives me following json
{"id":2,"username":"jdoe","password":"$2a$10$5hgIyQr.K9wb8cXEyWGbROAU.rkYzd19vP7ajHpwp1KUYdShfcPn.","lastname":"doe","firstname":"john","customfield":"Hello there"}
But now i have following problems and questions :
How can i check if the username and password is equal to the username and password of json by going to api/authenticate ? (without {id})
can i hide this json from the users ?
Is this safe ?
how will angular now all the users propertys ? (i suggest i can retrieve this from the json)
any pro tips on how to solve this?
From AngularJS you are calling HTTP POST method and at Spring side you have declared as HTTP GET, which is wrong.
Correct request mapping is
#RequestMapping(value = "/api/authenticate",method = RequestMethod.POST, consumes = "application/json")
#ResponseBody
public User getUser(#RequestBody User user) {
//here request body contains User POJO object's payload (JSON object)
//You are getting username from JSON,
//so you need to update your call to findOne method
return repo.findOne(user.getUserName());
}
Please refer
#RequestBody and #ReponseBody spring
#RequestBody annotation spring docs
#RequestMapping#consumes