web-dev-qa-db-ja.com

Spring 3--2つのボタンを備えたフォーム、2つのパラメーターをコントローラーメソッドに送信

コントローラーメソッドに送信しようとしている2つのパラメーターを持つSpring3 MVCフォームがあり、404エラーが発生します。この問題のひねりは、フォームに2つの送信ボタンがあり、クリックされた送信ボタンがパラメーターの1つの値を決定することです。これが私のフォームです。

    <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";
}
9
user636859

私は自分の問題を解決しました。同じ問題でこのスレッドにヒットした他の人のために、コードを投稿しています。これが私のフォームです。

<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";
}
15
user636859

フォームのaction"/ apply"に設定されていますが、コントローラーのマッピングは"/ apply/{action}/{id}";です。 Dispatcherサーブレットには、これら2つの間の接続を確立する方法がありません。

メソッドが正しくマップされていても、期待どおりの動作をしません。actioninput、およびそれらが対応するものを混乱させています。 HTTPリクエスト。

actionは、フォームリクエストのURLを設定します。この場合は「/ apply "」です。各<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>

このようにして、常に正確に2つのパラメーター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のDeveloper Toolsなど)を使用して送信要求を検査することです。リクエストを簡単にキャプチャして、HTTPパラメータ、URL、メソッドが何であるかを確認し、期待と比較することができます。

9
kryger