Thymeleaf form - how to pass a value for model attribute from one controller method to another one - spring-boot

I'm struggling with adding products into product table for a specific user, whiich is logged via log method. The issue is that the attribue userLogin loses his value and is not equal to the user who logged into. So the actual value for attribute userLogin in addProduct method is null, hence there is an exception.
#RequestMapping("/home")
public String home(Model model) {
model.addAttribute("customer", new Customer());
model.addAttribute("userLogin", new Customer());
return "register";
}
#PostMapping("/save")
public String save(#ModelAttribute(value = "customer") #Valid Customer customer, BindingResult bindingResult) {
if (bindingResult.hasErrors()) {
throw new NotValidInputException();
}
if (customerService.checkIfCustomerIsInDb(customer)) {
throw new CustomerAlreadyExists();
}
customerService.saveCustomerIntoDb(customer);
return "saved";
}
#ExceptionHandler(NotValidInputException.class)
public String notValidInputExceptionHandler() {
return "databaseError";
}
#ExceptionHandler(CustomerAlreadyExists.class)
public String customerAlreadyInDbHandler() {
return "customerError";
}
#RequestMapping("/log")
public String login(Model model, #ModelAttribute(name = "userLogin") Customer customerFromLoginForm) {
if (Objects.isNull(customerService.getUserByLoggingDetails(customerFromLoginForm))) {
return "userNotFound";
}
model.addAttribute("product", new Product());
return "logged";
}
#PostMapping(value = "/addProduct")
public String addProduct(#ModelAttribute("userLogin") Customer customerFromLoginForm, #ModelAttribute(value = "product") Product product) {
// customer is null
customerFromLoginForm = customerService.findCustomerById(customerFromLoginForm.getId());
product.setCustomer(customerFromLoginForm);
customerFromLoginForm.setProducts(Arrays.asList(product));
productService.addProduct(product);
return "logged";
}
The form in logged. html
<form th:method="post" th:action="#{addProduct}" th:object="${product}">
<input type ="text" th:field="*{name}" placeholder="Name" /><br />
<input type ="text" th:field="*{category}" placeholder="Category" /><br />
<input type="number" th:field="*{price}" placeholder="Price" /><br />
<input style="text-align: center" type="submit" value="Add Product" /> </form>
Not sure what I'm missing here

See this answer: Not able to pass model Attribute passed from controller to thymeleaf html back to another controller .
In general, I would use a hidden input for it, e.g:
<input type ="hidden" th:name="userLogin" th:value="${userLogin}" />
Then your controller method should get it. Let me know if this helps.

Related

check if Team exists in the database or the input field is empty

