Spring 3 - 带2个按钮的表单,向控制器方法发送2个参数

时间:2013-05-13 03:37:11

标签: spring-mvc submit http-status-code-404 parameter-passing

我有一个带有2个参数的Spring 3 MVC表单我正试图发送到我的控制器方法,我收到404错误。这个问题的转折是表单有2个提交按钮,点击的提交按钮决定了其中一个参数的值。这是我的表格。

    <form:form action="/approve/${bulletin.id}" method="post">
        <table>
            <tr>
                <td colspan="2"><b>From:</b> <c:out value="${bulletin.name}" /></td>
            </tr>
            <tr>
                <td colspan="2"><b>Subject:</b> <c:out
                        value="${bulletin.subject}" /></td>
            </tr>
            <tr>
                <td colspan="2"><b>Date:</b> <c:out value="${bulletin.date}" />
                    <br></td>
            </tr>
            <tr>
                <td colspan="2"><t:notePrint note="${bulletin.note}" /> <input
                    type="hidden" name="id" value="${bulletin.id}" /></td>
            </tr>
            <tr>
                <td><input type="submit" name="approve" value="Approve" /></td>
                <td><input type="submit" name="deny" value="Deny" /></td>
            </tr>
        </table>
        <br />
    </form:form>

这是我的控制器表格。

@RequestMapping(value = "/approve/{id}", method = RequestMethod.POST)
public String approveBulletin(@RequestParam int id,
        @RequestParam(required = false, value = "approve") String approve,
        @RequestParam(required = false, value = "deny") String deny, Model model) {
    try {
        if (approve.equalsIgnoreCase("approve")) {
            bulletinDAO.approveBulletin(id);
            model.addAttribute("approval",
                    "Your bulletin has been approved.");
        }
        if (deny.equalsIgnoreCase("deny")) {
            bulletinDAO.denyBulletin(id);
            model.addAttribute("approval", "Your bulletin has been denied.");
        }

        List<Bulletin> bulletins = bulletinDAO.getApprovedBulletins();
        model.addAttribute("bulletins", bulletins);
    } catch (Exception e) {
        System.out.println(e.getMessage());
        return "FailurePage";
    }

    return "ApproveBulletin";
}

2 个答案:

答案 0 :(得分:15)

我已经解决了自己的问题。我发布我的代码是为了让其他任何人遇到同样的问题。这是我的表格。

<form:form action="approve" method="post">
    <table>
        <tr>
            <td colspan="2"><b>From:</b> <c:out value="${bulletin.name}" /></td>
        </tr>
        <tr>
            <td colspan="2"><b>Subject:</b> <c:out
                    value="${bulletin.subject}" /></td>
        </tr>
        <tr>
            <td colspan="2"><b>Date:</b> <c:out value="${bulletin.date}" />
                <br></td>
        </tr>
        <tr>
            <td colspan="2"><t:notePrint note="${bulletin.note}" /> <input
                type="hidden" name="id" value="${bulletin.id}" /></td>
        </tr>
        <tr>
            <td><input type="submit" name="approve" value="Approve" /></td>
            <td><input type="submit" name="deny" value="Deny" /></td>
        </tr>
    </table>
    <br />
</form:form>

以下是我的控制器方法。

@RequestMapping(value = "/approve", method = RequestMethod.POST, params = { "approve" })
public String approve(@RequestParam int id, @RequestParam String approve, Model model) {
    try {
        bulletinDAO.approveBulletin(id);
        model.addAttribute("approval", "Your bulletin has been approved.");

        List<Bulletin> bulletins = bulletinDAO.getApprovedBulletins();
        model.addAttribute("bulletins", bulletins);
    } catch (Exception e) {
        System.out.println(e.getMessage());
        return "FailurePage";
    }

    return "ApproveBulletin";
}

@RequestMapping(value = "/approve", method = RequestMethod.POST, params = { "deny" })
public String deny(@RequestParam int id, @RequestParam String deny, Model model) {
    try {
        bulletinDAO.denyBulletin(id);
        model.addAttribute("approval", "Your bulletin has been denied.");

        List<Bulletin> bulletins = bulletinDAO.getApprovedBulletins();
        model.addAttribute("bulletins", bulletins);
    } catch (Exception e) {
        System.out.println(e.getMessage());
        return "FailurePage";
    }

    return "ApproveBulletin";
}

答案 1 :(得分:9)

您的表单action设置为“/ approve”,但您的控制器映射为“/ approve / {action} / {id}”; Dispatcher Servlet无法在这两者之间建立连接。

即使方法 正确映射,它也不会按照您的预期执行:您会混淆actioninput以及它们对应的内容HTTP请求。

action设置表单请求的网址,在您的情况下,它是“ / approve ”。 每个<input>元素的name参数用于添加值为value的HTTP参数,因此请求将具有以下组合:

  • id=${id}(所有请求)
  • approve=Approve(如果用户点击“批准”)
  • deny=Deny(如果用户点击“拒绝”)

要处理这两种情况,控制器的签名应更改为:

@RequestMapping(value = "/approve", method = RequestMethod.POST)
public String approveBulletin(@RequestParam int id,
            @RequestParam(required=false, defaultValue="") String approve,
            @RequestParam(required=false, defaultValue="") String deny,
            Model model) {
    if (approve.equals("Approve")) {
      // user clicked "approve"
    } else if (deny.equals("Deny")) {
      // user clicked "deny"            
    } else {
      throw new IllegalArgumentException("Need either approve or deny!");
    }

    // (...)
}

但我宁愿建议更改提交按钮的参数:

<td><input type="submit" name="approveParam" value="approveVal" /></td>
<td><input type="submit" name="approveParam" value="denyVal" /></td>

这样您总能得到两个参数:idapprove,然后您只需检查approve的值,看看它是“批准”还是“拒绝” “:

public String approveBulletin(@RequestParam int id,
        @RequestParam(value = "approveParam") String approveOrDeny,
        Model model) {
    if (approveOrDeny.equalsIgnoreCase("approveVal")) {
        // user clicked "approve"
    } else if (approveOrDeny.equalsIgnoreCase("denyVal")) {
        // user clicked "deny"
    } else {
        // wrong parameter sent
    }

有助于诊断此类问题(即,是客户端还是服务器问题)是使用浏览器的Web工具(Firefox中的Firebugs,Chrome中的开发人员工具等)检查传出请求。您可以轻松捕获请求并查看HTTP参数,URL和方法,并将其与您的期望进行比较。