SpringMVC Form validation with form:options - spring

I am trying to setup Form Validation in Spring, therefore I am using javax.validation Annotations. This works pretty well, it gets the Errors pretty well.
I have a form:options Field in my Form that gets precalculated Values from my Controller, but if you submit wrong data, these precalculated Values get lost.
The form looks like this:
<form:form method="post" action="../add" commandName="new-booking"
modelAttribute="new-booking" class="form-vertical">
<table>
<tr>
<td><form:label path="numberOfBikesBooked">Anzahl der Fahrräder</form:label><font
color='red'><form:errors path='numberOfBikesBooked' /></font></td>
</tr>
<tr>
<td><form:select path="numberOfBikesBooked">
<form:options items="${possibleBikeValues}" />
</form:select></td>
</tr>
<tr>
<td><form:label path="firstName">Vorname</form:label><font
color='red'><form:errors path='firstName' /></font></td>
</tr>
<tr>
<td><form:input path="firstName" /></td>
</tr>
<tr>
<td><form:label path="lastName">Nachname</form:label><font
color='red'><form:errors path='firstName' /></font></td>
</tr>
<tr>
<td><form:input path="lastName" /></td>
</tr>
<tr>
<td><form:label path="mailAddress">Email</form:label><font
color='red'><form:errors path='mailAddress' /></font></td>
</tr>
<tr>
<td><form:input path="mailAddress" /></td>
</tr>
<tr>
<td><input type='submit' value='Buchen!' class="btn" /></td>
</tr>
</table>
<form:hidden path="Date" />
<form:hidden path="cancelURI" />
</form:form>
The Controller like this (the add validates the Form and the AvailableBikes renders the Form):
#RequestMapping(value = "/add", method = RequestMethod.POST)
public String addPerson(#ModelAttribute("new-booking") #Valid Booking booking,
BindingResult result, Map<String, Object> model) {
if(result.hasErrors()){
return "booking";
}
logger.info(String.format("Adding a Booking with the following data: Name: %s %s Email: %s Date: %s", booking.getFirstName(), booking.getLastName(), booking.getMailAddress(), booking.getDate()));
bookingService.addBooking(booking);
model.put("booking", booking);
return "success";
}
#RequestMapping(value = "/AvailableBikes", method = RequestMethod.POST)
public String getAvailableBikes(#ModelAttribute("date") StringDate parDate,
Map<String, Object> model) {
// Parse Date
DateFormat dateFormat = new SimpleDateFormat("dd-MM-yy");
Date inDate = Calendar.getInstance().getTime();
try {
inDate = dateFormat.parse(parDate.getDate());
} catch (ParseException e) {
logger.severe(e.getMessage());
e.printStackTrace();
}
logger.info(String.format("Listing the available Bookings for the %s", inDate));
int availableBookings = bookingService.getAvailableBookings(inDate);
model.put("NumAvailableBikes", Integer.toString(availableBookings));
// TODO: Fix this with the AvailableBikesRange
List<Integer> allPossibleBikeValues = new ArrayList<Integer>();
for (int i = 1; i <= 30; i++) {
allPossibleBikeValues.add(i);
}
model.put("possibleBikeValues", allPossibleBikeValues);
// Get ready for new booking
Booking booking = new Booking();
booking.setDate(inDate);
// TODO: How to handle the Cancel?
booking.setCancelURI("xyz");
model.put("new-booking", booking);
return "booking";
}
Here is the Model (I think this won't matter):
#Entity
public class Booking {
#Id
#GeneratedValue
private Integer id;
#Column(name = "date", nullable = false)
#NotNull
private Date date;
#Column(name = "numberOfBikesBooked", nullable = false)
#Min(1)
#Max(100)
private int numberOfBikesBooked;
#Column(name = "mailAddress", nullable = false)
#Email
private String mailAddress;
#Column(name = "firstName", nullable = false)
#NotBlank
#Size(min=3, max=100)
private String firstName;
#Column(name = "lastName", nullable = false)
#NotBlank
#Size(min=3, max=100)
private String lastName;
#Column(name = "cancelURI", nullable = true)
private String cancelURI;

The problem with the firstName is that you have two form:input for it :) The second must be mailAddress.
The problem with precalculated values is simple: when you return the view name string, controller does not get called. The model for this case is empty. The are several solutions: you can extract precalculation to a method and call it where you need. Or (I prefer this way) you can set up interceptors to populate model for urls:
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/context-relative-url.html" />
<bean class="a.b.c.DropDownPopulator" />
</mvc:interceptor>
</mvc:interceptors>
And the populator:
public class DropDownPopulator extends HandlerInterceptorAdapter {
#Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
Map<String, String> result = new LinkedHashMap<String, String>(/*map for dropdown*/);
modelAndView.addObject("values", result);
}
}

