异常:Neither BindingResult nor plain target object for bean name 'command' available as request attribute
这个异常在使用标签<form:form>时经常遇到,原因是因为model中没有绑定表单对象,而spring默认绑定的表单对象名为"command",或者是因为Controller中声明的绑定对象与form标签中声明的绑定对象名不一致而导致出现的异常。
示例:
1.配置文件略过(使用标注的spring的配置文件非常简单,本例不需要特殊的配置)
2.Controller
@Controller
@RequestMapping("/form")
@SessionAttributes("formBean")
public class FormController {
// Invoked on every request
@ModelAttribute
public void ajaxAttribute(WebRequest request, Model model) {
model.addAttribute("ajaxRequest", AjaxUtils.isAjaxRequest(request));
}
// Invoked initially to create the "form" attribute
// Once created the "form" attribute comes from the HTTP session (see @SessionAttributes)
@ModelAttribute("command")(注1)
public FormBean createFormBean() {
return new FormBean();
}
@RequestMapping(method=RequestMethod.GET)
public void form() {
}
@RequestMapping(method=RequestMethod.POST)
public String processSubmit(@Valid FormBean formBean, BindingResult result,
@ModelAttribute("ajaxRequest") boolean ajaxRequest,
Model model, RedirectAttributes redirectAttrs) {
if (result.hasErrors()) {
return null;
}
// Typically you would save to a db and clear the "form" attribute from the session
// via SessionStatus.setCompleted(). For the demo we leave it in the session.
String message = "Form submitted successfully. Bound " + formBean;
// Success response handling
if (ajaxRequest) {
// prepare model for rendering success message in this request
model.addAttribute("message", message);
return null;
} else {
// store a success message for rendering on the next request after redirect
// redirect back to the form to render the success message along with newly bound values
redirectAttrs.addFlashAttribute("message", message);
return "redirect:/form";
}
}
}
3.form.jsp
<form:form id="form" method="post" commandName="command"(注2) cssClass="cleanform">
<div class="header">
<h2>Form</h2>
<c:if test="${not empty message}">
<div id="message" class="success">${message}</div>
</c:if>
<s:bind path="*">
<c:if test="${status.error}">
<div id="message" class="error">Form has errors</div>
</c:if>
</s:bind>
</div>
<fieldset>
<legend>Personal Info</legend>
<form:label path="name">
Name <form:errors path="name" cssClass="error" />
</form:label>
<form:input path="name" />
<form:label path="age">
Age <form:errors path="age" cssClass="error" />
</form:label>
<form:input path="age" />
<form:label path="birthDate">
Birth Date (in form yyyy-mm-dd) <form:errors path="birthDate" cssClass="error" />
</form:label>
<form:input path="birthDate" />
<form:label path="phone">
Phone (in form (###) ###-####) <form:errors path="phone" cssClass="error" />
</form:label>
<form:input path="phone" />
<form:label path="currency">
Currency (in form $#.##) <form:errors path="currency" cssClass="error" />
</form:label>
<form:input path="currency" />
<form:label path="percent">
Percentage (in form ##%) <form:errors path="percent" cssClass="error" />
</form:label>
<form:input path="percent" />
</fieldset>
<fieldset>
<legend>Inquiry</legend>
<form:label path="inquiry">
Type (select one)
</form:label>
<form:select path="inquiry">
<form:option value="comment">Comment</form:option>
<form:option value="feedback">Feedback</form:option>
<form:option value="suggestion">Suggestion</form:option>
</form:select>
<form:label path="inquiryDetails">
Details
</form:label>
<form:textarea path="inquiryDetails" />
</fieldset>
<fieldset class="checkbox">
<legend>Request Additional Info</legend>
<label><form:checkbox path="additionalInfo[mvc]" value="true" />on Spring MVC</label>
<label><form:checkbox path="additionalInfo[java]" value="true" />on Java (4-ever)</label>
</fieldset>
<fieldset class="radio">
<legend>Subscribe to Newsletter?</legend>
<label><form:radiobutton path="subscribeNewsletter" value="true" />Yes</label>
<label><form:radiobutton path="subscribeNewsletter" value="false" /> No</label>
</fieldset>
<p><button type="submit">Submit</button></p>
</form:form>
Controller里必须使用@ModelAttribute("command")来说明绑定对象名(注1),Spring默认的绑定对象名为command,如果Controller使用了"command"为绑定对象名,则form标签中可以省略commandName="command"。(如示例代码)
如果想要使用其他名称作为绑定名,例如@ModelAttribute("user"),则必须在form标签中显式声明commandName="user"或者声明modelAttribute="user"(注2)。