Display sendError message on xhtml page - jsf

My error page is not displaying error message sent by senderror method. Error Page :
<h:head>
<title>Error Page</title>
</h:head>
<h:body>
<p>Error : #{requestScope['javax.servlet.error.message']}</p>
<h:outputText value="#{requestScope['javax.servlet.error.message']}" />
</h:body>
I am sending error like this from a filter
((HttpServletResponse) response).sendError(-1, "You do not have a active session to access this page.");
The correct page is rendered but I can only see Output as :
Error :
But the error message from javax.servlet.error.message is not printed.

This suggests that the FacesServlet isn't being invoked on the error page request while that's the one responsible for parsing all JSF tags and EL expressions in that XHTML file and producing HTML output. To confirm this, rightclick error page in browser and do View Source; you should not see any JSF/EL things in there, but pure JSF-generated HTML output.
You need to make sure that the <error-page><location> in web.xml matches the <url-pattern> of the FacesServlet as defined in web.xml. If you for example mapped it on an URL pattern of /faces/*, then the error page location must be like /faces/error.xhtml. Otherwise, change the FacesServlet mapping to *.xhtml, so that you never need to worry about virtual URLs.
That said, -1 is absolutely not a valid HTTP status code to start with. Something in 4xx range is more appropriate for this. E.g. 400 or perhaps 401 depending on how you're doing authentication.

Related

h:body not rerendered when using FullAjaxExceptionHandler

I'm using the OmniFaces FullAjaxExceptionHandler to display error pages. The error pages are shown correctly, but I'm having issues with the styling of those pages.
My application is using a template which has CSS classes defined on the body element. These classes are different for normal and error pages:
Normal page:
<h:body styleClass="main-body layout-compact">
Error page:
<h:body styleClass="exception-body error-page">
When the FullAjaxExceptionHandler processes an exception, a forward to the error page is performed (based on the <error-page> mechanism in web.xml). Apparently this does not rerender the <h:body> tag, because when checking the HTML output, I can see that the <body> tag still contains the CSS classes from the normal page (instead of the classes of the error page).
It seems that the content of the original <h:body> is replaced with the content of the error page <h:body> instead of just replacing the full <h:body>. I don't know if this is default JSF / FullAjaxExceptionHandler behaviour.
Is there any way to have the <h:body> rendered with the correct CSS classes? Moving the CSS classes away from <h:body> is not an option.
This is unfortunately "by design". JSF doesn't replace the entire document when performing ajax navigation, but it only replaces the children of individual <head> and <body> elements, leaving the parents untouched. This is done so for historical reasons; older Internet Explorer versions namely doesn't support replacing them altogether.
What I have done myself is to simply put the style into the <main> element instead. The <header> and <footer> are usually identical anyway in the final HTML output. Basically:
<html>
<head>
<title>...</title>
</head>
<body>
<header>...</header>
<main class="#{page.type}">...</main>
<footer>...</footer>
</body>
</html>
If you really need to have the <body class> modified, then your best bet is to do so via JavaScript embedded in the error page template.
<h:outputScript rendered="#{faces.ajaxRequest}">
document.body.className = "exception-body error-page";
</h:outputScript>
Note: #{faces} is only available since OmniFaces 2.5, if you're using an older version, use instead #{facesContext.partialViewContext.ajaxRequest}).

Prevent home (welcome file) URL from changing to full URL when submitting a JSF form

I've a welcome file
<welcome-file-list>
<welcome-file>configurationClass.xhtml</welcome-file>
</welcome-file-list>
It is opening properly on start with url "http://127.0.0.1:8080/fav/".
Then in my page, i am having a sortable table which is calling to a method sortFavs() present in my class. And i am returning null from server method.
So url is changing to "http://127.0.0.1:8080/fav/configurationClass.xhtml"
Can i get the same output with previous url? How to do this without using any other lib like omnifaces or others ?
Add <f:ajax execute="#form" render="#form" /> to the command button/link. This way the POST request will be performed asynchronously instead of synchronously and the browser's address bar URL will stay the same all time.

Why does this text not appear in JSF?

I have the following HTML file:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html>
<html
xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
>
<head>
<title>First Example JSF Program</title>
<head>
<body>
Hello <h:outputText value="Darwin"></h:outputText>!
</body>
</html>
But the output, expected 'Hello Darwin!' won't appear. Only 'Hello !' appears. Why is this? There are no errors and I'm sure it has all JAR files necessary - if it didn't it would throw an error right?
Cheers
P.S. This is an HTML 5 file, does that make a difference?
That can happen if the request URL as you see in browser's address did not match the <url-pattern> of the FacesServlet as definied in webapp's web.xml and hence the FacesServlet wasn't able to do its job of performing all the JSF works.
If you right click the page in browser and do View Source, you should have noticed that the JSF <h:outputText> tag is completely unprocessed. JSF tags aren't recognized by the webbrowser. They are supposed to be processed by the FacesServlet in the webserver. They are supposed to generate proper HTML code and the final HTML result should not contain any JSF tags at all.
You need to make sure that the request URL as you see in browser's address matches the <url-pattern> of the FacesServlet as definied in webapp's web.xml. Imagine that it is *.jsf like as
<url-pattern>*.jsf</url-pattern>
then you should need to change the URL in the address bar from /some.xhtml to /some.jsf.
Alternatively, you could also just change the web.xml to map the FacesServlet on *.xhtml directly
<url-pattern>*.xhtml</url-pattern>
so that you don't need to fiddle with virtual URLs anymore.
As to the file having HTML5 doctype, no that makes absolutely no difference. I'd only remove that XML prolog as that's valid for XHTML doctype only. See also Is it possible to use JSF+Facelets with HTML 4/5?

JSF view parameters and h:form action

this question is "extending" the following post
Handling view parameters in JSF after post
Asume that I'm creating an custom URL that I'm opening in a dialog.
URL example "test.html?id=123"
I want to insert the "id=123" part into the h:form action so that it returns back to the same view with the extra parameter "id=123" part.
I have followed the above post and worked on the third solution, the custom ViewHandler that extends ViewHandlerWrapper.
I'm modifying the action and the form gets redirected to the same origin (until now it works).
First issue
Lets say I have the following xhtml page.
<f:metadata>
<f:event type="preRenderView" listener="#{bean.init}" />
<f:viewParam name="id" value="#{bean.id}"/>
</f:metadata>
<h:form>
...
...
</h:form>
When i post the above i get the correct id value on the back end.
If i resubmit the post i get null values, the url however stays the same (test.html?id=xxx)
Cant figure out why i'm getting null values on the second submit
Second issue is that when I have validated the form and everything is fine, my submit method returns back a new url "test.html?force-redirect=true..." but this does not happen, instead the URL is the same as the one entered in the h:form action, (if i make a custom redirect with the new URL then it works and i get redirected to "test.html?faces-redirect=true...").
My question, I guess is a theoretical one, is this the supposed behavior?
Thanks,
Dimman

JSF1.2 to JSF2.1 migration: Using a4j:ajax / f:ajax on First page causes: "ReferenceError: RichFaces / jsf is not defined"

I am migrating JSF1.2 application to JSF 2.1. It has a Login page, which uses facelets template. And the template page has h:head tag. Login page has a tag h:selectBooleanCheckbox inside ui:composition/ui:define/h:form/a4j:outputPanel/h:panelGrid/h:panelGroup tags.
<h:selectBooleanCheckbox value="#{bean.alogin}" >
<a4j:ajax event="click" execute="#form" render="loginPanel" />
</h:selectBooleanCheckbox>
On click of check box, I am getting 'ReferenceError: RichFaces is not defined' in Browser Error Console.
The issue is same even with using f:ajax tag, and having
<h:outputScript name="jsf.js" library="javax.faces" target="head"/>
in template page/login page.
This issue (of not finding/loading js libs) is coming only on the First load of Login page. That means if I login to my application and logout and then use the above check box, there is no issue.
Please direct with any pointers and that will be very helpful.
Thanks very much in advance.
And following is the html generated in head tag:
<script src="/myapp/javax.faces.resource/jsf.js.faces?ln=javax.faces" type="text/javascript"><!--
//--></script>
I have the two *.faces mappings in web.xml. One is CustomFilter (implementing javax.servlet.Filter) and the other is CustomServlet (extending org.apache.myfaces.webapp.MyFacesServlet).
ReferenceError: RichFaces / jsf is not defined
This is a JavaScript error. This means that neither var RichFaces = ...; nor var jsf = ...; is anywhere been defined in JavaScript context. This in turn means that auto-including the JSF and RichFaces-provided JavaScript files jsf.js and richfaces.js has failed. This can in turn be caused by not having used the <h:head> component to declare the HTML head which is a mandatory hook for JSF to auto-include JavaScript files.
Apparently you forgot to replace the
<head>
...
</head>
in your templates by
<h:head>
...
</h:head>
Fix it accordingly.
Using <h:outputScript name="jsf.js" library="javax.faces" target="head"/> only fixes the JSF part of the error, not the RichFaces part and is actually a workaround, not a solution.
Update: as per your question update, you confirmed that you've mapped sort of a login Filter on the exact URL pattern of those resources (at least, the filter name "session filter" in combination with the problem symptoms described so far indicates that you're blocking requests whereby the user is not logged-in). JSF resources are served by *.faces URL pattern through the FacesServlet as well and thus they are checked by that filter as well (if you have studied the generated <script src> URL closely, you'd have realized that).
You likely need to alter your Filter to skip the logged-in check on those resources so that those resources won't be redirected to the login page as well. You could do that by checking if the request URI does not concern the ResourceHandeler.RESOURCE_IDENTIFIER URLs.
#Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest) request;
HttpServletResponse res = (HttpServletResponse) response;
if (req.getRequestURI().startsWith(req.getContextPath() + ResourceHandler.RESOURCE_IDENTIFIER)) {
chain.doFilter(request, response); // Skip JSF resources (CSS/JS/Images/etc)
return;
}
// ... Continue your login check here.
}

Resources