Related

Field is always null in Spring Boot Postmapping method

I want to bind my HTML table with all fields to Java code in Spring Boot.
Therefore, I have annotated my method with Postmapping, too.
I was already able to show all the fields in Thymeleaf and I was also able to set the checkBox value ( true / false ) accordingly.
This is my Thymeleaf HTML code:
<form action="#" th:action="#{/mitarbeiterverwaltung}" th:object="${users}" method="post">
<fieldset>
<table border="1" align="center">
<thead>
<tr>
<!-- <th:text = "#{mitarbeiterverwaltung.active}>Active ( Tick ) / Passive</th>-->
<th>Active ( Tick ) / Passive</th>
<th>ID</th>
<th>Username</th>
<th>Anzeigename</th>
<th>Dienstnummer</th>
</tr>
</thead>
<tbody>
<tr th:each="user, itemStat : *{users}">
<td><input th:field="*{users[__${itemStat.index}__].isActive}"
th:checked="${user.isActive}"
class="checkBox"
type="checkBox"
name="checkBox"
/></td>
<td><input th:field="*{users[__${itemStat.index}__].id}"
readonly/></td>
<td><input th:field="*{users[__${itemStat.index}__].username}"
readonly/></td>
<td><input class="anzeigename"
type="text"
name="anzeigename"
th:field="*{users[__${itemStat.index}__].anzeigename}"
th:id="${itemStat.index}"
readonly/></td>
<td><input class="dienstnummer"
type="text"
name="dienstnummer"
th:field="*{users[__${itemStat.index}__].dienstnummer}"
th:id="${itemStat.index}"
readonly/></td>
</tr>
</tbody>
</table>
<br />
<div style="text-align:center;">
<input type="submit" id="submitButton" th:value="Speichern"/>
</div>
</fieldset>
And this is my Java code, where the field isActive of UserCreationDto is always null.
#PostMapping
public String updateActivePassiveUser(#ModelAttribute UserCreationDto userTableSettings,
#RequestParam("checkBox") String checkBoxName, BindingResult result, Model model, Errors errors) {
logger.info("Method {} called in {}", new Object() {}.getClass().getEnclosingMethod().getName(), this.getClass().getName());
if (errors.hasErrors()) {
logger.error("Error in {}", new Object() {}.getClass().getEnclosingMethod().getName());
return "error";
}
List<Benutzer> users = userManagementServiceImpl.getAllUsers();
userManagementServiceImpl.updateActivePassiveUser(1, 0);
return "redirect:/mitarbeiterverwaltung?success";
}
Here is a picture of the field in Java code where the method is annotated with #PostMapping
And so does my #RequestMapping look like:
This is my #RequestMapping method:
#RequestMapping
public String showUserManagement(Model model) {
logger.info("Method {} called in {}", new Object() {}.getClass().getEnclosingMethod().getName(), this.getClass().getName());
List<Benutzer> users = userManagementServiceImpl.getAllUsers();
userForm = userManagementServiceImpl.saveUserForm(users);
model.addAttribute("users", userForm);
return "mitarbeiterverwaltung";
}
My UserCreationDto where all the fields get added to a list:
public class UserCreationDto {
private List<User> users = new ArrayList<>();
public void addUser(User user) {
this.users.add(user);
}
public List<User> getUsers() {
return users;
}
public void setUsers(List<User> users) {
this.users = users;
}
}
And my simple POJO class with all the fields
#Data
public class User {
//#SafeHtml prevents XSS ( Cross-Site Scripting )
#SafeHtml
private String username;
private String password;
private String anzeigename;
private String dienstnummer;
private long id;
private Boolean isActive;
}
The other fields like anzeigename, dienstnummer, id, and username are filled within my Java code, however, isactive is always null.
Maybe, someone can tell me what I am doing wrong here.
Thank you very much in advance.
I think you have to many options set. You don't need th:checked:
<input th:field="*{users[__${itemStat.index}__].isActive}"
class="checkBox"
type="checkBox"
name="checkBox" />
I found another way now, but it is not really nice.
#PostMapping
public String updateActivePassiveUser(#Valid #ModelAttribute("userForm") UserCreationDto userTableSettings,
#RequestParam List<String> searchValues, BindingResult result, Model model, Errors errors) {
The field searchValues contains all the checkBoxes that are ticked.
This is my view:
<td><input type="checkbox"
name="searchValues"
th:value="${user.id}"
th:checked="${user.isActive}"
/>
Now, the only problem that I am having is how to update my column that is of type Boolean in Postgresql?
For accomplishing this task I call this:
userRepo.updateActivePassiveUser(new Boolean("False"), id);
#Modifying
#Query(value = "UPDATE benutzer SET active = :active WHERE id = :id", nativeQuery = true)
#Transactional
void updateActivePassiveUser(#Param("active") Boolean active, #Param("id") long id);
However, the value in my database never changes.
Maybe, someone could give me a last hint, please!

Spring 4 mvc RedirectView with BindingResult errors and RedirectAttributes and ModelAttribute

I have controller (POST|GET) and jsp view form (add person)
how can I make a redirect if I have a mistake - to see errors on the page in the fields INPUT ? bindingResult.hasErrors() == true ?
if ok i see success FlashAttribute
if i have error i see FlashAttribute error but i don't see mistake fields INPUT
#RequestMapping(
value = "/addUserProfile",
method = RequestMethod.GET
)
public ModelAndView addUserProfile() {
ModelAndView modelAndView = new ModelAndView(VIEW_ADD_USER_PROFILE);
return modelAndView;
}
#ModelAttribute("userProfile")
UserProfile userProfile() {
return new UserProfile();
}
and view addUserProfile.jsp
<form:form id="data" action="/addUserProfile" method="POST" modelAttribute="userProfile" commandName="userProfile">
<p><pre><code>${errorMessage}</code></pre></p>
<p><pre><code>${id}</code></pre></p>
<p><pre><code>${successMessage}</code></pre></p>
<table>
<tr>
<td><form:label path="phone">phone</form:label></td>
<td><form:input path="phone"/></td>
<td><form:errors path="phone" cssClass="error"/></td>
</tr>
<tr>
<td><form:label path="firstname">firstname</form:label></td>
<td><form:input path="firstname"/></td>
<td><form:errors path="firstname" cssClass="error"/></td>
</tr>
<!--submit -->
<tr>
<td><input type="submit" value="submit"/></td>
</tr>
</table>
</form:form>
Howto redirect to
#RequestMapping(
value = "/addUserProfile",
method = RequestMethod.POST
)
public RedirectView addUserProfile(HttpServletRequest request,
#Valid #ModelAttribute("userProfile") UserProfile userProfile,
BindingResult bindingResult,
RedirectAttributes redirectAttrs) {
RedirectView redirectView = new RedirectView(request.getRequestURI());
if (bindingResult.hasErrors()) {
redirectAttrs.addFlashAttribute("errorMessage","error");
redirectView.setContextRelative(true);
} else {
redirectAttrs.addFlashAttribute("successMessage","success");
long id = userService.add(userProfile);
redirectAttrs.addFlashAttribute("id",id);
}
return redirectView;
}
Validate object form
public class UserProfile {
#NotEmpty
#Size(min = 9, max = 20)
private String phone;
#NotEmpty
#Size(min = 3, max = 20)
private String firstname;
}

