問題は次のとおりです。EJB が次の例外をスローします (glassfish ログから):
SEVERE: Attempting to confirm previously confirmed login using confirmation UUID: b90b33ca-dc69-41c1-9c60-99152810c89b
com.extremelatitudesoftware.els_commons.exceptions.LoginPreviouslyConfirmedException: Attempting to confirm previously confirmed login using confirmation UUID: b90b33ca-dc69-41c1-9c60-99152810c89b
at com.extremelatitudesoftware.security.auth.CredentialsController.checkForPreviousConfirmation(CredentialsController.java:244)
そして、例外スタックのクライアント側 (一番下) には、次のように表示されます。
WARNING: StandardWrapperValve[Faces Servlet]: PWC1406: Servlet.service() for servlet Faces Servlet threw exception
java.lang.NullPointerException
at com.extremelatitudesoftware.accesscontrol.registration.RegistrationConfirmationBean.setChallengeQuestion(RegistrationConfirmationBean.java:61)
at com.extremelatitudesoftware.accesscontrol.registration.RegistrationConfirmationBean.fetchChallengeResponse(RegistrationConfirmationBean.java:51)
もちろん、ブラウザーでは、null ポインター例外があったことを示す一般的な 500 例外エラーが発生します。
「com.extremelatitudesoftware.els_commons.exceptions.LoginPreviouslyConfirmedException」を検出し、「おっと、これは既に確認済みです!」のようなカスタム エラー ページが必要です。
これが行われるように、クライアント/JSFレイヤーが例外を正しく「見る」ようにするために、誰かが私を正しい方向に向けることができますか?
これが問題の使用例です
。EJB 層に、ユーザーが以前にログイン アカウントを確認したかどうかを確認するメソッドがあります。そうでない場合は、リクエストを処理して新しいアカウントを確認します。彼らが古い電子メールに戻って「うーん、それをもう一度クリックしましょう」と言った場合、バックエンドはそれを検出し、JSF/クライアント層によって取得されることを意図して例外をスローし、ユーザーに通知しますアカウントがすでに確認されていること。
サンプルコードの追加:
条件をチェックし、必要に応じて例外をスローするメソッド。ほとんどの場合、これは発生しないため、誰かがアカウントを確認するたびに不必要な呼び出しを行う代わりに、このメカニズムを使用したいと考えています.
...
private void checkForPreviousConfirmation(Credentials cr)
throws LoginPreviouslyConfirmedException {
if (!(CredentialsStatusType.PENDING.equals(cr.getStatus()))
|| !(CredentialsDispositionType.WAITING.equals(cr.getDisposition()))) {
String msg = "Attempting to confirm previously confirmed login using "
+ "confirmation UUID: " + cr.getConfirmationUuid();
Logger.getLogger(CredentialsController.class.getName()).log(Level.INFO,
msg);
throw new LoginPreviouslyConfirmedException(msg);
}
}
カスタム例外:
public class LoginPreviouslyConfirmedException extends RuntimeException {
public LoginPreviouslyConfirmedException(String msg, Throwable cause) {
super(msg, cause);
}
public LoginPreviouslyConfirmedException(String msg) {
super(msg);
}
}
これは、JSF 層の ManagedBean にあります。次の方法で呼び出されます: preRenderView
...
public void fetchChallengeResponse() {
try {
crespList = regFacade.fetchChallengeResponse(confirmUuid);
} catch (LoginPreviouslyConfirmedException ex) {
String msg = "Attempting to confirm previously confirmed login using " + "confirmation UUID: " + getConfirmUuid();
Logger.getLogger(RegistrationConfirmationBean.class.getName()).log(Level.SEVERE, msg, ex);
FacesContext facesContext = FacesContext.getCurrentInstance();
Application application = facesContext.getApplication();
NavigationHandler navigationHandler = application.getNavigationHandler();
navigationHandler.handleNavigation(facesContext, null, "faces/errorpages/already_confirmed.xhtml");
facesContext.renderResponse();
}catch (Exception ex){
String msg = "Including this to see if the previously confirmed exception was skipped over";
Logger.getLogger(RegistrationConfirmationBean.class.getName()).log(Level.SEVERE, msg, ex);
}
this.setChallengeQuestion();
}
ログには次のように表示されます。
INFO: Attempting to confirm previously confirmed login using confirmation UUID: b90b33ca-dc69-41c1-9c60-99152810c89b
WARNING: EJB5184:A system exception occurred during an invocation on EJB CredentialsController, method: public java.util.ArrayList com.extremelatitudesoftware.security.auth.CredentialsController.fetchChallengeResponseByCredentialUuid(java.lang.String) throws com.extremelatitudesoftware.els_commons.exceptions.LoginPreviouslyConfirmedException
WARNING: javax.ejb.TransactionRolledbackLocalException: Exception thrown from bean
次に、いくつかトレースします。
SEVERE: Including this to see if the previously confirmed exception was skipped over
javax.ejb.EJBTransactionRolledbackException
BalusC の提案に従って、ManagedBean のコードを次のように変更しました。
public void fetchChallengeResponse() throws LoginPreviouslyConfirmedException{
crespList = regFacade.fetchChallengeResponse(confirmUuid);
this.setChallengeQuestion();
}
これは web.xml にあります
<error-page>
<exception-type>com.extremelatitudesoftware.els_commons.exceptions.LoginPreviouslyConfirmedException</exception-type>
<location>/errorpages/already_confirmed.xhtml</location>
</error-page>