Spring MVC - a form that generates new instances of model objects

I have a simple mvc application that lists all the rules in the database and allows the user to select a specific row to delete this rule. The controller has a simple listRules () method that adds two model objects to ModelMap.

@Controller public class RulesController { @Resource private RuleManager ruleManager; @RequestMapping(value = "/", method = RequestMethod.GET) public ModelAndView listRules() { ModelAndView mv = new ModelAndView("/rules"); List<Rule> rules = this.ruleManager.getAllRules(); ListRulesModel listRulesModel = new ListRulesModel(); listRulesModel.setRules(rules); mv.addObject("listRulesModel",listRulesModel); SelectedRuleModel selectedRuleModel = new SelectedRuleModel(); mv.addObject("selectedRuleModel",selectedRuleModel); return mv; } @RequestMapping(value = "/submit", method = RequestMethod.POST, params = {"delete"}) public ModelAndView deleteRule(@ModelAttribute("selectedRuleModel") SelectedRuleModel selectedRuleModel,ModelMap model) { System.out.println("deleteRule "+selectedRuleModel.hashCode()); System.out.println("model "+model); if(selectedRuleModel.getRuleId()!=null) getRuleManager().deleteRule(getRuleManager().getRule(selectedRuleModel.getRuleId())); return new ModelAndView("redirect:/"); } 

My model objects

 public class ListRulesModel { private List<Rule> rules = null; public List<Rule> getRules() { return rules; } public void setRules(List<Rule> rules) { this.rules = rules; } } 

and

 public class SelectedRuleModel { @NotNull private Integer ruleId = null; public Integer getRuleId() { return ruleId; } public void setRuleId(Integer ruleId) { this.ruleId = ruleId; } @Override public String toString() { return String.format("SelectedRuleModel [ruleId=%s]", ruleId); } } 

The main elements of my presentation are the tabular form, which shows each rule as a string. The radio object should fill the "selectedRuleModel.ruleId" field with the rule value in the list.

 <head> <script type="text/javascript" src="<c:url value="/resources/js/jquery-2.1.1.min.js"/>"></script> <script type="text/javascript" src="<c:url value="/resources/js/jquery.tablesorter.min.js"/>"> </script> <script type="text/javascript" src="<c:url value="/resources/js/jquery.tablesorter.widgets.min.js"/>"></script> <script type="text/javascript" src="<c:url value="/resources/js/rules.js"/>"></script> <link href="<c:url value="/resources/css/base.css"/>" rel="stylesheet"/> <link href="<c:url value="/resources/css/theme.blue.css"/>" rel="stylesheet"/> <link href="<c:url value="/resources/css/rules.css"/>" rel="stylesheet"/> </head> <form:form method="POST" action="submit" modelAttribute="selectedRuleModel"> <button type="submit" name="delete" value="delete" class="btn btn-primary">Delete Selected Rule</button> ... <c:forEach items="${listRulesModel.rules}" var="rule" varStatus="status"> <tr> <td><form:radiobutton path="ruleId" value="${rule.id}"/></td> <td>${rule.name}</td> <td>${rule.batch}</td> ... </form> 

Each time I submit the "delete row" form, it seems that a new "SelectedRuleModel" object is passed as a parameter to the deleteRule () method, so the value of "ruleId" is always null. What am I doing wrong with my model / method mapping?

HTML generated

 <form id="selectedRuleModel" action="submit" method="POST"> <button type="submit" name="amend" value="amend" class="btn btn-primary">Amend Selected Rule</button> <button type="submit" name="branch" value="branch" class="btn btn-primary">Branch Selected Rule</button> <button type="submit" name="delete" value="delete" class="btn btn-primary">Delete Selected Rule</button> </div> <!-- Add rule table --> <table id="rulesTable" class="tablesorter"> <thead> <tr> <th>ID</th> <th>Rule Name</th> .... </tr> </thead> <tbody> <tr> <td><input id="ruleId2" name="ruleId" type="radio" value="20"/></td> <td>Gender_Balance</td> <td>*</td> .... 

EDIT - I updated the controller's deleteRule () method to include the BindResult object.

  @RequestMapping(value = "/submit", method = RequestMethod.POST, params = {"delete"}) public ModelAndView deleteRule( @Valid @ModelAttribute("selectedRuleModel") SelectedRuleModel selectedRuleModel, BindingResult result, ModelMap model) { System.out.println("deleteRule "+selectedRuleModel.getRuleId()); System.out.println("model "+model.toString()); System.out.println("BindingResult "+result.toString()); if(selectedRuleModel.getRuleId()!=null) getRuleManager().deleteRule(getRuleManager().getRule(selectedRuleModel.getRuleId())); return new ModelAndView("redirect:/"); } 

As you can see in the log for this method, "selectedRuleModel" is null, but the model has "selectedRuleModel" with a null value of "ruleId".

 2014-10-14 11:18:21,428 INFO [STDOUT] (http-127.0.0.1-8080-2) deleteRule null 2014-10-14 11:18:21,428 INFO [STDOUT] (http-127.0.0.1-8080-2) model {selectedRuleModel=SelectedRuleModel [ruleId=null], org.springframework.validation.BindingResult.selectedRuleModel=org.springframework.validation.BeanPropertyBindingResult: 0 errors} 2014-10-14 11:18:21,428 INFO [STDOUT] (http-127.0.0.1-8080-2) BindingResult org.springframework.validation.BeanPropertyBindingResult: 0 errors 

EDIT Adding web.xml and applicationContext.xml in case someone noticed that I am not initializing some necessary component correctly.

 <web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"> <context-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/applicationContext.xml</param-value> </context-param> <servlet> <servlet-name>hedgingcorrection</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>namespace</param-name> <param-value>applicationContext</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>hedgingcorrection</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <jsp-config> <taglib> <taglib-uri>/spring</taglib-uri> <taglib-location>/WEB-INF/tld/spring-form.tld</taglib-location> </taglib> </jsp-config> </web-app> 

And my applicationContext.xml has

 <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:context="http://www.springframework.org/schema/context" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <mvc:annotation-driven/> <mvc:resources mapping="/resources/**" location="/resources/"/> <mvc:view-controller path="/"/> <context:component-scan base-package="abc.xwz.web.correction.controller"/> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix"> <value>/WEB-INF/pages/</value> </property> <property name="suffix"> <value>.jsp</value> </property> </bean> 

I removed three mvc elements from my applicationContext.xml file that the form started working with.

 <mvc:annotation-driven/> <mvc:resources mapping="/resources/**" location="/resources/"/> <mvc:view-controller path="/"/> 

FRIDAY EDIT - I highlighted a problem for including javascript elements in jsp form. Without javascript files included, the form passes data to the controller. When scripts are added, it seems that the form data is not associated with a ModelAttribute object. The javascript files are primarily aimed at enabling tableorting functions in the html table, so I cannot understand why they perform the action of submit buttons. 50 points for anyone who can explain this.

0
spring mvc
Oct 13 '14 at 17:11
source share
1 answer

The only thing I can think of is that rules.js or one of the other imported javascript can disable the radio button just before sending - in this case, no value will be presented in the POST operation, which will then make sense why ModelAttribute is not popularized.

0
Oct 24 '14 at 1:39 on
source share
— -



All Articles