2014-10-13 2 views
0

У меня есть простое приложение mvc, в котором перечислены все правила в БД и позволяет пользователю выбрать определенную строку для удаления этого правила. Контроллер имеет простой метод listRules(), который добавляет два модельных объекта в ModelMap.Spring MVC - форма, генерирующая новые экземпляры объектов модели

@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:/"); 
    } 

Мои объекты модели

public class ListRulesModel { 

    private List<Rule> rules = null; 

    public List<Rule> getRules() { 
     return rules; 
    } 

    public void setRules(List<Rule> rules) { 
     this.rules = rules; 
    } 
} 

и

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); 
    } 
} 

Основными элементами мой взгляд являются формой таблица, которая показывает каждое правило в качестве строки. Радиообъект должен заполнить поле «selectedRuleModel.ruleId» значением правила в списке.

<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> 

Каждый раз, когда я отправить «удалить строку» сформировать представляется, что новый объект «» SelectedRuleModel передается в качестве параметра методу deleteRule(), такие, что значение «ruleId» всегда нуль. Что я делаю неправильно с моим сопоставлением модели/метода?

Сгенерированный HTML является

<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 - Я обновить метод контроллера deleteRule(), чтобы включить объект BindResult.

@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:/"); 
} 

Как вы можете видеть в протоколирования для этого метода «selectedRuleModel» равно нулю, но модель имеет «selectedRuleModel» с нулевым значением «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 Добавление web.xml и applicationContext.xml в случае, если кто-то видит, что я не инициализацию некоторых требуемых компонентов правильно.

<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> 

И мой applicationContext.xml имеет

<?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> 

Я снял три элемента из MVC моего applicationContext.xml файла его форма начала работать.

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

FRIDAY EDIT - Я выделил проблему для включения элементов javascript в форму jsp. Без включенных файлов javascript форма передает данные контроллеру. Когда скрипты добавляются, кажется, что данные формы не связаны с объектом ModelAttribute. Файлы javascript в первую очередь направлены на то, чтобы включить функции tableorting в таблице html, поэтому я не могу понять, почему они выполняют действие кнопок отправки. 50 очков для тех, кто может это объяснить.

+0

И вопрос в том, что? –

+0

Я уточнил вопрос. – emeraldjava

+0

Нормально, что для каждого запроса создается новый 'SelectedRuleModel', но его' id' следует заполнять с помощью '@ ModelAttribute'. Вместо хэша попробуйте напечатать 'ruleId'. –

ответ

0

Единственное, о чем я могу думать, это то, что rules.js или один из других импортных javascript может отключать переключатель непосредственно перед отправкой - в этом случае никакая ценность не будет представлена ​​в операции POST, которая тогда имеет смысл, почему TypeAttribute не популяризируется.

Смежные вопросы