Spring MVC的 - 的形式产生新的模型对象实例(Spring MVC - form gene

2019-11-03 08:44发布

我有一个简单的MVC应用程序,其中列出了在数据库中的所有规则,并允许用户选择特定的一行来删除该规则。 该控制器具有简单listRules()方法,它增加了两个模型对象到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:/");
    }

我的模型对象

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”值总是零。 我有什么错IO与我的模型/方法映射在做什么?

生成的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>
....

编辑 - 我已经更新控制器方法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

编辑添加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>

我删除从我的applicationContext.xml三个MVC元素文件,它的形式开始工作。

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

FRIDAY编辑 - 我已经分离出的问题列入JSP表单的JavaScript元素。 如果没有javascript文件包括,表单提交数据到控制器。 当添加脚本似乎表单数据不正确绑定到的ModelAttribute对象。 JavaScript文件主要目的是使在HTML表tablesorting功能,所以我不能明白为什么它们影响的提交按钮的作用。 50点人谁可以解释它。

Answer 1:

我能想到的唯一的事情就是rules.js或其他JavaScript进口中的一个可以禁用单选按钮之前提交 - 在这种情况下没有价值将在POST操作,这会又有意义的,因为提交为什么的ModelAttribute不被popualated。



文章来源: Spring MVC - form generating new model object instances
标签: spring-mvc