It is necessary to check if the input fields for Team are empty, and whether there is such a Team in the repository.
If the field is not empty and there is no such Team, then you can create a new Team. If the field is empty or Team already exists, then give an error
AdminController
#Controller
public class AdminController {
#RequestMapping(value = "/admin/team", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
public String addTeam(Model model, #ModelAttribute("teamForm") #Validated TeamForm teamForm,
BindingResult result, final RedirectAttributes redirectAttributes) {
System.out.println("addTeam invoked");
if (result.hasErrors()) {
return "/admin";
}
Team newTeam = new Team();
newTeam.setName(teamForm.getName());
newTeam.setUrl(teamForm.getUrl());
teamRepository.save(newTeam);
return "teamList";
}
#RequestMapping(value = "/admin", method = RequestMethod.GET)
public String adminPage(Model model) {
model.addAttribute("teamForm",new TeamForm());
model.addAttribute("eventForm",new EventForm());
model.addAttribute("usersForm",new UsersForm());
return "admin";
}
admin.html
<form th:action="#{/admin/team}"
th:object="${teamForm}" method="POST">
Team name:
<input type="text" th:field="*{name}" />
<p th:if="${#fields.hasErrors('name')}" th:errors="*{name}">Incorrect Name</p>
<br/>
Url :
<input type="text" th:field="*{url}" />
<br/>
<input type="submit" value="Create Team" />
</form>

Thymeleaf input type="date" can not display and update

I can't find the right way to display the "birthday" field from datbase!
Even when i try to submit the new value to db, it doesn't work. What i'm doing wrong?
Here is my code:
Controller
#RequestMapping(value = {"/settings"}, method = RequestMethod.GET)
public ModelAndView settings() {
ModelAndView model = new ModelAndView();
model.addObject("user", user);
model.addObject("countries", getListOfCountries());
model.setViewName("user/settings");
return model;
}
#RequestMapping(value = {"/settings"}, method = RequestMethod.POST)
public ModelAndView updateUserGeneralSettings(#ModelAttribute User user) {
ModelAndView model = new ModelAndView();
userService.update(user);
model.addObject("user", user);
model.addObject("countries", getListOfCountries());
model.setViewName("user/settings");
return model;
}
HTML
<form method="POST" th:action="#{/settings}" th:object="${user}">
<div>
</div>
...
...
<div class="costum-field">
<label for="dateOfBirth" th:text="#{field.dateOfBirth}"></label>
<input type="date" id="dateOfBirth" class="form-control" th:field="*{dateOfBirth}"/>
</div>
...
...
<div>
</div>
</form
View in browser
So, as you can see all fields are working properly. Please suggest what is my mistake.

Post method in spring controller is not working

I have developed a form in jsp and in the form if user clicks submit button then the controller should capture the parameters but unfortunately it is not working.
/*<form action="http://localhost:8080/school" method="POST">*/
<form action="/school" method="POST">
School name: <input type="text" id="school" name="school" />
<input type="hidden" value="${firstName}" name = "firstName"/>
<input type="hidden" value="${lastName}" name = "lastName"/>
<input type="submit" value="Submit" />
</form>
The controller function is like this:
#RequestMapping(value = "/school", method = RequestMethod.POST)
public void setSchool(HttpServletRequest request,HttpServletResponse response){
String firstName= request.getParameter("firstName");
String lastName= request.getParameter("lastName");
String school= request.getParameter("school");
String status = userController.setSchool(firstName, lastName, school);
try {
if(!status.equals("SUCCESS")) {
response.sendError(HttpServletResponse.SC_FORBIDDEN, status);
}
response.sendRedirect("http://localhost:8080/getInsideSchool?school="+school+"&firstName="+firstName+"&lastName="+lastName);
} catch (IOException e) {
e.printStackTrace();
}
}
When i click on submit button in the form i cannot reach the controller function. How do i map url or fix this issue?
Thank you
<form action="/school" method="POST">
First create a POJO
class User {
private String school;
private String firstName;
private String lastName;
// getter setter constructor
}
Then write the controller method as following
#RequestMapping(value = "/school", method = RequestMethod.POST)
public String home(#ModelAttribute User user) {
System.out.println(user.toString());
return "redirect:/home";
}

Spring form binding return null with many-2-one relationship

Here is the problem, when I try to submit form, user entity returns null.
Form is
<form:form class="g-form" modelAttribute="objView" id="userAssignmentForm">
<form:hidden path="id" value="${objView.id}"/>
${objView.user.id}
<div class="g-form-group required">
<label for="user">User</label>
<form:hidden id="user" path="user" value="${objView.user}"/>
<input type="text" value="${objView.user.userName}" readonly="true"/>
<input type="button" class="import-input" onclick="gImport.showImportUserForm()"/>
</div>
Controller is
#RequestMapping(value = "/create", method = RequestMethod.POST)
public #ResponseBody
String create(
#ModelAttribute("objView") UserAssignmentView objView, BindingResult result,
SessionStatus status,
HttpServletRequest request) throws UnsupportedEncodingException {
UserAssignment obj = new UserAssignment();
obj.setUser(objView.getUser());
userAssignmentService.create(obj);
return "ok";
}
Model is below contains a view entity. What am I missing?
public class UserAssignmentView extends UserAssignment {
public UserAssignmentView() {
}
public UserAssignmentView(UserAssignment obj) {
setId(obj.getId());
setStatus(obj.getStatus());
setUser(obj.getUser());
}
}
And this is form view part of controller
#RequestMapping(value = "/form", method = RequestMethod.POST)
public ModelAndView form(HttpServletRequest request) {
UserAssignment obj = new UserAssignment();
Account account = AccountRegistry.getByHttpSession(request.getSession());
ModelAndView modelAndView = new ModelAndView("forms/userAssignmentForm");
modelAndView.addObject("objView", UserAssignmentWrapper.wrap(obj));
return modelAndView;
}
I could not solve since 3 days, how can I set user to userassignment?

Spring MVC Form Validation - The request sent by the client was syntactically incorrect

I am trying to add form validations to a working application. I started by adding a NotNull check to Login Form. I am using Hibernate impl of Bean Validation api.
Here's the code I have written
#Controller
#RequestMapping(value="/login")
#Scope("request")
public class LoginController {
#Autowired
private CommonService commonService;
#Autowired
private SiteUser siteUser;
#InitBinder
private void dateBinder(WebDataBinder binder) {
SimpleDateFormat dateFormat = new SimpleDateFormat("dd-MM-yyyy");
CustomDateEditor editor = new CustomDateEditor(dateFormat, true);
binder.registerCustomEditor(Date.class, editor);
}
#ModelAttribute
protected ModelMap setupForm(ModelMap modelMap) {
modelMap.addAttribute("siteUser", siteUser);
return modelMap;
}
#RequestMapping(value="/form", method = RequestMethod.GET)
public ModelAndView form(ModelMap map){
if (siteUser.getId() == null){
map.addAttribute("command",new SiteUser());
return new ModelAndView("login-form",map);
}else {
return new ModelAndView("redirect:/my-dashboard/"+siteUser.getId());
}
}
#RequestMapping(value="/submit", method=RequestMethod.POST)
public ModelAndView submit(#Valid SiteUser user, ModelMap map, BindingResult result){
if (result.hasErrors()) {
map.addAttribute("command", user);
System.out.println("Login Error block");
return new ModelAndView("login/form",map);
}
else {
User loggedInUser = commonService.login(user.getEmail(), user.getPassword());
if (loggedInUser != null) {
siteUser.setId(loggedInUser.getId());
siteUser.setName(loggedInUser.getName());
System.out.println("site user attr set");
}
return new ModelAndView("redirect:/my-dashboard/"+loggedInUser.getId());
}
}
}
The Model is
#Component
#Scope("session")
public class SiteUser {
private Integer id = null;
#NotNull
private String name = null;
private String email = null;
private String password = null;
private List<String> displayPrivList = null;
private List<String> functionPrivList = null;
// And the getters and setters
}
The JSP is
<c:url var="loginSubmitUrl" value="/login/submit"/>
<form:form method="POST" action="${loginSubmitUrl}">
<form:errors path="*" />
<div class="row">
<div class="span4">
</div>
<div class="span4">
<h3>Please Login</h3>
<label><span style="color:red">*</span>Email</Label><form:input path="email" type="text" class="input-medium" />
<label><span style="color:red">*</span>Password</Label><form:input path="password" type="password" class="input-medium" />
<br/>
<button type="submit" class="btn btn-primary">Login</button>
<button type="button" class="btn">Cancel</button>
</div>
</div>
</form:form>
I have added messages.properties and the annotation driven bean def in the context xml.
Other answers on the subject talk about form fields not getting posted. In my case, that's the expected behavior - that if I submit a blank form, I should get an error.
Please advise what am I missing?
I think this question had the same issue as yours
Syntactically incorrect request sent upon submitting form with invalid data in Spring MVC (which uses hibernate Validator)
which just points out
You have to modify the order of your arguments. Put the BindingResult result parameter always directly after the parameter with the #Value annotation
You need this: <form:errors path="email" cssClass="errors" />
Use the tag form:errors for each input with the same "path" name.
It is also possible to list all the error at the same time if you don't put a path.
Here, check an full example with sample code that you can download to learn how to do:
http://www.mkyong.com/spring-mvc/spring-3-mvc-and-jsr303-valid-example/
Can you try changing the <form:form> by including the commandName to it like this
<form:form method="POST" action="${loginSubmitUrl}" commandName="user">

Resources