Spring SimpleFormController - including successful lookup form

UPDATE 1/31/10 . As this thread continues to receive a lot of views ... I'm curious if it has helped anyone lately? Feel free to leave comments / feedback, thanks.


I have a Spring form where I would like to reuse the search page to include the results in the search form. Currently, when I do this, I am getting the following error while loading the success view:

java.lang.IllegalStateException: Neither BindingResult nor plain target object for bean name 'searchAccounts' available as request attribute 

Here is my bean configuration:

 <bean name="/search.html" class="myapp.web.AccountSearchController"> <property name="sessionForm" value="true"/> <property name="commandName" value="searchAccounts"/> <property name="commandClass" value="myapp.service.AccountSearch"/> <property name="validator"> <bean class="myapp.service.AccountSearchValidator"/> </property> <property name="formView" value="accountSearch"/> <property name="successView" value="accountSearchResults"/> </bean> 

Here is the JSP snippet that contains the search form:

 <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %> <%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %> <form:form method="post" commandName="searchAccounts"> <table valign="top" cellspacing="0" cellpadding="0" width="500" border="0"> <tr> <td valign="top"> <div class="border-title">Account Search</div> <div id="navhome"> <div class="border"> <div id="sidebarhome"> <table id="form"> <tr> <td colspan="2">Search by Account ID or Domain Name. If values are provided for both, only accounts matching both values will be returned.</td> </tr> <tr> <td colspan="2">&nbsp;</td> </tr> <tr> <td align="right" valign="top"><form:label path="accountId">Account ID</form:label>:</td> <td><form:input path="accountId" size="30"/></td> </tr> <c:set var="accountIdErrors"><form:errors path="accountId"/></c:set> <c:if test="${not empty accountIdErrors}"> <tr> <td>&nbsp;</td> <td>${accountIdErrors}</td> </tr> </c:if> <tr> <td align="right" valign="top"><form:label path="domainName">Domain Name</form:label>:</td> <td><form:input path="domainName" size="30"/></td> </tr> <c:set var="domainNameErrors"><form:errors path="domainName"/></c:set> <c:if test="${not empty domainNameErrors}"> <tr> <td>&nbsp;</td> <td>${domainNameErrors}</td> </tr> </c:if> <tr> <td colspan="2">&nbsp;</td> </tr> <tr> <td>&nbsp;</td> <td><input type="submit" name="submit" value="Search"> </td> </tr> </table> </div> </div> </div> </td> </tr> </table> </form:form> 

And ... here is my form controller class (less import):

  public class AccountSearchController extends SimpleFormController { protected final Log logger = LogFactory.getLog(getClass()); public ModelAndView onSubmit(Object command, BindException errors) throws ServletException { String accountId = ((AccountSearch) command).getAccountId(); String domainName = ((AccountSearch) command).getDomainName(); logger.info("User provided search criteria...\n\tDomain Name: " + domainName + "\n\tAccountId: " + accountId); //TODO do search logger.info("returning from AccountSearch form view to " + getSuccessView()); return new ModelAndView(getSuccessView()); } protected Object formBackingObject(HttpServletRequest request) throws ServletException { AccountSearch accountSearch = new AccountSearch(); return accountSearch; } } 

Thanks in advance for your help!

-L

UPDATE:

I put this in an annotated controller for each answer below. Here is the new / working code:

 @Controller @RequestMapping("/search.html") public class AccountSearchController { // note: this method does not have to be called setupForm @RequestMapping(method = RequestMethod.GET) public String setupForm(Model model) { AccountSearchCriteria accountSearchCriteria = new AccountSearchCriteria(); model.addAttribute("accountSearchCriteria", accountSearchCriteria); model.addAttribute("title", "Account Search"); return "accountSearch"; } // note: this method does not have to be called onSubmit @RequestMapping(method = RequestMethod.POST) public String onSubmit(@ModelAttribute("accountSearchCriteria") AccountSearchCriteria accountSearchCriteria, BindingResult result, SessionStatus status, Model model) { new AccountSearchValidator().validate(accountSearchCriteria, result); if (result.hasErrors()) { return "accountSearch"; } else { ArrayList<AccountSearchCriteria> accountSearchResults = new ArrayList<AccountSearchCriteria>(); AccountSearchCriteria rec = new AccountSearchCriteria(); rec.setDomainName("ajcoon.com"); accountSearchResults.add(rec); AccountSearchCriteria rec2 = new AccountSearchCriteria(); rec2.setDomainName("ajcoon2.com"); accountSearchResults.add(rec2); //TODO do search //ArrayList<HashMap<String,String>> accountSearchResults = new AccountSearchService().search(accountId,domainName); if( accountSearchResults.size() < 1 ){ result.rejectValue("domainName", "error.accountSearch.noMatchesFound", "No matching records were found."); return "accountSearch"; } else if(accountSearchResults.size() > 1){ model.addAttribute("accountSearchResults", accountSearchResults); return "accountSearch"; } else { status.setComplete(); return "redirect:viewAccount?accountId="; //return "redirect:viewAccount?accountId=" + accountSearchResults.get(0).getAccountId(); } } } } 
+4
source share
1 answer

try using (throws an exception instead of ..)

 protected Object formBackingObject(HttpServletRequest request) throws Exception { AccountSearch accountSearch = new AccountSearch(); System.out.println("inside formBackingObject"); return accountSearch; } 

It looks like your formBackingObject method is not executing. repeat the code with the change above and see the log console to see if this method is executing.

-

You should use annotation instead of controller extension. Spring 3.0 will discount the controller hierarchy.

+1
source

All Articles