I'm trying to set up a webapp with ReactJS as the front-end and a Java back-end connected via Spring, but I am new to Spring.
I have two different Requests set up right now in a RestController:
@RequestMapping(value = "/index")
public String index() {
return "index string!";
}
@RequestMapping(method=RequestMethod.POST, value="/login")
public void login(@RequestParam("user") User user) {
System.out.println(user);
}
I can successfully query /index from the front-end like this:
fetch("http://localhost:3002/index").then(function(response) {
console.log(response.text());
return response;
});
This prints a Promise that contains the string "index string!" (I'm not exactly sure how to use this string yet either, but that's not my main problem)
I want to send data using a POST request (should it be PUT?) for a user to log in. My plan is to get a User Object from the request and validate that against my database somewhere else in the Java code. Here is a User object:
public class User {
private String username;
private String password;
public User(String uName, String pass) {
username = uName;
password = pass;
}
}
and here is the POST request in the front-end:
fetch('http://localhost:3002/login', {
method: 'POST',
body: {
username: username,
password: password
}
});
where username and password are strings parsed from HTML.
My understanding is that Spring should create a User Object from the body of the request and let me use that, but instead I'm getting a 400 error without much more detail.
How can I make this 400 error go away and successfully pass data from my front-end to my back-end?
EDIT: here is the top few lines of the returned error
VM10542:1 POST http://localhost:3002/login 400 ()
(anonymous) @ VM10542:1
func @ LoginPage.js:26
LoginPage.js:26 is the fetch call.
I'm trying to set up a webapp with ReactJS as the front-end and a Java back-end connected via Spring, but I am new to Spring.
I have two different Requests set up right now in a RestController:
@RequestMapping(value = "/index")
public String index() {
return "index string!";
}
@RequestMapping(method=RequestMethod.POST, value="/login")
public void login(@RequestParam("user") User user) {
System.out.println(user);
}
I can successfully query /index from the front-end like this:
fetch("http://localhost:3002/index").then(function(response) {
console.log(response.text());
return response;
});
This prints a Promise that contains the string "index string!" (I'm not exactly sure how to use this string yet either, but that's not my main problem)
I want to send data using a POST request (should it be PUT?) for a user to log in. My plan is to get a User Object from the request and validate that against my database somewhere else in the Java code. Here is a User object:
public class User {
private String username;
private String password;
public User(String uName, String pass) {
username = uName;
password = pass;
}
}
and here is the POST request in the front-end:
fetch('http://localhost:3002/login', {
method: 'POST',
body: {
username: username,
password: password
}
});
where username and password are strings parsed from HTML.
My understanding is that Spring should create a User Object from the body of the request and let me use that, but instead I'm getting a 400 error without much more detail.
How can I make this 400 error go away and successfully pass data from my front-end to my back-end?
EDIT: here is the top few lines of the returned error
VM10542:1 POST http://localhost:3002/login 400 ()
(anonymous) @ VM10542:1
func @ LoginPage.js:26
LoginPage.js:26 is the fetch call.
Share Improve this question edited Dec 4, 2017 at 23:55 Jordan asked Dec 4, 2017 at 23:31 JordanJordan 531 gold badge2 silver badges5 bronze badges 4- What is the body of the 400 response? That might contain more information. Can you debug the request with something like Postman? – tahsmith Commented Dec 4, 2017 at 23:42
-
@RequestParam("user")
- it forces POST URL to be'http://localhost:3002/login?user=...
, try to remove that annotation from the method and replace it with@RequestBody
– Vadim Commented Dec 4, 2017 at 23:48 - Taking out the @RequestParam("user") makes it a 500 error instead – Jordan Commented Dec 4, 2017 at 23:53
- Sorry... look at @pawkrol response for details... – Vadim Commented Dec 5, 2017 at 0:10
1 Answer
Reset to default 8First of all, yes POST is the correct method for this type of call.
In your case you have two options:
Send data as a body
So that the endpoint implementation will look like this:
@RequestMapping(method=RequestMethod.POST, value="/login")
public void login(@RequestBody User user) {
System.out.println(user);
}
Then send it as a JSON
fetch('http://localhost:3002/login', {
method: "POST",
headers: {
Accept: "application/json",
"Content-Type": "application/json"
},
body: JSON.stringify({
username: "foo",
password: "bar"
})
});
Or send it in params
So that the endpoint implementation will look like this:
@RequestMapping(method=RequestMethod.POST, value="/login")
public void login(@RequestParam("username") String username,
@RequestParam("password") String password) {
System.out.println(username + " " + password);
}
Then send it in params (not the best implementation):
fetch('http://localhost:3002/login?username=' + username
+ '&password=' + password, {
method: "POST",
headers: {
Accept: "application/json",
"Content-Type": "application/json"
}
});
Of course you should bear in mind that plain sending a password is not a good idea, but I believe it is for learning purposes. In other case you may take a look at HTTPS.
You may also take a look at other login handling techniques like for starters JWT or maybe you can introduce OAUTH. Good luck!
EDIT:
I haven't noticed that your model class is wrong. I believe that you need to make it look like this:
class User {
private String username;
private String password;
public User(String username, String password) {
this.username = username;
this.password = password;
}
public String getUsername() {
return username;
}
public String getPassword() {
return password;
}
}
So the Spring was telling you that the constructor is wrong, because he couldn't find the proper mapping for the username
and password
fields.