1

Spring (3.1)、Spring MVC (3.1)、および Spring Security (3.0) を組み合わせて使用​​し、2 つのフォームを持つ単一の JSP ページをまとめました。1 つはログインするためのフォームで、もう 1 つは登録するためのフォームです (つまり、新しいユーザーを作成します)。

登録フォームではform、コントローラーによってバックアップされた Spring タグを使用してリクエストを処理しますが、ログイン フォームでは、Springformタグが必要だとは思わないので気にしません。リクエストが に送信されている限り、Spring Security が認証を処理するため、フォームの送信を処理するために記述する必要のあるコントローラーもありませんj_spring_security_check

登録フォームは正常に機能していますが、ログイン フォームに問題があります。ログインフォームの送信ボタンをクリックすると、登録フォームも送信されるか、少なくともSpringはそのフォームを送信しようとしていると考えています。JSP は次のとおりです。

    <form id="loginform" method="POST" action="<c:url value='j_spring_security_check'/>">
        <label for="existing_email">Email:</label> 
        <input name="j_username" id="existing_email" type="text" value="${SPRING_SECURITY_LAST_USERNAME}" /> 

        <label for="existing_password">Password:</label> 
        <input name="j_password" id="existing_password" type="password" /> 

        <input id="login-form-submit" type="submit" value="Sign in" />
    </form>

    <form:form id="registrationform" modelAttribute="user" method="POST" action="register">
        <form:label path="username" for="email">Email:</form:label> 
        <form:input path="username" name="username" id="email" type="text" /> 
        <form:errors path="username" cssClass="formError" />

        <form:label path="password" for="password">Password:</form:label>
        <form:input path="password" name="password" id="password" type="password" />
        <form:errors path="password" cssClass="formError" />

        <input id="registration-form-submit" type="submit" value="Sign up" />
    </form:form>

タイプ送信の入力のformタグが存在しないことに注意してください。これは、私が見た例では通常のことのようです。フォームタグを送信ボタンに追加しても、ターゲットオブジェクト (この場合はユーザー)の何にもマップされないため、意味がないと思います。

「サインイン」ボタンをクリックすると、次の例外が発生します。

SEVERE: Servlet.service() for servlet [appServlet] in context with path [/project1] threw exception [An exception occurred processing JSP page /WEB-INF/views/registration.jsp at line 29
28:         <form:form id="registrationform" modelAttribute="user" method="POST" action="register">
29:             <form:label path="username" for="username">Username:</form:label> 
30:             <form:input path="username" name="username" id="username" type="text" />
31:             <form:errors path="username" cssClass="formError" />
32:              


Stacktrace:] with root cause
java.lang.IllegalStateException: Neither BindingResult nor plain target object for bean name 'user' available as request attribute
    at org.springframework.web.servlet.support.BindStatus.<init>(BindStatus.java:141)

これは、modelAttribute 属性を に含めるのを忘れた場合から認識していますform:formが、もちろん、このフォームをコントローラーに送信したくありません。

私が犯している間違いや簡単な解決策があると感じています。これを回避する方法、またはおそらく別のアプローチを推奨できる人はいますか?

必要な場合に備えて、登録要求を処理するコントローラー メソッドを次に示します。

    @RequestMapping(value = "**/register", method = RequestMethod.POST)
    public String registerUser(@ModelAttribute("user") @Validated User user, BindingResult errors, ModelMap model) {
        if (errors.hasErrors()) {
            return "registration";
        }
        // Other stuff then...
        return "profile"
    }
4

2 に答える 2

1

フォームタグで「user」modelAttributeを使用している場合は、null以外のリクエスト属性が「user」という名前で存在している必要があります。

これをリクエスト属性に追加する1つの方法は、上記の回答で行ったことです。他の方法は次のとおりです。

(1)ModelMapに追加します。

    @RequestMapping(value = "/loginfailed", method = RequestMethod.GET)
public String loginFailed(ModelMap model) {
    model.addAttribute("user", new User());
    model.addAttribute("error", "true");
    return "registration";
}  

(2)リクエストスコープを追加します(WebRequestまたはHttpServletRequestを使用):

    @RequestMapping(value = "/loginfailed", method = RequestMethod.GET)
public String loginFailed(ModelMap model, WebRequest webRequest) {
   webRequest.setAttribute("user", new User(), WebRequest.SCOPE_REQUEST);
    model.addAttribute("error", "true");
    return "registration";
}  

(3)メソッドで@ModelAttributeを使用します。

    @ModelAttribute("user")
public User user() {
    return new User();
}  

メソッドでの@ModelAttributeの使用およびメソッド引数での@ModelAttributeの使用も参照してください。

また、type属性を使用する必要がないことにも注意してください。form:inputおよびform:passwordを参照してください。

于 2012-05-27T16:59:03.927 に答える
0

問題は、ログインが失敗し、同じページが別の URL パス上にあり、別のコントローラー メソッドを介して提供されている場合に特にあると思います。したがって、問題は両方のフォームが提出されたということであるという私の当初の疑いは、私はまだ何が起こっているのかを完全には理解しておらず、それはまだそれと関係があるかもしれませんが. いずれにせよ、これは私にとって問題を修正したものです:

もともと次のようなコントローラーメソッドがありました。

@RequestMapping(value = "/loginfailed", method = RequestMethod.GET)
public String loginFailed(ModelMap model) {
    model.addAttribute("error", "true");
    return "registration";
}

Spring Security コンテキストでは/loginfailed、ログイン試行が失敗した場合にデフォルトで移動するパスとして指定します。これは、ユーザー オブジェクトが必要なように見える場所なので、次のように署名を変更すると、すべて機能します。

@RequestMapping(value = "/loginfailed", method = RequestMethod.GET)
public String loginFailed(@ModelAttribute("user") User user, BindingResult errors, ModelMap model) {
    model.addAttribute("error", "true");
    return "registration";
}

他の人からのコメント/説明を歓迎します。

于 2012-05-27T12:02:26.347 に答える