Spring MVC #Valid not working when form is binded to a list

I am trying to do form validations on a Spring MVC form binded to a list of objects. The validations are not working. Please let me know if I am missing something
#Component
public class Customer{
#NotEmpty private int custId;
#NotEmpty private List<Order> orders;
//Getters & Setters...
}
#Component
public class Order{
#NotEmpty private String id;
#NotEmpty private String orderName;
//Getters & Setters...
}
//JSP - custFormBean is set as a model attribute
<form:form method="post" action="/submitOrder.htm" modelAttribute="custFormBean">
<table class="activity" width="600px" bgcolor="#FCF4DE">
<c:forEach items="${custForm.orders}" var="order" varStatus="status">
<tr>
<td>
<c:out value="${order.id}" />
</td>
</tr>
<tr>
<td>
<form:password path="orders[${status.index}].orderName" name="name" />
</td>
<td><form:errors path="orders[${status.index}].orderName" cssClass="errorMessage" /></td>
</tr>
</c:forEach>
<tr></tr>
<tr>
<td align="center" colspan="2">
<input type="submit" id="orderSubmit" class="formButton" value="OK" />
</td>
</tr>
</table>
</form:form>
//Controller
#Controller
#SessionAttributes("custFormBean")
public class CustomerController {
#RequestMapping(value = "/order.htm", method=RequestMethod.GET)
public String getOrder(ModelMap model, HttpServletRequest request) {
nextPage = "order"
try {
Customer custBean = custService.getCustOrders(...);
model.addAttribute("custFormBean", custBean);
} catch (ServiceException e) {
log.error("ServiceException when calling getChallengeQuestionLists", e);
}
return nextPage;
}
#RequestMapping(value = "/submitOrder.htm", method=RequestMethod.POST)
public String submitOrder(#Valid #ModelAttribute("custFormBean") Customer custBean, BindingResult result, Model model, HttpServletRequest request){
String nextPage = "success";
if(result.hasErrors()) {
//This is not working - The custBean is populated with the values entered in the form but if I leave the fields empty the validation is not kicking in.
log.debug("Validation errors...");
nextPage = "error";
}
return nextPage;
}
}
Please let me know if I am missing something
From Hibernate Validator javadoc of #NotEmpty:
Check that a String is not empty (not null and length > 0) or that a
Collection (or array) is not empty (not null and length > 0)
I think your list is not null and has length > 0 although all of them are blanks. So according to this the validator probably kicked it and yielded correct result.
You may need to write custom validator that checks there's at least a non-blank element in the list?

