我試圖在MultiActionController上應用表單驗證(我知道現在不推薦使用控制器類)。使用MultiActionController進行Spring-MVC表單驗證
我發現這個答案(這讓我更接近我的目標,但不完全): How to perform Spring validation in MultiActionController?
好了,所以根據javadoc,異常處理方法是控制器的方法與參數(HttpServletRequest request, HttpServletResponse response, ExceptionClass exception)
。
據我所知(糾正我,如果我錯了),它看起來像工作流程如下:春季調度員 - 小服務程序去控制器的請求方法,如果發生異常它的執行(例如,由於驗證失敗而導致的綁定異常),它將轉到異常處理程序方法,使其異常參數與發生的異常相匹配(如果存在這樣的異常處理程序方法)。
但與常規控制器的方法不同,此異常處理程序方法沒有命令對象參數。 所以我的問題是我該如何訪問該方法,與發生綁定異常(由於驗證錯誤)的請求一起發送的命令對象?
例如,當我通過註解使用驗證,我在請求處理程序方法訪問(作爲方法參數)兩者BindingResult和命令對象,所以在驗證錯誤的情況下,我可以加載返回ModelAndView與命令對象數據。
然而,我的異常處理方法(在我的MultiActionController),這與
BindException bindException = (BindException) bindingException.getRootCause();
return new ModelAndView("myFormView").addAllObjects(bindException.getModel());
結束 - 提交無效數據後,我得到和異常,我的JSP視圖(「myFormView」)不能被渲染因爲找不到命令對象。
謝謝!
更多信息:
在我的控制器(SearchBookController)我的實際要求處理方法是這樣的:
public ModelAndView list(HttpServletRequest request, HttpServletResponse response, Book book) throws Exception {
ModelMap modelMap = new ModelMap();
//getting a list of books according to the propertiest of the command object book...
modelMap.addAttribute("bookList", bookDAO.listBooks(book));
return new ModelAndView("bookForm", modelMap);
}
我還添加了以下異常處理方法控制器:
public ModelAndView hanldeBindException(HttpServletRequest request, HttpServletResponse response, ServletRequestBindingException bindingException) {
// do what you want right here
//I WOULD LIKE TO ADD HERE THE SUBMITTED BOOK AND THE FETCHED BOOKLIST TO THE ModelAndView, BUT I DO NOT KNOW HOW TO DO IT
BindException bindException = (BindException) bindingException.getRootCause();
return new ModelAndView("bookForm").addAllObjects(bindException.getModel());
}
這就是我在我的servlet-dispatcher.xml中將我的驗證器添加到SearchBookController :
<bean name="/book/search.htm" class="com.books.web.SearchBookController" p:validators-ref="searchBookValidator" >
<property name="bookDAO" ref="myBookDAO" />
</bean>
<bean id="searchBookValidator" class="com.books.validator.SearchBookValidator" />
眼下驗證只是確保在書中性質由ValidationUtils.rejectIfEmptyOrWhitespace驗證。
我的視圖(bookForm.jsp)顯示了提交字段和搜索結果(它在呈現結果視圖時重新顯示提交的字段)。所以在提交之後,視圖應該同時得到book命令對象和bookList對象。
bookForm。jsp看起來像這樣:
<tr>
<td>Details :</td>
<td><form:input path="details" /></td>
<td><form:errors path="details" cssClass="error"/></td>
</tr>
(詳情是Book的一個領域)。
下面是當我嘗試加載bookForm.jsp(提交甚至之前,只是當我嘗試加載網頁,所以我可以填寫表格)我收到異常消息:
(** *當我從servlet-dispatcher.xml中的控制器定義中刪除p:validators-ref="searchBookValidator"
時,jsp頁面在提交前後正確加載)。
HTTP Status 500 -
--------------------------------------------------------------------------------
type Exception report
message
description The server encountered an internal error() that prevented it from fulfilling this request.
exception
org.apache.jasper.JasperException: An exception occurred processing JSP page /WEB-INF/jsp/bookForm.jsp at line 209
206: --%>
207: <tr>
208: <td>Details :</td>
209: <td><form:input path="details" /></td>
210: <td><form:errors path="details" cssClass="error"/></td>
211: </tr>
212: <tr>
Stacktrace:
org.apache.jasper.servlet.JspServletWrapper.handleJspException(JspServletWrapper.java:510)
org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:413)
org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:313)
org.apache.jasper.servlet.JspServlet.service(JspServlet.java:260)
javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
org.springframework.web.servlet.view.InternalResourceView.renderMergedOutputModel(InternalResourceView.java:238)
org.springframework.web.servlet.view.AbstractView.render(AbstractView.java:250)
org.springframework.web.servlet.DispatcherServlet.render(DispatcherServlet.java:1047)
org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:817)
org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:719)
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:644)
org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:549)
javax.servlet.http.HttpServlet.service(HttpServlet.java:617)
javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
root cause
java.lang.IllegalStateException: Neither BindingResult nor plain target object for bean name 'book' available as request attribute
org.springframework.web.servlet.support.BindStatus.<init>(BindStatus.java:141)
org.springframework.web.servlet.tags.form.AbstractDataBoundFormElementTag.getBindStatus(AbstractDataBoundFormElementTag.java:174)
org.springframework.web.servlet.tags.form.AbstractDataBoundFormElementTag.getPropertyPath(AbstractDataBoundFormElementTag.java:194)
org.springframework.web.servlet.tags.form.AbstractDataBoundFormElementTag.getName(AbstractDataBoundFormElementTag.java:160)
org.springframework.web.servlet.tags.form.AbstractDataBoundFormElementTag.autogenerateId(AbstractDataBoundFormElementTag.java:147)
org.springframework.web.servlet.tags.form.AbstractDataBoundFormElementTag.resolveId(AbstractDataBoundFormElementTag.java:138)
org.springframework.web.servlet.tags.form.AbstractDataBoundFormElementTag.writeDefaultAttributes(AbstractDataBoundFormElementTag.java:122)
org.springframework.web.servlet.tags.form.AbstractHtmlElementTag.writeDefaultAttributes(AbstractHtmlElementTag.java:408)
org.springframework.web.servlet.tags.form.InputTag.writeTagContent(InputTag.java:140)
org.springframework.web.servlet.tags.form.AbstractFormTag.doStartTagInternal(AbstractFormTag.java:102)
org.springframework.web.servlet.tags.RequestContextAwareTag.doStartTag(RequestContextAwareTag.java:79)
org.apache.jsp.WEB_002dINF.jsp.bookForm_jsp._jspx_meth_form_005finput_005f0(bookForm_jsp.java:593)
org.apache.jsp.WEB_002dINF.jsp.bookForm_jsp._jspService(bookForm_jsp.java:326)
org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:377)
org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:313)
org.apache.jasper.servlet.JspServlet.service(JspServlet.java:260)
javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
org.springframework.web.servlet.view.InternalResourceView.renderMergedOutputModel(InternalResourceView.java:238)
org.springframework.web.servlet.view.AbstractView.render(AbstractView.java:250)
org.springframework.web.servlet.DispatcherServlet.render(DispatcherServlet.java:1047)
org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:817)
org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:719)
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:644)
org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:549)
javax.servlet.http.HttpServlet.service(HttpServlet.java:617)
javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
UPDATE:
按照下面的答案,我現在可以從異常處理程序方法訪問命令對象。但我仍然有一個問題:如果我提交的數據應該引發錯誤信息,例如通過
<tr>
<td>Details :</td>
<td><form:input path="details" /></td>
<td><form:errors path="details" cssClass="error"/></td>
</tr>
在結果視圖JSP - 我沒有看到該錯誤消息。
我的驗證程序是這樣的:
public class SearchBookValidator implements Validator {
//......
@Override
public void validate(Object target, Errors errors) {
ValidationUtils.rejectIfEmptyOrWhitespace(errors, "details", "details.required");
}
}
和我messages.properties包含以下行:
details.required=details are required
幫我看看會發生什麼,我已經包括在下面的代碼我控制器的hanldeBindException:
Map mp = bindException.getModel();
for (Object o : mp.entrySet()) {
Map.Entry pairs = (Map.Entry)o;
System.out.println(pairs.getKey() + " = " + pairs.getValue());
}
當我故意提交表單時g數據(即細節文本字段爲空),我得到的控制檯上輸入如下:
command = [email protected]
org.springframework.validation.BindingResult.command = org.springframework.validation.BeanPropertyBindingResult: 1 errors
Field error in object 'command' on field 'details': rejected value []; codes [details.required.command.details,details.required.details,details.required.java.lang.String,details.required]; arguments []; default message [null]
你可以看到爲什麼我沒有得到過任何<form:errors path="details" cssClass="error"/>
錯誤訊息?
您可以發佈呈現頁面的輸出(「無法呈現,因爲無法找到命令對象」) –
謝謝。我剛剛在主標題** MORE INFO **下添加了輸出和更多詳細信息。 – rapt