here is the addVariable.jsp
<h3>Add Process Variable</h3>
<br>
<form:form action="/cpms/vrms/add" commandName="processVariable">
<table>
<tr>
<td>Variable Name </td>
<td><form:input path="variableName" /></td>
</tr>
<tr>
<td>Symbol </td>
<td><form:input path="symbol" /></td>
</tr>
<tr>
<td>Description </td>
<td><form:textarea path="variableDescription" rows="3" cols="20" /></td>
</tr>
<tr>
<td>Unit</td>
<td><form:input path="unit" /></td>
</tr>
<tr>
<td>Type</td>
<td>
<form:radiobuttons path="dataType" items="${dataTypes}"/>
</td>
</tr>
<tr>
<td>Source</td>
<td><form:radiobuttons path="source" items="${sourceList}"/></td>
</tr>
<tr>
<td>Is Input?</td>
<td>
<form:radiobuttons path="input" value="true" />
<form:radiobuttons path="input" value="false" />
</td>
</tr>
<tr>
<td>Is Constant?</td>
<td>
<form:radiobuttons path="constant" value="true"/> Yes
<form:radiobuttons path="constant" value="false"/> No
</td>
</tr>
<tr>
<td colspan="2">
<input type="submit" value="Add Variable" />
</td>
</tr>
</table>
The VariableManagementController
public class VariableManagementController {
#Autowired
private IVariableManagementService variableManagementService;
private static final String ADD_FORM_PATH="cpms/vrms/addVariable";
#RequestMapping(value="/cpms/vrms/add/form",method=RequestMethod.GET)
String addProcessVariable(Model model){
DATA_TYPE[] dataTypes = DATA_TYPE.values();
SOURCE[] sourceList = SOURCE.values();
model.addAttribute("dataTypes",dataTypes);
model.addAttribute("sourceList",sourceList);
model.addAttribute("processVariable", new ProcessVariable());
return ADD_FORM_PATH;
}
The ProcessVariable bean
public class ProcessVariable {
private String variableId;
private String variableName;
private String variableDescription;
private String symbol;
private String unit;
private DATA_TYPE dataType;
private SOURCE source;
private boolean constant; //if isConstant=true then isOutput must be false
private boolean input;
//getters and setters
When i hit a link with target http://localhost:9090/wcc/cpms/vrms/add/form i get following exception.
org.apache.jasper.JasperException: An exception occurred processing JSP page /WEB-INF/jsp/cpms/vrms/addVariable.jsp at line 46
43: <tr>
44: <td>Is Input?</td>
45: <td>
46: <form:radiobuttons path="input" value="true" />
47: <form:radiobuttons path="input" value="false" />
48: </td>
49: </tr>
.
.
.
root cause
java.lang.IllegalArgumentException: Attribute 'items' is required and must be a Collection, an Array or a Map
I dont want to add an attribute in my model from within the controller for boolean values. It should have worked like this. I am using spring mvc 3.1.2
I dont think so using items=${inputTypes} is mandatory. i can simply use hardcoded values for my boolean values
If you are not using a list use
<form:radiobutton />
eg.
<form:radiobutton path="sex" value="M"/>Male
<form:radiobutton path="sex" value="F"/>Female
Here is a post explaning something similar:
http://www.mkyong.com/spring-mvc/spring-mvc-radiobutton-and-radiobuttons-example/
Related
Can you have a #Initbinder on several data in the same form?
I have a spring form which contains a select dropdown of an object and two datafields, I have an Initbinder on the dates otherwise I get an error on submit. But I also need to bind the dropdown to an object.
I have a Type which has two dates and a Category, and it is the Category I need to bind because it can not be empty on save.
I think it will help me to validate the form to.
So can I have this in my Type controller?
#InitBinder
public void initBinder(WebDataBinder binder) {
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
dateFormat.setLenient(false);
binder.registerCustomEditor(Date.class, new CustomDateEditor(dateFormat, true));
binder.registerCustomEditor(Category.class, "category", new CategoryEditor(CategoryService));
}
And this is the Editor:
public class CategoryEditor extends PropertyEditorSupport {
private CategoryService categoryService;
public CategoryEditor(CategoryService categoryService) {
this.categoryService = categoryService;
}
#Override
public void setAsText(String text) throws IllegalArgumentException {
if (text.equals("0")) {
this.setValue(null);
} else {
Category sc = categoryService.getCategory(Integer.parseInt(text));
this.setValue(sc);
}
}
#Override
public String getAsText() {
Category parent = new Category();
if (this.getValue() != null) {
parent = (Category) this.getValue();
}
return "";
}
}
And my jsp-page
<s:url value="/mvc/type/save" var="actionUrl" />
<sf:form method="POST" modelAttribute="type" action="${actionUrl}">
<fieldset>
<legend><s:message code="${heading}" /></legend>
<table>
<tr>
<th><label for="category"><s:message code="category" />:</label></th>
<td><sf:select path="category.ID" id="category">
<sf:option value="0"> </sf:option>
<sf:options items="${listOfCategories}" itemLabel="name" itemValue="ID" />
</sf:select></td>
</tr>
<tr>
<th><label for="name"><s:message code="name" />:</label></th>
<td><sf:input path="name" id="name" />
<sf:hidden path="ID" />
<sf:hidden path="version" /></td>
</tr>
<tr>
<th><label for="marketing"><s:message code="marketing" />:</label></th>
<td><sf:input path="marketingFunction" id="marketing" /></td>
</tr>
<tr>
<th><label for="status"><s:message code="status" />:</label></th>
<td><sf:select path="lifeCycleStatus">
<sf:option value="0"> </sf:option>
<sf:options items="${listOfEnums}" />
</sf:select></td>
</tr>
<tr>
<th><label for="validfrom"><s:message code="validfrom" />:</label></th>
<td><sf:input path="validFrom" id="validfrom" /></td>
</tr>
<tr>
<th><label for="validuntil"><s:message code="validuntil" />:</label></th>
<td><sf:input path="validUntil" d="validuntil" /></td>
</tr>
<tr>
<td colspan="2">
<input id="saveButton" class="right" type="submit" title="<s:message code="save" />" value=" [ <s:message code="save" /> ] " />
</td>
</tr>
</table>
</fieldset>
</sf:form>
So my question: Can I have multiple binder in the same initBinder in my controller? It seems like I can't because I never enter the CategoryEditor. How do I do this?
There aren't multiple binders, there are multiple PropertyEditors.
Your custom one is never called because you are binding the wrong path.
<sf:select path="category.ID" id="category">
You must bind to category and not category.ID
<sf:select path="category" id="category">
On my 'update user' page I have a hidden field to hold the ID of the current user being edited. I've checked the HTML source and the value populates correctly. However when I submit the form, the userID value ALWAYS comes through as 0 while every other field comes through correctly.
-I've tried setting the type as form:input and submitting it, still 0 on the controller side.
-There are no bindingresult errors.
-Page URL: /admin/update-user.html?uid=3 (I've tried changing the URL variable from uid to userID, no difference.)
So what the heck is going on?! Am I missing something obvious??
JSTL
<form:form commandName="user" method="POST">
<form:hidden path="userID"/>
<table width="400" cellpadding="3" cellspacing="0" border="0" class="datatable">
<tr>
<td>User ID #</td>
<td>${user.userID}</td>
</tr>
<tr>
<td valign="top">Password</td>
<td>****<br />Change Password</td>
</tr>
<tr>
<td>First Name</td>
<td><form:input path="firstName" /></td>
</tr>
<tr>
<td>Last Name</td>
<td><form:input path="lastName" /></td>
</tr>
<tr>
<td>Gender: </td>
<td>
<form:select path="gender">
<form:option value="Male" label="Male" />
<form:option value="Female" label="Female" />
</form:select>
</td>
</tr>
<tr>
<td>Birthday: </td>
<td><form:input path="birthday" id="datepickerpast" readonly="true" /></td>
</tr>
<tr>
<td>Email</td>
<td><form:input path="email" /></td>
</tr>
<tr>
<td> </td>
<td><input type="submit" value="Update" /> <input type="reset"></td>
</tr>
</table>
</form:form>
Controller
#RequestMapping(value = "admin/update-user", method = RequestMethod.POST)
public String processUpdateUser(ModelMap model, #ModelAttribute("user") User user, BindingResult result) throws SQLException {
if (result.hasErrors()) {
model.addAttribute("user", user);
model.addAttribute("pagetitle", "Admin - Update User Details");
return "admin/users/update-user";
} else {
userDao.updateUser(user);
return "redirect:/admin/user-management.html";
}
}
Object Properties with appropriate getters/setters
private int userID;
private String firstName;
private String lastName;
private String username;
private String email;
private Date birthday;
private String gender;
Realized my getter was type Integer but my setter and property was type int. Made all of them Integer and it worked. If someone can explain why there was no error on compile or why it didn't work the way it was, that'd be greatly appreciated.
Sigh, there goes 3 hours of my life.
You got a compiler error because of autoboxing, which allows for the automatic conversion of primitives to their wrapper class alternatives. As to why it didn't work when the getter was using Integer, I can't help you there.
I am trying to create a jsp form for inputting the user information.
I am using a controller to display the input page.
I have added an User bean object with the modelmap.The controller returns the ModelandView object.
The problem lies here.No model value gets returned to the jsp page. Anybody know why this happens??please help me...
<context:annotation-config/>
<context:component-scan base-package="com.mobilize.rest"/>
<mvc:annotation-driven/>
<bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping"/>
<import resource="configuration/messageConverter.xml"/>
<import resource="configuration/viewResolveContext.xml"/>
The code below shows the controller used to get the view AddUSer.jsp page
While debugging the values are properly stored in the object.
But the problem is that the object doesnt get received at the form page.
#RequestMapping(value = "/AddUser.html", method = RequestMethod.GET)
public ModelAndView addUser(
#RequestParam(value = "reload", required = false, defaultValue = "false")
Boolean reload,
#RequestParam(value = "reset", required = false, defaultValue = "false")
Boolean reset,HttpServletRequest request) {
HttpSession httpSession = request.getSession();
ModelMap modelmap = new ModelMap();
Users users = new Users();
modelmap.addAttribute("users", users);
modelmap.addAttribute("MOB_USER_ADD_STATUS_SUCCESS_MESSAGE","trial");
return new ModelAndView("AddUser", modelmap);
}
[Edited, additional code moved from comment section]
<div id="content" style="height:508px"> <br/>
<c:if test="${MOB_USER_ADD_STATUS_SUCCESS_MESSAGE!=null}">
<div align="center"
id="statusIndicator"
class="successMessage">${MOB_USER_ADD_STATUS_SUCCESS_MESSAGE}
</div>
</c:if>
${MOB_USER_ADD_STATUS_SUCCESS_MESSAGE}
<form:form commandName="users"
method="POST"
action="AddUser.html">
<table>
<tr>
<td> User Name: </td>
<td><form:input path="userName"
id="username">
</form:input>
</td>
</tr>
<tr>
<td></td>
<td><form:errors path="userName"
cssClass="errorMessage">
</form:errors>
</td>
</tr>
<tr>
<td> Password: </td>
<td> <form:textarea path="password" id="password"></form:textarea> </td>
</tr>
<tr>
<td></td>
<td><form:errors path="password" cssClass="errorMessage"></form:errors></td>
</tr>
<tr>
<td></td>
<td> <input type="submit" name="offer" value=" Add "/>
<input type= "reset"
name="Reset"
value=" Reset "
onclick="document.location.href='AddUser.html?reset=true'"/>
</td>
</tr>
</table>
</form:form>
</div>
The mistake was i imported the wrong class. Instead of importing org.springframework.web.servlet.ModelAndView , i imported
org.springframework.web.portlet.ModelAndView. That was the reason for the error. I should have been a bit more careful.
I need to validate the objects which are stored in the list on my form bean object.
Below is my form bean object.
public class Role implements java.io.Serializable {
// Fields
private int roleId;
#NotBlank
private String roleName;
private boolean active;
#Valid
private List<Module> modules;
// getters anfd setters
}
and below is my object which is present in the list of my main form bean object
public class Module implements Serializable {
private int id;
#NotBlank
private String moduleName;
// other properties and getters and setters
}
Below is my properties file
# -- Role form --
NotBlank.role.roleName=Role Name can not be blank.
NotBlank.module.moduleName=Module Name can not be blank.
Below is My JSP page, the form consists of a role name and modules which can be added to the role.
<table border="0" class="section_tbl2">
<tr>
<td width="150px" valign="top">
<spring:message code="dmx.role.form.label.name"/>
</td>
<td width="10px">:</td>
<td>
<form:input class="txtinput" id="roleName" path="roleName" maxlength="50"/> <form:errors path="roleName" cssClass="error"/>
</td>
</tr>
<tr><td colspan="3" height="8px"></td></tr>
<tr>
<td width="150px" vAlign="top">
Modules
</td>
<td width="10px" vAlign="top">:</td>
<td>
<table>
<tr>
<td>
<input type="button" value="<spring:message code="dmx.role.form.button.addModule.label"/>" onclick="return addModuleRow();"></input>
</td>
</tr>
<tr><td> </td></tr>
</table>
<table cellpadding="0" cellspacing="0" border="0" class="tblstyle1" id="moduleTable">
<thead>
<tr>
<th class="fst" width="200px">
<spring:message code="dmx.role.form.label.moduleName"/>
</th>
<th width="50px"><spring:message code="dmx.role.form.label.create"/></th>
<th width="50px"><spring:message code="dmx.role.form.label.update"/></th>
<th width="50px"><spring:message code="dmx.role.form.label.delete"/></th>
<th width="30px"></th>
</tr>
</thead>
<tbody id="moduleTBody">
<c:forEach items="${role.modules}" var="module" varStatus="status" >
<c:set var="moduleCounter" value="${status.index}"/>
<tr id="moduleRowId_${moduleCounter}">
<td class="fst txt-center">
<form:select onchange="checkIfThisModuleAlreadySelected(this);" class="seloption" id="selectedModule_${moduleCounter}" path="modules[${moduleCounter}].id">
<form:option value="" label="-- Select Module --"/>
<form:options items="${moduleList}" itemLabel="moduleName" itemValue="id" />
</form:select>
</td>
<td class="txt-center">
<form:checkbox id="create_${moduleCounter}" path="modules[${moduleCounter}].create"/>
</td>
<td class="txt-center">
<form:checkbox id="update_${moduleCounter}" path="modules[${moduleCounter}].update"/>
</td>
<td class="txt-center">
<form:checkbox id="delete_${moduleCounter}" path="modules[${moduleCounter}].delete"/>
<td class="txt-center">
<input class="delbtn" id="moduleDelBtn_${moduleCounter}" name="moduleDelBtn[${moduleCounter}]" type="button" onclick="delModuleRow(${moduleCounter});">
</td>
</tr>
</c:forEach>
</tbody>
</table>
</td>
</tr>
<tr><td colspan="3" height="3px"></td></tr>
</table>
I can successfully validate the role name i.e. when role name is blank I get an error message but when module is not selected i do not get any error message.
Please help
Adding #NotNull and #Size constraints to your module list should help:
#Valid
#NotNull
#Size(min = 1)
private List<Module> modules;
The #Valid annotation causes the elements of the annotated collection to be validated but it doesn't validate wether that collection is not null or contains any elements.
Hi
Could someone help me understand what am I doing wrong in the following code due to which I am getting this error:
Caused by: java.lang.IllegalStateException: Neither BindingResult nor plain target object for bean name 'user' available as request attribute
at org.springframework.web.servlet.support.BindStatus.<init>(BindStatus.java:141)
at org.springframework.web.servlet.tags.form.AbstractDataBoundFormElementTag.getBindStatus(AbstractDataBoundFormElementTag.java:174)
at org.springframework.web.servlet.tags.form.AbstractDataBoundFormElementTag.getPropertyPath(AbstractDataBoundFormElementTag.java:194)
at org.springframework.web.servlet.tags.form.AbstractDataBoundFormElementTag.getName(AbstractDataBoundFormElementTag.java:160)
at org.springframework.web.servlet.tags.form.AbstractDataBoundFormElementTag.autogenerateId(AbstractDataBoundFormElementTag.java:147)
at org.springframework.web.servlet.tags.form.AbstractDataBoundFormElementTag.resolveId(AbstractDataBoundFormElementTag.java:138)
at org.springframework.web.servlet.tags.form.AbstractDataBoundFormElementTag.writeDefaultAttributes(AbstractDataBoundFormElementTag.java:122)
at org.springframework.web.servlet.tags.form.AbstractHtmlElementTag.writeDefaultAttributes(AbstractHtmlElementTag.java:408)
at org.springframework.web.servlet.tags.form.InputTag.writeTagContent(InputTag.java:140)
at org.springframework.web.servlet.tags.form.AbstractFormTag.doStartTagInternal(AbstractFormTag.java:102)
at org.springframework.web.servlet.tags.RequestContextAwareTag.doStartTag(RequestContextAwareTag.java:79)
at org.apache.jsp.WEB_002dINF.views.signUp_jsp._jspx_meth_form_005finput_005f0(signUp_jsp.java:179)
at org.apache.jsp.WEB_002dINF.views.signUp_jsp._jspx_meth_form_005fform_005f0(signUp_jsp.java:111)
at org.apache.jsp.WEB_002dINF.views.signUp_jsp._jspService(signUp_jsp.java:74)
at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:374)
... 59 more
UserManagementController.java
#Controller
public class UserManagementController {
//displays sign up page(GET)
#RequestMapping(method=RequestMethod.GET, value="/signUp.html")
public ModelAndView signUpForm() {
System.out.println("Sign up");
return new ModelAndView("/signUp", "user", new User());
}
}
signUp.jsp
<body>
<h3>Sign up</h3>
<table>
<form:form commandName="user" >
<tr>
<td>First name:</td>
<td><form:input path="firstName"/></td>
</tr>
<tr>
<td>Last name:</td>
<td><form:input path="lastName"/></td>
</tr>
<tr>
<td>Username:</td>
<td><form:input path="username"/></td>
</tr>
<tr>
<td>Password:</td>
<td><form:input path="password"/></td>
</tr>
<tr>
<td>Email:</td>
<td><form:input path="email"/></td>
</tr>
<tr>
<td></td>
<td><input type="submit" value="Submit"></td>
</tr>
</form:form>
</table>
</body>
Could someone help me understand it?
Thanks.
I was mistakenly using the wrong import for ModelAndView.
I was supposed to use org.springframework.web.servlet.ModelAndView but the one I was mistakenly using was org.springframework.web.portlet.ModelAndView.
I've got the code working now.
Thanks :)