Spring Validator for duplicate record in database

In my page jsp, i have a form where i can add a user to my database, and i use a validator to show errors when fields are empty, but what i want to do is, when i insert a duplicate entry of the primary key of my table, the validator show me a message that this login for example is already taken instead having an error by Apache!
this is my User POJO :
package gestion.delegation.domaine;
import java.io.Serializable;
public class User implements Serializable{
/**
*
*/
private static final long serialVersionUID = 1L;
int id;
String nom;
String prenom;
String login;
String password;
String role;
boolean enable;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getNom() {
return nom;
}
public void setNom(String nom) {
this.nom = nom;
}
public String getPrenom() {
return prenom;
}
public void setPrenom(String prenom) {
this.prenom = prenom;
}
public String getLogin() {
return login;
}
public void setLogin(String login) {
this.login = login;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public boolean getEnable() {
return this.enable;
}
public void setEnable(boolean enable) {
this.enable = enable;
}
public User(int id, String nom, String prenom, String login,
String password, String role, boolean enable) {
super();
this.id = id;
this.nom = nom;
this.prenom = prenom;
this.login = login;
this.password = password;
this.role = role;
this.enable = enable;
}
public String getRole() {
return role;
}
public void setRole(String role) {
this.role = role;
}
public User() {
super();
}
}
and this is my validator :
package gestion.delegation.validator;
import gestion.delegation.domaine.User;
import org.springframework.validation.Errors;
import org.springframework.validation.ValidationUtils;
import org.springframework.validation.Validator;
public class AddUserValidator implements Validator{
#Override
public boolean supports(Class<?> clazz) {
return User.class.isAssignableFrom(clazz);
}
#Override
public void validate(Object obj, Errors err) {
ValidationUtils.rejectIfEmptyOrWhitespace(err, "nom", "name.required","Choisissez un nom");
ValidationUtils.rejectIfEmptyOrWhitespace(err, "prenom", "prenom.required", "Choisissez un prenom");
ValidationUtils.rejectIfEmptyOrWhitespace(err, "login", "login.required", "Choisissez un login");
ValidationUtils.rejectIfEmptyOrWhitespace(err, "password", "password.required", "Choisissez un password");
ValidationUtils.rejectIfEmpty(err, "role", "role.required", "Choisissez un role");
}
}
the form :
<c:if test="${not empty msg_success}">
<div class="success">Vous avez ajouter un utilisateur avec
succès !</div>
</c:if>
<form:form name="ajf"
action="${pageContext.request.contextPath}/ajouter_user"
method="post" commandName="user">
<table id="tabmenu">
<tr>
<td id="idtab">Nom :</td>
<td><form:input type="text" path="nom"
class="round default-width-input" name="name_" /></td>
<td><form:errors path="nom" Class="errorbox" /></td>
</tr>
<tr>
<td id="idtab">Prénom :</td>
<td><form:input type="text" path="prenom" name="prenom_"
class="round default-width-input" /></td>
<td><form:errors path="prenom" cssClass="errorbox" />
</tr>
<tr>
<td id="idtab">Login :</td>
<td><form:input type="text" path="login" name="login_"
cssClass="round default-width-input" /></td>
<td><form:errors path="login" cssClass="errorbox" /></td>
</tr>
<tr>
<td id="idtab">Password :</td>
<td><form:input type="password" path="password" name="pass_"
class="round default-width-input" /></td>
<td><form:errors path="password" cssClass="errorbox" /></td>
</tr>
<tr>
<td id="idtab">Séléctionner un rôle :</td>
<td><form:select path="role">
<form:option value="" label="" />
<form:option value="ROLE_ADMIN">Administrateur</form:option>
<form:option value="ROLE_USER">Simple utilisateur</form:option>
</form:select></td>
<td><form:errors path="role" cssClass="errorbox" /></td>
</tr>
<tr>
<td id="idtab">Activé :</td>
<td><form:input type="checkbox" value="true" path="enable" />
Oui</td>
</tr>
<tr></tr>
<tr></tr>
<tr>
<td><input
class="button round blue image-right ic-right-arrow"
type="submit" value="Créer" /></td>
<td><input
class="button round blue image-right ic-right-arrow"
type="reset" value="Initialiser" /></td>
</tr>
</table>
</form:form>
Any Idea?
I'm afraid that a Validator will not be sufficient in this case. Although you could extend your AddUserValidator class to check whether the given user name is free, it will not
work in a situation in which two users simultaneously try to register using the same user name - the validation will pass, however one of the users will get an error from the database.
To protect yourself against such situations I would place the registration logic in a try catch block and in case of an error display a proper message to the user. This would be kind of an application-level validation.
Spring validator simply checks your object in accordance with the prescribed rules before you bring it into the database. It does not know anything about the database. To display the error that occurred while working with a database, you need to catch the exception manually.
In your Controller Just Check the duplication by querying from Model Repository.
#Model Entity
#Table(name = "people")
public class People {
#Column(name = "nic")
#NotEmpty(message = "*Please provide your nic")
private String nic;
#Repository
public interface PeopleRepository extends JpaRepository<People, Integer>{
People findByNic(String nic);
}
#Controller
#RequestMapping(value = "/welcome", method = RequestMethod.POST)
public ModelAndView createNewPeople(Model model,, BindingResult bindingResult) {
ModelAndView modelAndView = new ModelAndView();
People peopleExistsEmail = peopleService.findUserByNic(people.getNic());
if (peopleExistsEmail != null) {
bindingResult
.rejectValue("nic", "error.people",
"There is already a person registered with the nic provided");
}
if (bindingResult.hasErrors()) {
modelAndView.setViewName("welcome");
} else {
peopleService.savePeople(people);
modelAndView.addObject("successMessage", "People has been registered successfully");
modelAndView.addObject("people", new People());
} catch (Exception e) {
e.printStackTrace();
}
}
return modelAndView;
}
So this is the Right Answer :
The method in DAO class implementation is like that :
public boolean AddUser(User user) {
boolean t=true;
final String User_INSERT1 = "insert into utilisateurs (login, password, nom, prenom,enable) "
+ "values (?,?,?,?,?)";
final String User_INSERT2="insert into roles (login,role) values(?,?)";
/*
* On récupère et on utilisera directement le jdbcTemplate
*/
MessageDigestPasswordEncoder encoder = new MessageDigestPasswordEncoder("SHA");
String hash = encoder.encodePassword(user.getPassword(), "");
final String check ="select count(*) from utilisateurs where login = ?";
int result= getJdbcTemplate().queryForInt(check, new Object[]{String.valueOf(user.getLogin())});
if (result==0) {
getJdbcTemplate()
.update(User_INSERT1,
new Object[] {user.getLogin(),
hash, user.getNom(),
user.getPrenom(), user.getEnable(),
});
getJdbcTemplate().update(User_INSERT2, new Object[]{user.getLogin(),user.getRole()});
return t;
}
else { t = false ; return t;}
}
The controller :
#RequestMapping(value ="/ajouter_user", method = RequestMethod.POST)
public String add(#ModelAttribute User us,BindingResult result,ModelMap model) {
AddUserValidator uservalid=new AddUserValidator();
uservalid.validate(us, result);
if (result.hasErrors()) {
model.addAttribute("usersystem", userservice.getAllUsers());
return "gestionUser";
}else {
boolean e = userservice.AddUser(us);
if (e==false){
model.addAttribute("msg_failed","true");
}
else {
model.addAttribute("msg_success","true");}
model.addAttribute("usersystem", userservice.getAllUsers()); /*verifier*/
return "gestionUser";
}
}
And for showing the error in the jsp file :
<c:if test="${not empty msg_failed}">
<div class="errorblock">Il existe déjà un utilisateur avec cet login </div>
</c:if>
The method in DAO class implementation is like that :
public final long insert(final User user) throws MyException {
String sql = "INSERT INTO users ....";
String chkSql = "SELECT count(*) FROM users WHERE username=:username";
Map namedParams = new HashMap();
namedParams.put("username", user.getUsername());
long newId = namedTemplate.queryForInt(chkSql, namedParams);
if (newId > 0) {
try {
throw new MyException(-1);
} catch (MyException e) {
throw e;
}
}
newId = ...;// could be generated if not inc field or triggered...
namedParams.put("username", user.getUserName());
...
...
namedParams.put("id", newId);
namedTemplate.update(sql, namedParams);
return newId;
}
MyException like that:
public class MyException extends Exception{
private static final long serialVersionUID = 1L;
int a;
public MyException(int b) {
a=b;
}
}
Controller:
#RequestMapping(value = "/user", method = RequestMethod.POST)
public final ModelAndView actionUser(
final ModelMap model,
#ModelAttribute("myitemuser") #Valid final User user,
final BindingResult bindResult,
...);
...
try {
userService.addUser(user); // or dao... ;)
} catch (Exception e) {
UserValidator userValidator = new UserValidator();
userValidator.custError(bindResult);
}
UserValidator like that:
...
#Override
public final void validate(final Object object, final Errors errors) {
User user = (User) object;
...
if (user.getPassword().isEmpty()) {
errors.rejectValue("password", "error.users.emptypass");
}
}
public final void custError(final Errors errors){
errors.rejectValue("username"/* or login */, "error.users.uniqname");
}
...
Ну как то так))))

