#RequestMapping annotation ignoring POST, Spring - java

My Controller:
#Controller
#RequestMapping("/registration")
public class RegisterController {
#RequestMapping("")
public String register() {
return "register";
}
#RequestMapping(value = "", method = RequestMethod.POST)
public ModelAndView registerUser(#RequestParam("emailsignup") String email,
#RequestParam("firstname") String firstName,
#RequestParam("lastname") String lastName,
#RequestParam("passwordsignup") String password) throws SQLException, ClassNotFoundException {
ModelAndView modelAndView = new ModelAndView();
.... SQL code that inserts if it can
}
My register.jsp is just a regular form, I had this code working prior but it was mapping to "/" and was messing up my other mapping. When the POST form is clicked (if successful) I want it to return the user to /profile, if non successful to stay on /registration... how can I do this?

You can use, HttpRedirectAttributes like this:
#RequestMapping(value = "", method = RequestMethod.POST)
public ModelAndView registerUser(#RequestParam("emailsignup") String email,
#RequestParam("firstname") String firstName,
#RequestParam("lastname") String lastName,
#RequestParam("passwordsignup") String password,
RedirectAttributes redirect) throws SQLException, ClassNotFoundException {
redirect.addFlashAttribute("emailsignup", emailsignup);
redirect.addFlashAttribute("firstname", emailsignup);
// Next
// Or redirect.addFlashAttribute("profile", profileObject)
return modelAndView.setViewName("redirect:/profile");
}
Then in your jsp recover properties like this:
<label>${emailsignup} </label>
or
<label>${profileObject.emailsignup}</label>

Related

POST request from Angular to SpringBoot API not sending parameters

I have this code, where I send an object to the API:
validateLogin(user:User):Observable<string>{
console.log(JSON.stringify(user));
return this.http.post<string>(`http://localhost:8080/login/login`, user).pipe(
map((resp)=>{
return this.repareString(JSON.stringify(resp));
})
)
}
I don't see anything wrong, but Spring Boot says "required request parameter 'user' for method parameter type String is not present". I've also tried sending it as a JSON object but it says the same. I believe that this is caused by the code in angular, that's why I post it here.
#RestController
#RequestMapping("/login")
public class LoginController {
#PostMapping("/login")
public static String login(#RequestParam String user) throws Exception{
System.out.println(user);
Login l = new ObjectMapper().readValue(user, Login.class);
if(l.checkUser().equals("ok")){
if(l.checkPassword().equals("ok")){
return "logged";
} else {
return l.checkPassword();
}
}
return l.checkUser();
}
}
And the Login class:
public class Login extends Database{
public String email;
public String pass;
public Statement stm;
public Login(String email, String pass) throws Exception{
this.email = email;
this.pass = pass;
this.stm = (Statement) this.con.createStatement();
}
I have tried sending it as a JSON string and I've also tried sending the object properties individually as various params.
Change your controller like this:
#RestController
#RequestMapping("/login")
public class LoginController {
#PostMapping("/login")
public static String login(#RequestBody Login login) throws Exception{
System.out.println(login);
if(login.checkUser().equals("ok")){
if(login.checkPassword().equals("ok")){
return "logged";
} else {
return login.checkPassword();
}
}
return login.checkUser();
}
}

Spring mvc validate a primitive with #RequestBody doesn't work

I'm trying to validate an email that I receive from the post request body but it's doesn't work !
#RequestMapping(value = "myservice/emails", method = RequestMethod.POST)
public String requestFoo(#RequestBody #Email String email) {
return email;
}
When I send a request with a string that doesn't respect the email regex the function is executed and I receive a 200 status code.
Even do I add the #Valid annotation the result is always the same.
#RequestMapping(value = "myservice/emails", method = RequestMethod.POST)
public String testValidation(#Valid #RequestBody #Email String email) {
return email;
}
Start with Spring 3.2 #RequestBody method argument may be followed by Errors object, hence allowing handling of validation errors in the same #RequestMapping :
#RequestMapping(value = "myservice/emails", method = RequestMethod.POST)
public ResponseEntity<String> testValidation(#Valid #RequestBody #Email String email, Errors errors) {
if (errors.hasErrors()) {
return ResponseEntity.badRequest().body(ValidationErrorBuilder.fromBindingErrors(errors));
}
return email;
}
And create a custom validator :
public class ValidationErrorBuilder {
public static ValidationError fromBindingErrors(Errors errors) {
ValidationError error = new ValidationError("Validation failed. " + errors.getErrorCount() + " error(s)");
for (ObjectError objectError : errors.getAllErrors()) {
error.addValidationError(objectError.getDefaultMessage());
}
return error;
}
}

Java Spring MVC How to get this set value?

How to get the value has been set from GET method? How to pass the value to POST method? Should I declare global variable?
EDIT: What I want is doing something on GET method and display a textbox on jsp if setdisplayBox = true. When the user POST the form, the setdisplayBox should be true too and return the same jsp without redirect
#RequestMapping(method = RequestMethod.GET)
public String getSuccess(ModelMap model, #ModelAttribute("user") User user, HttpServletRequest request)
{
String boxDisplay = "True";
user.setdisplayBox(boxDisplay);
return "success";
}
#RequestMapping(method = RequestMethod.POST)
public String resetPassword(HttpServletRequest request, ModelMap model, #ModelAttribute("user") User user, ModelMap modelMap)
{
user.setdisplayBox(user.getdisplayBox()); //how to get value has been set above?
return "success";
}
Set a global variable for the user.
private User userAccount;
#RequestMapping(method = RequestMethod.GET)
public String getSuccess(ModelMap model, #ModelAttribute("user") User user, HttpServletRequest request)
{
String boxDisplay = "True";
user.setdisplayBox(boxDisplay);
userAccount = user; //load user in to global var
return "success";
}
#RequestMapping(method = RequestMethod.POST)
public String resetPassword(HttpServletRequest request, ModelMap model, #ModelAttribute("user") User user, ModelMap modelMap)
{
user.setdisplayBox(userAccount.getdisplayBox());
userAccount = null; //reset it to something to make sure you are loading it to another user later.
return "success";
}

Handle update forms in Spring MVC

What is the proper way to handle editing objects in Spring MVC. Let's say I have user object:
public class User {
private Integer id;
private String firstName;
private String lastName;
//Lets assume here are next 10 fields...
//getters and setters
}
Now in my controller I have GET and POST for url: user/edit/{id}
#RequestMapping(value = "/user/edit/{user_id}", method = RequestMethod.GET)
public String editUser(#PathVariable Long user_id, Model model) {
model.addAttribute("userForm", userService.getUserByID(user_id));
return "/panels/user/editUser";
}
#RequestMapping(value = "/user/edit/{user_id}", method = RequestMethod.POST)
public String editUser(#Valid #ModelAttribute("userForm") User userForm,
BindingResult result, #PathVariable String user_id, Model model) {
if(result.hasErrors()) {
User user = userService.getById(user_id);
user.updateFields(userForm);
}
userService.update(user);
}
Now the question is do I really need to get my user from database in POST method and update every field one by one in some update method or is there better way for that?
I am thinking about using #PathVariable for User and get User from database with converter and then in some way inject parameters from POST method into that object automatically. Something like this:
#RequestMapping(value = "/user/edit/{user}", method = RequestMethod.POST)
public String editUser(#Valid #PathVariable("user") User userForm,
BindingResult result, Model model)
But when I try this I got error with BindingResults:
java.lang.IllegalStateException: An Errors/BindingResult argument is expected to be declared immediately after the model attribute, the #RequestBody or the #RequestPart arguments
Is there any easy way to create controller to handle objects editing or do I need to copy fields which could change one by one??
By the way, I can't use SessionAttributes because it causes problems for multiple tabs.
I believe you are sending "userForm" as a model attribute. If so try with following pattern,
#RequestMapping(value = "/user/edit/{user_id}", method = RequestMethod.POST)
public String editUser(#PathVariable String user_id, #Valid #ModelAttribute("userForm") User userForm,
BindingResult result, Model model)
Thanks
You keep user id in a input hidden inside your edit form.
#RequestMapping(value = "/user/edit", method = RequestMethod.POST)
public String editUser(#Valid #ModelAttribute("userForm") User userForm,
BindingResult result,Model model){
if(result.hasErrors()){
User user = userService.getById(userForm.getId());
user.updateFields(userForm);
}
userService.update(user);
return "redirect:.......";
}

Is it alright to create an object of modelandview in each method of the class?

I have following controller which is serving different requests. I am wondering if the way that I create ModelAndView is correct? I am creating one object in each method. Is there any better approach?
#RequestMapping(method = RequestMethod.GET)
public ModelAndView showNames() {
...
ModelAndView model = new ModelAndView("names");
model.addObject ....
return model;
}
#RequestMapping(value = "/name/{name}", method = RequestMethod.GET)
public ModelAndView showNameDetails(#PathVariable String name) {
...
ModelAndView model = new ModelAndView("name");
model.addObject ...
return model;
}
#RequestMapping(value = "/name/{name}/{item}", method = RequestMethod.GET)
public ModelAndView showItemsOfName(#PathVariable String name,
#PathVariable String item) {
...
ModelAndView model = new ModelAndView("item");
model.addObject ....
return model;
}
You can ask Spring to inject the Model for you, and then return the view name from the method, e.g.
#RequestMapping(method = RequestMethod.GET)
public String showNames(Model model) {
...
model.addObject ....
return "names";
}
#RequestMapping(value = "/name/{name}", method = RequestMethod.GET)
public String showNameDetails(#PathVariable String name, Model model) {
...
model.addObject ...
return "name";
}
#RequestMapping(value = "/name/{name}/{item}", method = RequestMethod.GET)
public String showItemsOfName(#PathVariable String name,
#PathVariable String item, Model model) {
...
model.addObject ....
return "item";
}
It's a bit cleaner, and less code.

Categories