Can not access the javax.servlet.error.* for error code 500 in JSF 2.2 with PrimeFaces 5.1 - jsf

I am working on JSF 2.2 with PrimeFaces 5.1, in my application for exception handling I have configured error code 500 in web.xml like below
<error-page>
<error-code>500</error-code>
<location>/500.xhtml</location>
</error-page>
and in 500.xhtml I am trying to access error code like below
<h:outputText value="#{requestScope['javax.servlet.error.status_code']}"></h:outputText>
at the time of testing I found that, I was redirected to a url like below
https://localhost:8443/appname/500.xhtml
which is wrong it should like https://localhost:8443/appname/configerd_path
and here I found that in requestScope I don't have javax.servlet.error.*
so I cannot display error code, error message and so on ...
I would like to ask here that, what is the best practice to handle this kind of error in JSF 2.2 and how can I access error code and error message ?

As I am using primefaces and it's provides a built-in exception handler to take care of exceptions in ajax and non-ajax request easily.
with the following EL, I am able to catch exception at my 500.xhtml page.
<h:outputText value="#{pfExceptionHandler.exception}" ></h:outputText>
<h:outputText value="#{pfExceptionHandler.type}"></h:outputText>
<h:outputText value="#{pfExceptionHandler.message}" ></h:outputText>
I hope it helps others :-)

Related

Omnifaces ViewScoped generates a POST call

My app is using Tomee 7.0.5, Java 8, MySql, JSF 2.2, Omnifaces 2.7. Primefaces 6.1, Prettyfaces 3.3.3. I tried to use Omnifaces' ViewScoped annotation together with #Named in my backing bean. It is required to use OWASP to validate requests. For some unknown reason a click on a link is converted to a POST request and since this link is used to navigate to another page there is no token yet in the request and so the validate request fails. Now, if I use javax.faces.view.ViewScoped instead everything is fine. I have 12 applications with the same pattern.
Each app has a template with a p:toolbar and links to navigate like:
<h:link outcome="pretty:search" value="Search"
onclick="showSpinningIcon();return true;" />
No errors in Chrome console. what am I missing here?

JSF 1.2 Error handling with IceFaces 1.8

my project is on JSF 1.2 and IceFaces. It works perfectly. I thought of adding error pages, to avoid showing that ugly exceptions page.
This is what I did :
web.xml
<error-page>
<exception-type>java.lang.Exception</exception-type>
<location>/error.xhtml</location>
</error-page>
error.xhml
<html>
<body>
<center>
<h1> HELLO THIS IS AN ERROR</h1>
</center>
</body>
I made a link in the application that generates the exception. But when I click on it, I just get nothing, neither the Hello message, neither the classic exception stack trace message.
Should I add some code to FacesConfig or something?

ViewExpiredException with tracking mode URL in Glassfish3

