Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Problems with redirect after catching Exception

Tags:

jsf-2

I have a problem with the redirect in my custom ExceptionHandler. The ExceptionHandler should handle NullPointerExceptions and perform a redirect if an exception occures. Here is the part of the Handler that is responsible for the redirect:

FacesContext fc = FacesContext.getCurrentInstance();
NavigationHandler nav = fc.getApplication().getNavigationHandler();
nav.handleNavigation(fc, null, "error" );

I have a simple page to test the ExceptionHandler:

<h:outputText value="#{requestTestBean.firstname}" />

And in the getter-Method for firstname I force a NullPointerException:

Object x = null;
x.toString();

The redirect to my error page works fine for this little example but when I add considerable more content on the page (like a menu with many entries and icons) the redirect doesn't work because the response is already commited in the exceptionHandler method. I also tried to redirect to the error page via response.sendRedirect() but the same problems occured.

Why is the response already commited? Is there any context-param or anything else to prevent this behavior?

Thanks

like image 789
Melanie Kirchner Avatar asked Feb 16 '26 07:02

Melanie Kirchner


1 Answers

That's one of the many reasons why doing business logic inside getters is a very bad idea.

But OK, let's assume that this is a really extreme requirement/usecase where poorly developed code is involved (you know, runtimeexceptions like NPE's are actually developer errors). The response will be committed when a certain response body buffer limit has been exceeded. This is usually around 2KB and the real default value is configureable at appserver level. But you can also configure it by a context param with the name javax.faces.FACELETS_BUFFER_SIZE which accepts the buffer size in bytes. Here's an example which sets it to 1MB.

<context-param>
    <param-name>javax.faces.FACELETS_BUFFER_SIZE</param-name>
    <param-value>1048576</param-value>
</context-param>

It will under the covers set the ServletResponse#setBufferSize() on every response.

Again, this is actually a workaround to your concrete problem and thus a poor approach. The real problem should be fixed in the code by letting the getters just return the bean properties and nothing else. The business logic needs to be done in the bean's constructor, postconstruct or any event (action) methods. They are executed far before the render response phase and thus you have all the chance to handle the exception.

like image 104
BalusC Avatar answered Feb 18 '26 19:02

BalusC



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!