У меня есть простое приложение 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 очков для тех, кто может это объяснить.
И вопрос в том, что? –
Я уточнил вопрос. – emeraldjava
Нормально, что для каждого запроса создается новый 'SelectedRuleModel', но его' id' следует заполнять с помощью '@ ModelAttribute'. Вместо хэша попробуйте напечатать 'ruleId'. –