Spring 3 — form with 2 buttons, sending 2 parameters to controller method

倖福魔咒の 提交于 2019-12-05 19:00:43

问题


I have a Spring 3 MVC form with 2 parameters I'm trying to send to my controller method, and I'm getting a 404 error. The twist on this problem is that the form has 2 submit buttons, and the submit button that is clicked dictates the value of one of the parameters. Here is my form.

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

Here is my controller 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";
}

回答1:


I have solved my own problem. I am posting my code for the benefit of anyone else who hits this thread with the same problem. Here is my form.

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

Here are my controller methods.

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



回答2:


Your form's action is set to "/approve" yet your Controller mapping is "/approve/{action}/{id}"; the Dispatcher Servlet has no way of making the connection between these two.

Even if the method was mapped correctly it wouldn't do what you expect it to do: you're confusing action and input and what they correspond to in the HTTP request.

action sets the URL of the form request, in your case it's "/approve". Each <input> element's name parameter is used to add HTTP parameters with value of value, so the request would have a combination of:

  • id=${id} (all requests)
  • approve=Approve (if user clicked "approve")
  • deny=Deny (if user clicked "deny")

To handle both these cases the controller's signature should be changed to something like this:

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

    // (...)
}

But I'd rather suggest changing the parameters of the submit buttons:

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

This way you always get exactly two parameters: id and approve, then you can just check the value of approve to see if it was an "approve" or a "deny":

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
    }

What helps diagnosing such problems (ie. whether it's the client or server problem) is inspecting the outgoing request using browser's web tools (Firebugs in Firefox, Developer Tools in Chrome, etc.). You can easily capture the request and see what the HTTP parameters, URL and method were and compare them to your expectations.



来源:https://stackoverflow.com/questions/16514501/spring-3-form-with-2-buttons-sending-2-parameters-to-controller-method

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!