私は個人的に別の方法で実装します。次のように
はあなたのfaces-config.xml
で例外ハンドラファクトリを定義します。
<factory>
<exception-handler-factory>
com.package.faces.FullAjaxExceptionHandlerFactory
</exception-handler-factory>
</factory>
はjavax.faces.context.ExceptionHandlerFactory
を拡張し、例外ハンドラファクトリを作成します。 ExceptionHandlerの独自の実装が返されます。これは、例えば次のようになります。
import javax.faces.context.ExceptionHandler;
import javax.faces.context.ExceptionHandlerFactory;
public class FullAjaxExceptionHandlerFactory extends ExceptionHandlerFactory {
private ExceptionHandlerFactory wrapped;
/**
* Construct a new full ajax exception handler factory around the given wrapped factory.
* @param wrapped The wrapped factory.
*/
public FullAjaxExceptionHandlerFactory(ExceptionHandlerFactory wrapped) {
this.wrapped = wrapped;
}
/**
* Returns a new instance of {@link FullAjaxExceptionHandler} which wraps the original exception handler.
*/
@Override
public ExceptionHandler getExceptionHandler() {
return new FullAjaxExceptionHandler(wrapped.getExceptionHandler());
}
/**
* Returns the wrapped factory.
*/
@Override
public ExceptionHandlerFactory getWrapped() {
return wrapped;
}
}
最後に、すべての例外を処理するためにjavax.faces.context.ExceptionHandlerWrapper
を拡張します。例は次のとおりです。
public class FullAjaxExceptionHandler extends ExceptionHandlerWrapper {
private ExceptionHandler wrapped;
public FullAjaxExceptionHandler(ExceptionHandler wrapped) {
this.wrapped = wrapped;
}
private static Throwable extractCustomException(Throwable ex) {
Throwable t = ex;
while (t != null) {
if (t instanceof YourOwnExceptionInterface) {
return t;
}
t = t.getCause();
}
return ex;
}
private static String extractMessage(Throwable t) {
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
t.printStackTrace(pw);
return matchJmillErrorTag(sw.toString());
}
public static boolean handleException(Throwable original) {
Throwable ex = extractCustomException(original);
if (ex instanceof ViewExpiredException) {
// redirect to login page
return false;
} else if (ex instanceof YourOwnExceptionInterface) {
((YourOwnExceptionInterface) ex).handle();
return true;
} else if (ex instanceof NonexistentConversationException) {
FacesContext.getCurrentInstance().getExternalContext().invalidateSession();
// redirect to login page
return false;
} else {
String message = extractMessage(ex);
final FacesContext fc = FacesContext.getCurrentInstance();
original.printStackTrace();
// redirect to error page
fc.responseComplete();
return true;
}
}
@Override
public void handle() throws FacesException {
final Iterator<ExceptionQueuedEvent> i = getUnhandledExceptionQueuedEvents().iterator();
FacesContext facesContext = FacesContext.getCurrentInstance();
if (Redirector.isRedirectingToLogin(facesContext)) {
return;
}
while (i.hasNext()) {
ExceptionQueuedEvent event = i.next();
ExceptionQueuedEventContext context = (ExceptionQueuedEventContext) event.getSource();
i.remove();
if (!handleException(context.getException())) {
return;
}
}
getWrapped().handle();
}
@Override
public ExceptionHandler getWrapped() {
return wrapped;
}
}
前のクラスのpublic static boolean handleException(Throwable original)
を確認してください。それを使ってすべての例外を管理することができます。
私はについての条件を置いています。これは、たとえばNotAuthorizedException
種類の例外によって実装されるhandle()
メソッドのインターフェイスです。この場合、NotAuthorizedException
のhandle()
メソッドでは、たとえばp:growlコンポーネントを使用して特定の操作を完了できないことをユーザーに通知します。私は豆の中でこれを使用したいと思います。throw new NotAuthorizedException("message");
カスタム例外クラスはもちろんRuntimeException
を拡張する必要があります。
'other.xhtml'はログインが必要な保護されたページですか?なぜプラットフォームをテストしているのですか?注意これはJSFとは関係ありません。これは、Tomcatやサーブレットコンテナが何であれ強制されます。 – EJP
@EJP:admin.xhtmlは、ログインに成功した後に表示されるページです。 admin.xhtmlでセッションタイムアウトが機能しているかどうかを確認するためのリンクを1つ追加しました。保護された種類のページではありません。 –