I am pretty new to Spring MVC so please be easy on me.
I am having difficulties to understand how to achieve the following requirements in Spring MVC:
userList.jsp
<spring:url value="strFormAction" var="/rest/security/user/list" />
<form:form id="userListForm" method="GET" action="${strFormAction}" modelAttribute="user">
<form:select id="strRegionId" path="${strRegionId}" cssClass="form-control" onchange="updateUsersList('1');">
<spring:message var="strSelectRegionLabel" code="select.region" />
<form:option value="0" label="${strSelectRegionLabel}" />
<form:options items="${regions}" itemValue="intId" itemLabel="strNameFr" />
</form:select>
<form:select id="strArchived" path="${strArchived}" cssClass="form-control">
<spring:message var="strYesLabel" code="yes" />
<form:option value="true" label="${strYesLabel}"/>
<spring:message var="strNoLabel" code="no" />
<form:option value="false" label="${strNoLabel}"/>
</form:select>
<table>
...
<c:forEach items="${users}" var="user">
...rows generated here...
</c:forEach>
...
</table>
</form:form>
UserController.java
@RequestMapping(value = "/list", method = RequestMethod.GET)
public String processUserList( @ModelAttribute("user") User user,
@RequestParam(value = "strRegionId", required = false) String strRegionId,
@RequestParam(value = "strArchived", required = false) String strArchived,
@RequestParam(value = "strSortBy", required = false) String strSortBy,
Model model) {
int intRegionId = strRegionId != null && strRegionId.equals("0") == false ? Integer.valueOf(strRegionId) : 0;
boolean booArchived = strArchived != null && strArchived.length() > 0 ? Boolean.valueOf(strArchived) : false;
int intSortBy = strSortBy != null && strSortBy.length() > 0 ? Integer.valueOf(strSortBy) : 1;
List<Region> regions = this.locationService.lstRegions();
model.addAttribute("strRegionId", String.valueOf(intRegionId));
model.addAttribute("strArchived", String.valueOf(booArchived));
model.addAttribute("strSortBy", String.valueOf(intSortBy));
List<User> users = this.securityService.listUsersByRegionAndArchiveState(intRegionId, booArchived, intSortBy);
model.addAttribute("user", new User());
model.addAttribute("users", users);
model.addAttribute("regions", regions);
return "user/userList";
}
It seems like I can't use the Spring form taglib at all without providing a modelAttribute in the form. I have then placed a dummy modelAttribute from my controller, but now I get:
javax.servlet.ServletException: javax.servlet.jsp.JspException: org.springframework.beans.NotReadablePropertyException: Invalid property '0' of bean class [spring4base.model.security.User]: Bean property '0' is not readable or has an invalid getter method: Does the return type of the getter match the parameter type of the setter?
As I said earlier, that page is not meant to be backed by any specific POJO. This is a search page, that must return a list of users (User entity bean) based on filters selected previously (region, archived state). Form must submit on itself every time a dropdown is changed (user chooses a region, submit is done on the same mapping, and then the users list reloads with only users from that specific region).
I'm coming from Struts 1 in which we needed to create ActionForm for every single page. From what I read from the documentation, forms are not necessary these days so I am really looking forward into fixing that issue.
Any help would be greatly appreciated.
I would just create helper class containing your search criteria, for instance:
public class UserSearchCriteria {
private String regionId;
private Boolean archived;
private String sortBy;
// Getters and setters
}
Then I would modify your controller method like so (some code is missing, but this should give you the idea).
@RequestMapping(value = "/list", method = RequestMethod.GET)
public String processUserList(@ModelAttribute("searchCriteria") UserSearchCriteria userSearchCriteria, Model model) {
// Retrieve users and perform filtering based on search criteria
List<User> users = this.securityService.listUsers(searchCriteria);
model.addAttribute("users", users);
model.addAttribute("regions", regions);
return "user/userList";
}
And then you would use your filtering form like this:
<spring:url value="/rest/security/user/list" var="formAction" />
<form:form id="userListForm" method="GET" action="${formAction}" modelAttribute="searchCriteria">
<form:select path="regionId" cssClass="form-control" onchange="updateUsersList('1');">
<spring:message var="strSelectRegionLabel" code="select.region" />
<form:option value="0" label="${strSelectRegionLabel}" />
<form:options items="${regions}" itemValue="intId" itemLabel="strNameFr" />
</form:select>
<form:select path="archived" cssClass="form-control">
<spring:message var="strYesLabel" code="yes" />
<form:option value="true" label="${strYesLabel}"/>
<spring:message var="strNoLabel" code="no" />
<form:option value="false" label="${strNoLabel}"/>
</form:select>
You had several errors in the form in your snippet. For example the path
attribute takes String containing name (or path) of the property to bind to, you were passing it some variable. Also you had value
and var
switched in your <spring:url>
I think.
Try it, it's not complete solution but hopefully it will give you some directions on how to implement this. If you run into any problems, leave a comment and I'll update the answer.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With