Oluşan hataları yakalamak ve özelleştirmek için ExceptionHandlerFactory ve ExceptionHandlerWrapper sınıfı aşağıdaki gibi kullanılabilir:
import java.util.Iterator;
import javax.faces.FacesException;
import javax.faces.context.ExceptionHandler;
import javax.faces.context.ExceptionHandlerWrapper;
import javax.faces.context.FacesContext;
import javax.faces.event.ExceptionQueuedEvent;
import javax.faces.event.ExceptionQueuedEventContext;
public class CustomExceptionHandler extends ExceptionHandlerWrapper {
private ExceptionHandler exceptionHandler;
public CustomExceptionHandler(ExceptionHandler exceptionHandler) {
this.exceptionHandler = exceptionHandler;
}
@Override
public ExceptionHandler getWrapped() {
return exceptionHandler;
}
@Override
public void handle() throws FacesException {
FacesContext fc = FacesContext.getCurrentInstance();
for (Iterator<ExceptionQueuedEvent> i = getUnhandledExceptionQueuedEvents().iterator(); i.hasNext();) {
ExceptionQueuedEvent event = i.next();
ExceptionQueuedEventContext context = (ExceptionQueuedEventContext) event.getSource();
Throwable t = context.getException();
t.printStackTrace();
Throwable c=t.getCause();
if(c!=null){
c.printStackTrace();
}
}
}
}
Factory sınıfı ise :
import javax.faces.context.ExceptionHandler;
import javax.faces.context.ExceptionHandlerFactory;
public class CustomExceptionHandlerFactory extends ExceptionHandlerFactory {
private ExceptionHandlerFactory exceptionHandlerFactory;
public CustomExceptionHandlerFactory() {
}
public CustomExceptionHandlerFactory(ExceptionHandlerFactory exceptionHandlerFactory) {
this.exceptionHandlerFactory = exceptionHandlerFactory;
}
@Override
public ExceptionHandler getExceptionHandler() {
return new CustomExceptionHandler(exceptionHandlerFactory.getExceptionHandler());
}
}
faces-config.xm dosyasına aşağıdaki gibi ekleme yapılması gerekir:
<factory>
<exception-handler-factory>com.fibiler.CustomExceptionHandlerFactory</exception-handler-factory>
</factory>
Artık herhangi bir exception oluşursa CustomExceptionHandler sınıfının handle() yöntemi çağrılacaktır. Basit olarak sadece çıktıya stack trace basılmıştır. Bunun yerine bir sayafa yönlendirilebilir, veritabanına exception loglanabilir, exception tipine göre alarm üretilebilir.
Handler aşağıdaki gibi değiştirilerek bir sayfaya yönlendirme yapabiliriz:
try{
Flash flash = fc.getExternalContext().getFlash();
flash.put("errorMessage", t.getMessage());
flash.put("errorDetails", Arrays.toString(t.getStackTrace()));
NavigationHandler navigationHandler = fc.getApplication().getNavigationHandler();
navigationHandler.handleNavigation(fc, null,
"/error.jsf?faces-redirect=true");
fc.renderResponse();
}catch(Exception e){
e.printStackTrace();
}
Aşağıdaki gibi bir error.jsf olabilir. (Primefaces kullanılmaktadır standart JSF olabilir)
<h:body>
<h1>HATA</h1>
<p:panel header="#{msg['error.caption.cause']}">
<h:outputText value="#{flash.keep.errorMessage}" style="white-space: pre-wrap;" />
</p:panel>
<p:panel toggleable="true" collapsed="true" header="#{msg['error.caption.detail']}">
<h:outputText value="#{flash.keep.errorDetails}" style="white-space: pre-wrap;" />
</p:panel>
</h:body>