why value of ModelMap attribute getting changed in jsp?

i have a controller given below:
#Controller
#SessionAttributes("user")
public class UserController {
#Autowired
AdminDaoInterface adminDao;
#Autowired
UserValidator userValidator;
#RequestMapping(value="userdetails.htm",method=RequestMethod.GET)
public String userDetails(ModelMap model) {
UserCommand userDetailsCmd = new UserCommand();
model.addAttribute("userDetailsCmd", userDetailsCmd);
return "UserDetails"; // will go to UserDetails.jsp
}
#RequestMapping(value="userdetails.htm",method = RequestMethod.POST)
public String userDetailsSubmit(
#ModelAttribute("userDetailsCmd") UserCommand userDetailsCmd,
Errors errors, ModelMap model){
//user will contains details of user found from database.
User user=adminDao.getUserOnId(userDetailsCmd.getUserId());
if(user==null) {
errors.rejectValue("userId", "user.not.exists");
return "UserDetails";
}
model.addAttribute("user",user);
return "ChangeUserDetails"; // will go to ChangeUserDetails.jsp
}
#RequestMapping(value="changeuserdetails.htm",method = RequestMethod.POST)
public String changeUserDetails(
#ModelAttribute("userDetailsCmd") UserCommand userDetailsCmd,
#ModelAttribute("user") User user){
// some stuff...
// BOTH user and userDetailsCmd OBJECTS HAVE A FIELD "userType"
// HERE user.userType SHOULD CONTAIN VALUE COLLECTED FROM DB (already
// existing value)
// AND userDetailsCmd.userType SHOULD CONTAIN VALUE SELECTED IN JSP IN
//ORDER TO UPDATE EXISTING VALUE of user.userType.
...
//BUT WHEN I SET VALUE OF userDetailsCmd.userType IN JSP, WHY VALUE OF
// user.userType GOT CHANGED ALWAYS TO THAT VALUE???
...
// somewhere later in code i m setting user.userType to
//userDetailsCmd.userType to update value.
adminDao.updateUser(user);
return "ChangeUserSuccess";
}
}
ChangeUserDetails.jsp is:
<form:form method="post" action="changeuserdetails.htm" commandName="userDetailsCmd">
<table>
<tr>
<td>User Id :</td>
<td>${user.userId}</td>
</tr>
<tr>
<td>Project :</td>
<td>${user.projectId} </td>
<td>Change To:</td>
<td>
<form:select path="projectId">
<form:option value="-1" label="SELECT"/>
<form:options items="${projectList}" itemValue="pid"
itemLabel="projectName"/>
</form:select>
</td>
</tr>
<tr>
<td>User Type :</td>
<td>${user.userType}</td>
<td>Change To:</td>
<td>
<form:select path="userType">
<form:option value="not changed" label="SELECT"/>
<form:option value="admin" label="Admin" />
<form:option value="user" label="User" />
</form:select>
</td>
</tr>
<tr>
<td colspan="2">
<input type="submit" value="Change User Details"/>
</td>
</tr>
</table>
</form:form>
why value of user.userType always got changed when i set/change value of command object userDetailsCmd (userDetailsCmd.userType) in jsp?
is this because both have same attribute name (userType)?
EDIT:
UserCommand class (command object)is :
public class UserCommand{
private String userId;
private String password;
private int projectId;
private String userType;
private int listUserId;
private List usersList;
//PLUS getters and setters for these fields...
}
And User class (a POJO )is:
public class User{
private String userId;
private String password;
private int projectId;
private String userType;
//PLUS getters and setters for these fields...
}
#InitBinder("user")
public void userBinding(DataBinder binder) {
binder.setDisallowedFields("userType");
}
Add this to your controller and the userType field of the User object will not get populated.

Resources