our customer doesn't want to have session handling with cookies and it also will cause problems with an Apache/mod_rewrite gateway, so i tried to use
<tracking-mode>URL</tracking-mode>
in our web.xml. That should be all with Glassfish3/Servlet 3.0. However now i get ViewExpiredExceptions when trying to log in(it's not an AJAX request):
<p:commandButton id="submit"
value="${msg['Login.submit.label']}"
action="#{loginBean.login}"
ajax="false"/>
I also tried to save the session on the client side, than i can see the JSESSIONID in the URL but that throws NotSerializableExceptions for my #EJBs. Any ideas? Do i miss something? It used to work fine with the cookies.
UPDATE: LoginBean.login returns "Home.xhtml?faces-redirect=true", expected behaviour when clicking the commandButton: POST on Login.xhtml, my login page, redirect and GET on Home.xhtml.
SECOND UPDATE:
Looks like my action never gets called, i'm directly getting the ViewExpiredException and a HTTP 500 error code.
THIRD UPDATE:
Looks like the HttpSession is always null with tracking mode set to URL, with cookies the HttpSession is correctly created. Shouldn't the FacesServlet create a session and append the JSESSIONID in the URL if there is no session?
ANOTHER UPDATE:
With
<param-name>javax.faces.STATE_SAVING_METHOD</param-name>
<param-value>client</param-value>
the session will be created on postback. But than i'm running into
java.io.NotSerializableException
.
The other option is to set restore view compability to true.
Edit your web.xml and add following code and try.
<context-param>
<param-name>com.sun.faces.enableRestoreView11Compatibility</param-name>
<param-value>true</param-value>
</context-param>
Updated:
Reference
com.sun.faces.enableRestoreView11Compatibility is a JSF 1.2 setting that tells JSF 1.2 to behave like JSF 1.1.
com.sun.faces.enableRestoreView11Compatibility == true means "do not throw a ViewExpiredException; instead, just create a new view if the old one has expired."
The IBM notes on the JSF 1.1 behaviour say:
This can have adverse behaviors because it is a new view, and items that are usually in the view, such as state, are no longer be there.
The default JSF 1.2 behaviour is defined in the spec as this:
If the request is a postback, call ViewHandler.restoreView(), passing the FacesContext instance for the current request and the view identifier, and returning a UIViewRoot for the restored view. If the return from ViewHandler.restoreView() is null, throw a ViewExpiredException with an appropriate error message. javax.faces.application.ViewExpiredException is a FacesException` that must be thrown to signal to the application that the expected view was not returned for the view identifier. An application may choose to perform some action based on this exception.
To have a ViewExpiredException thrown when the view expires, remove the com.sun.faces.enableRestoreView11Compatibility parameter or set it to false.
The com.sun namespace suggests that the parameter is a Sun/Mojarra and derived implementation-specific setting, so it probably will not work with all JSF implementations.
Fixed by updating Mojarra. My Glassfish 3.1.2.2 came with Mojarra 2.1.6 and this bug:
https://java.net/jira/browse/JAVASERVERFACES-2143
Updated to 2.1.22 and everything works.

FullAjaxExceptionHandler does not redirect to error page after invalidated session

I am having issues with the Omnifaces FullAjaxExceptionHandler (http://showcase.omnifaces.org/exceptionhandlers/FullAjaxExceptionHandler). It does not redirect to the specified error page after the session is invalidated.
I have the following in my faces-config:
<factory>
<exception-handler-factory>org.omnifaces.exceptionhandler.FullAjaxExceptionHandlerFactory</exception-handler-factory>
</factory>
And the following in my web.xml:
<error-page>
<exception-type>javax.faces.application.ViewExpiredException</exception-type>
<location>/pages/error/viewExpired.html</location>
</error-page>
After I invalidate the session, from a user's perspective nothing seems to happen. The application is just 'dead'. In my console I see the following Ajax request:
A POST to the original facelet page with a response code of 302
a GET to the login page with a code 200 (but nothing happens because it's requested via Ajax)
I am running MyFaces 2.1.10, Primefaces 3.5, Primefaces Extension 0.6.3 & Omnifaces 1.4.1 on WebLogic 12c
Could anyone help me in the right direction? How do I get the FullAjaxExeptionHandler to work properly?
Thanks
A POST to the original facelet page with a response code of 302
This is not right. A redirect on a JSF ajax request must have a response code of 200 with a special XML response with a <redirect> element with target URL in its url attribute.
This thus indicates that you manually used HttpServletResponse#sendRedirect() somewhere long before JSF has the chance to deal with ViewExpiredException.
Perhaps you've somewhere a servlet filter which checks some session attribute and sends a redirect based on its presence/state? That filter should then be manipulated based on the following answer: JSF Filter not redirecting After Initial Redirect in order to recognize JSF ajax requests and return a special XML response instead of a 302 response.
E.g.
if ("partial/ajax".equals(request.getHeader("Faces-Request"))) {
response.setContentType("text/xml");
response.getWriter()
.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>")
.printf("<partial-response><redirect url=\"%s\"></redirect></partial-response>", loginURL);
} else {
response.sendRedirect(loginURL);
}
This all is completely unrelated to the FullAjaxExceptionHandler. JSF didn't have any chance to throw a ViewExpiredException because you're already sending a redirect yourself beforehand.

Catching inner JSF exceptions and handling them on my own

I am using JSF 1.2.
I would like to be able to catch the JSF internal exceptions to produce a better looking error page and maybe try to re-load the session (Using backing bean data)
How Can I do this?
Thanks!
You didn't mention what version of JSF you are using, but in JSF 2.0 all JSF exceptions thrown by the framework are being published as events and handled by a global ExceptionHandler. You can replace this with your own implementation in faces-config.xml:
<exception-handlerfactory>
com.foo.myExceptionHandler
</exception-handlerfactory>
See this answer for some additional details: Differences between action and actionListener

Resources