How to display this message from custom class type annotation in Spring as a warning message in HTML form? I am using Spring Boot MVC and Thymeleaf. Thymeleaf can handle field errors and global errors that are not associated with any specific fields in the form, but still exist. If this custom annotation finds that passwords don't match is this global error or field error? How can I show this message?
Custom annotation:
#Target({ TYPE, ANNOTATION_TYPE })
#Retention(RUNTIME)
#Constraint(validatedBy = PasswordMatchesValidator.class)
#Documented
public #interface PasswordMatches {
String message() default "Passwords don't match";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
Validator class:
public class PasswordMatchesValidator implements ConstraintValidator<PasswordMatches, Object> {
#Override
public void initialize(PasswordMatches passwordMatches) {
}
#Override
public boolean isValid(Object obj, ConstraintValidatorContext context) {
UserDto userDto = (UserDto) obj;
return userDto.getPassword().equals(userDto.getMatchingPassword());
}
}
Post Controller
#PostMapping(value = "/register")
public ModelAndView processRegistration(ModelAndView modelAndView, #Valid #ModelAttribute ("userDto") UserDto userDto,
BindingResult bindingResult, HttpServletRequest request, Errors errors) {
// Lookup user in database by e-mail
User userExists = userService.findByEmail(userDto.getEmail());
System.out.println(userExists);
if (userExists != null) {
modelAndView.addObject("alreadyRegisteredMessage", "Oops! There is already a user registered with the email provided.");
modelAndView.setViewName("register");
bindingResult.reject("email");
}
if (bindingResult.hasErrors()) {
modelAndView.setViewName("register");
} else { // new user so we create user and send confirmation e-mail
User user = userService.createNewAccount(userDto);
user.setEnabled(false);
userService.saveUser(user);
modelAndView.addObject("confirmationMessage", "A confirmation e-mail has been sent to " + userDto.getEmail());
modelAndView.setViewName("registered");
}
}
HTML form:
<div class="container">
<div class="row">
<div class="card col-6 mx-auto" style="width: 20rem; margin: 20px;">
<div class="card-body">
<h4 class="card-title">Registration form:</h4>
<form th:action="#{register}" th:object="${userDto}" th:method="post" method="post" action="register">
<div class="form-group">
<label th:for="name" for="Name">Name</label>
<input type="text" class="form-control" th:field="*{name}" id="name" placeholder="Enter name">
<p class="text-danger" th:if="${#fields.hasErrors('name')}" th:errors="*{name}"></p>
</div>
<div class="form-group">
<label th:for="surname" for="Surname">Surname</label>
<input type="text" class="form-control" th:field="*{surname}" id="surname" placeholder="Enter surname">
<p class="text-danger" th:if="${#fields.hasErrors('surname')}" th:errors="*{surname}"></p>
</div>
<div class="form-group">
<label th:for="username" for="Username">Username</label>
<input type="text" class="form-control" th:field="*{username}" id="username" placeholder="Enter username">
<p class="text-danger" th:if="${#fields.hasErrors('username')}" th:errors="*{username}"></p>
</div>
<div class="form-group">
<label th:for="email" for="Email">Email address</label>
<input type="email" class="form-control" th:field="*{email}" id="email" aria-describedby="emailHelp" placeholder="Enter email">
<small id="emailHelp" class="form-text text-muted">We'll never share your email with anyone else.</small>
<p class="text-danger"th:if="${#fields.hasErrors('email')}" th:errors="*{email}"></p>
<p class="text-danger" th:text="${alreadyRegisteredMessage}"></p>
</div>
<div class="form-group">
<label th:for="password" for="Password">Password</label>
<input type="password" class="form-control" th:field="*{password}" id="password" placeholder="Password">
<p class="text-danger"th:if="${#fields.hasErrors('password')}" th:errors="*{password}"></p>
</div>
<div class="form-group">
<label th:for="matchingPassword" for="matchingPassword">Confirm Password</label>
<input type="password" class="form-control" th:field="*{matchingPassword}" id="matchingPassword" placeholder="Password">
<p class="text-danger"th:if="${#fields.hasErrors('matchingPassword')}" th:errors="*{matchingPassword}"></p>
</div>
<button type="submit" class="btn btn-primary">Submit</button>
</form>
</div>
</div>
</div>
</div>
You can customize the PasswordMatchesValidator class to display the warning message.
public class PasswordMatchesValidator implements ConstraintValidator<PasswordMatches, Object> {
private String message;
#Override
public void initialize(PasswordMatches passwordMatches) {
this.message = passwordMatches.message();
}
#Override
public boolean isValid(Object obj, ConstraintValidatorContext context) {
final UserDto userDto = (UserDto) obj;
boolean isValid = userDto.getPassword().equals(userDto.getMatchingPassword());
if (!isValid) {
context.disableDefaultConstraintViolation();
context
.buildConstraintViolationWithTemplate( message )
.addPropertyNode( "matchingPassword" ).addConstraintViolation();
}
return isValid;
}
}
The solution is to include global errors Thymeleaf syntax in HTML form. But for some reason single quote in this message: "Passwords don't match", doesn't get rendered. The answer to this problem is here.
Related
I'm working on a registration form in Spring Boot and thymeleaf but it's not submitting to the database. I even run the debugger mood and it did not hit the endpoints for the registration. Note, that my login and other functionalities work fine. I'm following this here to create my registration
How to I get this endpoint to create a new user?
register.html
<form th:action="#{/registration}" th:object="${user}" method="post">
<p class="error-message" th:if="${#fields.hasGlobalErrors()}"
th:each="error : ${#fields.errors('global')}" th:text="${error}">Validation
error</p>
<div class="form-group"
th:classappend="${#fields.hasErrors('firstName')}? 'has-error':''">
<label for="firstName" class="control-label">First name</label> <input
id="firstName" class="form-control" th:field="*{firstName}" />
<p class="error-message"
th:each="error: ${#fields.errors('firstName')}"
th:text="${error}">Validation error</p>
</div>
<div class="form-group"
th:classappend="${#fields.hasErrors('lastName')}? 'has-error':''">
<label for="lastName" class="control-label">Last name</label> <input
id="lastName" class="form-control" th:field="*{lastName}" />
<p class="error-message"
th:each="error : ${#fields.errors('lastName')}"
th:text="${error}">Validation error</p>
</div>
<div class="form-group"
th:classappend="${#fields.hasErrors('email')}? 'has-error':''">
<label for="email" class="control-label">E-mail</label> <input
id="email" class="form-control" th:field="*{email}" />
<p class="error-message"
th:each="error : ${#fields.errors('email')}" th:text="${error}">Validation
error</p>
</div>
<div class="form-group"
th:classappend="${#fields.hasErrors('username')}? 'has-error':''">
<label for="email" class="control-label">Username</label> <input
id="email" class="form-control" th:field="*{username}" />
<p class="error-message"
th:each="error : ${#fields.errors('username')}" th:text="${error}">Validation
error</p>
</div>
<div class="form-group"
th:classappend="${#fields.hasErrors('password')}? 'has-error':''">
<label for="password" class="control-label">Password</label> <input
id="password" class="form-control" type="password"
th:field="*{password}" />
<p class="error-message"
th:each="error : ${#fields.errors('password')}"
th:text="${error}">Validation error</p>
</div>
<!--
<div class="form-group">
<button type="submit" class="btn btn-success">Register</button>
<span>Already registered? <a href="/" th:href="#{/login}">Login
here</a></span>
</div>
-->
<div class="form-group">
<button type="submit" class="btn btn-success">Register</button>
</div>
</form>
controller.java
#Controller
public class RegisterationController {
#Autowired
private UserService userService;
#GetMapping("/register")
public String getRegisterPage(ModelMap model) {
User user = new User();
model.put("user", user);
return "register";
}
#PostMapping("/registration")
public String postRegister(#RequestBody User user, BindingResult result) {
User existingUser = userService.findByEmail(user.getEmail());
if(existingUser != null) {
result.rejectValue("email", null, "this email is already used");
}
if (result.hasErrors()) {
return "register";
}
userService.saveNewUser(existingUser);
return "redirect:/";
}
}
UserService.java
public void saveNewUser(User user) {
User nuser = new User();
nuser.setUsername(user.getUsername());
nuser.setEmail(user.getEmail());
nuser.setPassword(user.getPassword());
nuser.setFirstName(user.getFirstName());
nuser.setLastName(user.getLastName());
// TODO: is this how you set the role of the user?
nuser.setRoles((Set<Role>) Arrays.asList(new Role("user")));
userRepository.save(nuser);
}
I solved this problem by changing two things; first, I created a custom saveNewUser() but JPA manages that better so I changed that to this.
UserService.java
public User save(User user) {
user.setRoles(new HashSet<Role> (Arrays.asList(new Role("user"))));
return userRepository.save(user);
}
I also had to change my endpoint to this
controller.java
#PostMapping("/register")
public String postRegister(User user) {
BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
String encodedPassword = passwordEncoder.encode(user.getPassword());
user.setPassword(encodedPassword);
userService.save(user);
return "redirect:/";
}
I have User class So I created UserValidator.java using Validator interface of Spring for validation of User while registration.
Problem is that validations are applied successfully but jsp page does not show the error messages.
UserValidator.java
#Component
public class UserValidator implements Validator {
public boolean supports(Class<?> clazz) {
return User.class.equals(clazz);
}
public void validate(Object obj, Errors errors) {
ValidationUtils.rejectIfEmpty(errors, "userName", "Enter a valid name");
ValidationUtils.rejectIfEmpty(errors, "address", " Enter Address");
ValidationUtils.rejectIfEmpty(errors, "mobNo", "Enter valid mobile number");
ValidationUtils.rejectIfEmpty(errors, "emailId", "Enter a valid email");
User user = (User) obj;
System.out.println(""+user.getUserName());
Pattern pattern = Pattern.compile("^[A-Z0-9._%+-]+#[A-Z0-9.-]+\\.[A-Z]{2,6}$",
Pattern.CASE_INSENSITIVE);
if (!(pattern.matcher(user.getEmailId()).matches())) {
errors.rejectValue("emailId", "Invalid email! Please enter valid email");
}
}}
RegistrationController.java
#Controller
public class RegistrationController {
#Autowired
UserValidator userValidator;
#InitBinder
public void initBinder(WebDataBinder webDataBinder){
webDataBinder.setValidator(userValidator);
}
#Autowired
private DepartmentDao departmentDao;
#Autowired
private DesignationDao designationDao;
#Autowired
private ConfigDao configDao;
#Autowired
private HintQuestionDao hintQuestionDao;
#Autowired
private GroupDao groupDao;
#Autowired
private UserDao userDao;
#RequestMapping("Register")
public String getRegisterPage(#ModelAttribute("user") User user, Model model) {
model.addAttribute("departmentList", departmentDao.getDepartments());
model.addAttribute("designationList", designationDao.getDesignation());
model.addAttribute("levelList", configDao.getLevel());
model.addAttribute("questionList",hintQuestionDao.getQuestions());
model.addAttribute("groupList", groupDao.getGroup());
return "Registration";
}
#RequestMapping("newRegisterUser")
public String createUser(#ModelAttribute("user") User user, Model model,#RequestParam("deptId") int deptid,
#RequestParam("desgId") int desgId,#RequestParam("grpId")int grpId,HttpSession session, BindingResult bindingResult) throws Exception{
User userSess= (User) session.getAttribute("userObj");
if(userSess!=null) {
userValidator.validate(user, bindingResult);
if (bindingResult.hasErrors()) {
return "redirect:Register";
}
user.setMobNo(user.getMobNo());
user.setDepartment(departmentDao.getDepartmentById(deptid));
user.setDesignation(designationDao.getDesignationById(desgId));
user.setGroup(groupDao.getGroupById(grpId));
user.setUpw1(user.getUserName().replace(" " , "").substring(0,4)+user.getEmailId().substring(0,2)+"#"+user.getMobNo().toString().substring(8));
user.setCreatedBy(userSess.getUserName());
user.setCreationDate(new Timestamp(System.currentTimeMillis()));
user.setLoginStatus("A");
userDao.createUser(user);
}
else {
model.addAttribute("AddMessage","Login First");
}
return "redirect:ListOfUser";
}}
Registration.jsp
<form:form class="form" modelAttribute="user" method="post" action="newRegisterUser">
<div class="form-group row">
<label class="col-lg-3 col-form-label form-control-label">Name:</label>
<div class="col-lg-9">
<form:input class="form-control" type="text" path="userName"/>
<form:errors path = "userName" cssClass = "error" />
</div>
</div>
<div class="form-group row">
<label class="col-lg-3 col-form-label form-control-label">Address:</label>
<div class="col-lg-9">
<form:textarea class="form-control" rows="2" path="address"></form:textarea>
<form:errors path = "address" cssClass = "error" />
</div>
</div>
<div class="form-group row">
<label class="col-lg-3 col-form-label form-control-label">Mobile:</label>
<div class="col-lg-3">
<form:input class="form-control" type="text" path="mobNo"/>
</div>
<label class="col-lg-2 col-form-label form-control-label">Email:</label>
<div class="col-lg-4">
<form:input class="form-control" type="email" path="emailId"/>
<form:errors path = "emailId" cssClass = "error" />
</div>
</div>
<div class="form-group row">
<label class="col-lg-3 col-form-label form-control-label">Department:</label>
<div class="col-lg-3">
<select name="deptId" id="dept_Id" class="form-control" size="0">
<option value="0">--Select--</option>
<c:forEach var="depts" items="${departmentList}">
<option value="<c:out value="${depts.deptid}" />">${depts.deptnm}</option>
</c:forEach>
</select>
</div>
<label class="col-lg-2 col-form-label form-control-label">Designation:</label>
<div class="col-lg-4">
<select name="desgId" id="design_Id" class="form-control" size="0">
<option value="0">--Select--</option>
<c:forEach var="desig" items="${designationList}">
<option value="<c:out value="${desig.desgid}" />">${desig.desgnm}</option>
</c:forEach>
</select>
</div>
</div>
<div class="form-group row">
<label class="col-lg-3 col-form-label form-control-label">Level:</label>
<div class="col-lg-3">
<select name="userLevel" id="lvl_Id" class="form-control" size="0">
<option value="-1">--Select--</option>
<c:forEach var="levelList" items="${levelList}">
<option value="<c:out value="${levelList.sk}"/>">${levelList.ds}</option>
</c:forEach>
</select>
</div>
<label class="col-lg-2 col-form-label form-control-label">Group:</label>
<div class="col-lg-4">
<select name="grpId" id="grp_Id" class="form-control" size="0">
<option value="-1">--Select--</option>
<c:forEach var="groupList" items="${groupList}">
<option value="<c:out value="${groupList.grpid}" />">${groupList.grpnm}</option>
</c:forEach>
</select>
</div>
</div>
<div class="form-group row">
<label class="col-lg-3 col-form-label form-control-label">Hint Question:</label>
<div class="col-lg-3">
<select name="hintId" id="que_Id" class="form-control" size="0">
<option value="0">--Select--</option>
<c:forEach var="questionList" items="${questionList}">
<option value="<c:out value="${questionList.hintid}" />">${questionList.hintquestion}</option>
</c:forEach>
</select>
</div>
<label class="col-lg-2 col-form-label form-control-label">Answer:</label>
<div class="col-lg-4">
<form:input class="form-control" type="text" path="hintAns"/>
</div>
</div>
<div class="form-group row">
<label class="col-lg-5 col-form-label form-control-label"></label>
<div class="col-lg-7">
<input type="submit" class="btn btn-info" value="Register">
<input type="reset" class="btn btn-primary" value="Cancel">
</div>
</div>
</form:form>
Can anybody help me out?
What i did wrong in this?
Thank you in advance.
I am writing form that lets user to change his password. Instead of passing User object to form, I am passing 3 empty Strings. Everything is okay, but when I am passing Submit, Strings returns as empty. Is there any way to get String from forms in Spring without packaging them into objects like changePasswordForm with 3 String fields?
My code:
Change password view:
<!DOCTYPE html>
<html lang="en"
xmlns:th="http://www.thymeleaf.org">
<head th:replace="/fragments/head"></head>
<body>
<div class="container">
<div th:replace="/fragments/header"> </div>
<div class="jumbotron">
<h1 class="display-4">Changing password</h1>
<form action="#" th:action="#{/user/changePassword/} + ${user.id}" method="post">
<div class="form-group">
<label>Current password</label>
<input type="password" th:field="${currentPassword}" class="form-control" placeholder="Your current password"/>
</div>
<div class="form-group">
<label>New password</label>
<input type="password" th:field="${newPassword}" class="form-control" placeholder="Your new password"/>
</div>
<div class="form-group">
<label>New password confirmation</label>
<input type="password" th:field="${newPasswordConfirmation}" class="form-control" placeholder="Confirm your new password"/>
</div>
<button class="btn btn-primary">Submit</button>
<button class="btn btn-secondary">Reset</button>
</form>
</div>
<div th:replace="/fragments/footer"> </div>
</div>
</body>
</html>
User controller:
package io.gromo13.personalBlog.controller;
import io.gromo13.personalBlog.service.RoleService;
import io.gromo13.personalBlog.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;
import io.gromo13.personalBlog.model.User;
import javax.validation.Valid;
#Controller
#RequestMapping("/user")
#SessionAttributes("user")
public class UserController {
#Autowired
UserService userService;
#Autowired
RoleService roleService;
public void setUserService(UserService userService) {
this.userService = userService;
}
public void setRoleService(RoleService roleService) {
this.roleService = roleService;
}
#GetMapping("/{id}")
public String profile(#PathVariable Long id, Model model) {
User user = userService.get(id);
model.addAttribute("user", user);
return "/user/profile";
}
#GetMapping("/register")
public String register(Model model) {
model.addAttribute("roles", roleService.getAll());
model.addAttribute("user", new User());
return "/user/register";
}
#PostMapping("/register")
public String registerSubmit(#Valid User user, BindingResult bindingResult) {
if (bindingResult.hasErrors())
return "/user/register";
userService.add(user);
return "redirect:/admin/users";
}
#GetMapping("/edit/{id}")
public String edit(#PathVariable Long id, Model model) {
User user = userService.get(id);
model.addAttribute("user", user);
model.addAttribute("password", "");
return "/user/edit";
}
#PostMapping("/edit/{id}")
public String editSubmit(#ModelAttribute("user") #Valid User user, BindingResult bindingResult) {
if (bindingResult.hasErrors())
return "/user/edit";
userService.edit(user);
return "redirect:/admin/users";
}
#GetMapping("/changePassword/{id}")
public String changePasword(Model model) {
model.addAttribute("currentPassword", "");
model.addAttribute("newPassword", "");
model.addAttribute("newPasswordConfirmation", "");
return "/user/changePassword";
}
#PostMapping("/changePassword/{id}")
public String changePasswordSubmit(#PathVariable Long id,
#ModelAttribute("currentPassword") String currentPassword,
#ModelAttribute("newPassword") String newPassword,
#ModelAttribute("newPasswordConfirmation") String newPasswordConfirmation,
BindingResult bindingResult) {
if (bindingResult.hasErrors())
return "/user/changePassword";
User user = userService.get(id);
if (newPassword.equals(newPasswordConfirmation) && user.getPassword().equals(currentPassword)) {
user.setPassword(newPassword);
userService.edit(user);
}
return "redirect:/admin/users";
}
#GetMapping("/delete/{id}")
public String delete(#PathVariable Long id) {
userService.delete(id);
return "redirect:/admin/users";
}
}
Actually my whole page is working fine, I just cannot read single Strings passed to forms without wrapping to objects.
Every tutorial about forms in Spring I found is passing object like xForm or User to view and read them. It works for me too, but I do not see sense in creating special object just for single form.
change th:field to name tag
<!DOCTYPE html>
<html lang="en"
xmlns:th="http://www.thymeleaf.org">
<head th:replace="/fragments/head"></head>
<body>
<div class="container">
<div th:replace="/fragments/header"> </div>
<div class="jumbotron">
<h1 class="display-4">Changing password</h1>
<form action="#" th:action="#{/user/changePassword/} + ${user.id}" method="post">
<div class="form-group">
<label>Current password</label>
<input type="password" name="currentPassword" class="form-control" placeholder="Your current password"/>
</div>
<div class="form-group">
<label>New password</label>
<input type="password" name="newPassword" class="form-control" placeholder="Your new password"/>
</div>
<div class="form-group">
<label>New password confirmation</label>
<input type="password" name="newPasswordConfirmation" class="form-control" placeholder="Confirm your new password"/>
</div>
<button class="btn btn-primary">Submit</button>
<button class="btn btn-secondary">Reset</button>
</form>
</div>
<div th:replace="/fragments/footer"> </div>
</div>
</body>
</html>
remove this from controller
#GetMapping("/changePassword/{id}")
public String changePasword(Model model) {
model.addAttribute("currentPassword", ""); //remove
model.addAttribute("newPassword", ""); //remove
model.addAttribute("newPasswordConfirmation", ""); //remove
return "/user/changePassword";
}
and here change ModelAttribute to RequestParam Annotation
#PostMapping("/changePassword/{id}")
public String changePasswordSubmit(#PathVariable Long id,
#RequestParam("currentPassword") String currentPassword,
#RequestParam("newPassword") String newPassword,
#RequestParam("newPasswordConfirmation") String newPasswordConfirmation) {
this sentence bindingResult not work because this validate a POJO using validations annotations
//if (bindingResult.hasErrors())
// return "/user/changePassword";
for this case the best way is create a new POJO with those fields and then validate them.
if you want to use the validation you need to create a POJO and add the constraints.
1)
public class ChangePass {
#Size(min = 8,max = 13, message = "error current password between {min} to {max}")
private String currentPassword;
#Size(min = 8,max = 13,message = "error new password between {min} to {max}")
private String newPassword;
//validate later
private String newPasswordConfirmation;
}
2)
then you need to add a instance of this POJO in the view.
#GetMapping("/changePassword/{id}")
public String changePasword(Model model) {
model.addAttribute("userPass", new ChangePass()); // adding model
return "/user/changePassword";
}
3)
in your form you need to fix 2 things add
th:object="${userPass}" and add th:field="*{currentPassword}" not th:field="${currenctPassword}" the difference is " * "
<form th:action="#{/user/changePassword/} + ${user.id}" method="post" th:object="${userPass}">
<div class="form-group">
<label>Current password</label>
<input type="password" th:field="*{currentPassword}" class="form-control" placeholder="Your current password"/>
</div>
<div class="form-group">
<label>New password</label>
<input type="password" th:field="*{newPassword}" class="form-control" placeholder="Your new password"/>
</div>
<div class="form-group">
<label>New password confirmation</label>
<input type="password" th:field="*{newPasswordConfirmation}" class="form-control" placeholder="Confirm your new password"/>
</div>
<button class="btn btn-primary">Submit</button>
<button class="btn btn-secondary">Reset</button>
</form>
4)
and the Post Method should be...
#PostMapping("/changePassword/{id}")
public String changePassword(#PathVariable Long id,
#ModelAttribute("userPass"),
#Valid ChangePass change,
BindingResult errors){
if(errors.hasErrors()){
return "/user/changePassword";
}
//your next code
I'm creating a simple CRUD in Spring Boot+Thymeleaf and all other CRUD on application work well but this one. When I submit the form, the object comes with empty attributes to controller.
In the following, the code:
Artist.java
#Entity
public class Artist {
#Id
#GeneratedValue
private Long id;
#Column(nullable=false, length = 80)
private String artistName;
<getters and setters>
ArtistController.java
#Controller
public class ArtistController {
#Autowired
ArtistRepository artistRepository;
#GetMapping("/artist/add")
public String addArtist(Model model) {
model.addAttribute("artist", new Artist());
return "artist/form_artist";
}
#PostMapping("/artist/save")
public String artistSave(#ModelAttribute(name="artist") Artist artist) {
artistRepository.save(artist);
return "redirect:/artist";
}
}
And now, the form:
<form action="#" th:action="#{/artist/save}" th:object="${artist}" method="post" class="form-horizontal">
<div class="form-group">
<label for="id" >HobbyOn id:</label>
<input type="text" id="id" th:field="*{id}" readonly="readonly" class="form-control" placeholder="hobbyOn ID" />
</div>
<div class="form-group">
<label for="artistName" >Artist Name:</label>
<input type="text" th:field="*{artistName}" class="form-control" required="required" />
</div>
<div class="form-group">
<input class="btn btn-primary" type="submit" value="Submit" />
</div>
</form>
I can't see any difference from examples in internet and in my own code. Any help will be very welcomed.
Here is my code.When I check checkbox and click the edit button the value is fetched correctly.But edited value is not updated in mysql database as well as table.I'm using jdbc template for this example."location" field is select option value.
controller get the checkbox value and fetch data from database.after that the updated value is not shown in the table.
HomeController.java
#RequestMapping("/edit")
public String update(Model model,#RequestParam Map<String,String> req){
updateValue = new Integer(req.get("checkId"));
List<Users> users = userdao.getUpdateRecord(updateValue);
model.addAttribute("result",users);
return "formedit";
}
#RequestMapping("/saveUpdate")
public String saveUpdate(Model model,#RequestParam Map<String,String> req){
String name,storage,location,address;
name = req.get("name");
storage=req.get("storage");
location=req.get("location");
address = req.get("address");
int row = userdao.updateRecord(updateValue,name,storage,location,address);
String message = row+ "updated";
model.addAttribute("message", message);
result(model);
return "home";
}
UsersDAO doesn't get the update value from formedit page.
UsersDAO.java
public List<Users> getUpdateRecord(int updateValue){
System.out.println("update value"+updateValue);
String sql="select id,name,storage,location,address from customer where id="+updateValue;
return jdbc.query(sql,new UsersMapper());
}
public int updateRecord(int id,String name,String storage,String location,String address){
return jdbc.update("update customer set name = ?,storage = ?,location = ?,address=? where id = ?",id,name,storage,location,address);
formedit.jsp
<form role="form" action="saveUpdate" method="post" class="form-horizontal">
<c:forEach var="row" items="${result}">
<div class="row">
<div class="col-md-6">
<div class="form-group">
<label class="control-label col-xs-4 text">Customer Name</label>
<div class="col-xs-8">
<input type="text" class="form-control" name="name" value=${row.name }>
</div>
</div>
<div class="form-group">
<label class="control-label col-xs-4 text">Storage Location*</label>
<div class="col-xs-8">
<input type="text" class="form-control" name="storage" value=${row.storage }>
</div>
</div>
</div>
<div class="col-md-6">
<div class="form-group">
<label class="control-label col-xs-4 text">Location</label>
<div class="col-xs-8">
<input type="text" class="form-control" name="location" value=${row.location }>
</div>
</div>
<div class="form-group">
<label class="control-label col-xs-4 text">Customer Address</label>
<div class="col-xs-8">
<textarea class="form-control" name="address">${row.address }</textarea>
</div>
</div>
</div>
<input type="submit" class="btn btn-success btn-md col-md-offset-6" value="Update">
</div>
</c:forEach>
</form>
}
Because this is wrong:
return jdbc.update("update customer set name = ?,storage = ?,location = ?,address=? where id = ?",id,name,storage,location,address);
The parameters order is incorrect, it doesnt find id with value address.