Not getting 'Page Not Found' with JSF2.0 - jsf-2

I'm trying with Javaee6 with GlassFish3.1.
I created a web project (with JSF2.0), with only one file, one.xhtml
<?xml version="1.0" encoding="ISO-8859-1" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html">
<h:head>
<meta http-equiv="Content-Type"
content="text/html; charset=ISO-8859-1" />
<title>ONE</title>
</h:head>
<h:body>
<h:form id="oneForm">
<h:commandButton id="oneButton" value="To Two" action="two" />
</h:form>
</h:body>
</html>
I've not added web.xml, as it is optional for javaee6.
I added faces-config.xml, so that default servlet mapping works. (with only top element)
<faces-config version="2.0" .../>
When I hit command-button on the page, I'm expecting 'Page Not Found' error. But the page just reloads. If I actually put file two.xhtml, it works correctly, but in it's absence, does not give error, which I'm expecting.
Am I missing something, some config?
Thanks in advance.

This is expected. JSF works with so-called navigation cases. If it doesn't find a matching case, it will just postback to the same view. This is specified in the JSF 2.0 specification (pick the one for evaluation).
7.4.2 Default NavigationHandler Algorithm
...
The default NavigationHandler implementation must behave as if it were performing the following algorithm (although optimized implementation techniques may be utilized):
If no navigation case is matched by a call to the handleNavigation() method, this is an indication that the current view should be redisplayed. As of JSF 2.0, a null outcome does not unconditionally cause all navigation rules to be
skipped.
...
However, when you set the JSF project stage to Development by a context parameter in web.xml,
<context-param>
<param-name>javax.faces.PROJECT_STAGE</param-name>
<param-value>Development</param-value>
</context-param>
then clicking the button should then result in a development warning message in the postback,
Unable to find matching navigation case with from-view-id '/one.xhtml' for action 'two' with outcome 'two'
so that eventual developer mistakes are at least put in attention.

Related

Images ad richfaces component are not displaying in JSF2 [duplicate]

I am using PrimeFaces 3.4 in my web app and for a particular page the controls are not displayed with the normal PrimeFaces skin:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:p="http://primefaces.org/ui">
<h:head>
<title>VMS login</title>
</h:head>
<h:body>
  <h:form id="loginForm">
    <p:messages id="messages" showDetail="true" autoUpdate="true" closable="true" />
    <p:panel header="#{msgs['login.title']}">
      <p:panelGrid id="loginPanel" columns="2">
        <h:outputText value="#{msgs['login.username']}" />
        <p:inputText id="j_username" value="#{loginFormBean.userName}" required="true"></p:inputText>
        <p:message for="j_username" ></p:message>
        <h:outputText value="#{msgs['login.password']}" />
        <p:password id="j_password" value="#{loginFormBean.password}" required="true" feedback="false"></p:password>
        <p:message for="j_password"></p:message>
        <p:commandButton action="#{loginController.loginUsingSpringAuthenticationManager}" value="#{msgs['login.button']}" update="loginForm" ajax="true"></p:commandButton>
      </p:panelGrid>
    </p:panel>
  </h:form>
</h:body>
</html>
This outputs to:
The panel should have a header and so on.
The interesting thing is that in another page where I am using a <p:layout> with different panels in the layouts they display fine with their normal PrimeFaces look-and-feel.
What am I doing wrong? Thank you
Given that it only occurs on the login page, that can happen when the authentication mechanism also kicks on requests to JSF resources like CSS/JS/image files and redirects them to the login page as well. The webbrowser would then retrieve the HTML representation of the login page instead of the concrete resources. If you have investigated the HTTP traffic in the webbrowser's developer toolset, then you should have noticed that as well.
If you're using homegrown authentication with a servlet filter, then you need to tell the filter to not redirect them to the login page, but just continue them. It are those /javax.faces.resource/* URLs (you can get that URL path as constant by ResourceHandler#RESOURCE_IDENTIFIER).
if (request.getRequestURI().startsWith(request.getContextPath() + ResourceHandler.RESOURCE_IDENTIFIER)) {
chain.doFilter(request, response);
return;
}
// ...
Or if you're using container managed authentication, then you should add /javax.faces.resource/* to allowed URLs which should be skipped from login checks:
<security-constraint>
<web-resource-collection>
<web-resource-name>Allowed resources</web-resource-name>
<url-pattern>/javax.faces.resource/*</url-pattern>
</web-resource-collection>
<!-- No Auth Contraint! -->
</security-constraint>
See also Exclude css & image resources in web.xml Security Constraint.
Or when you're using 3rd party authentication framework like Spring Security, then you need to tell it the following way (assuming 3.1.0 or newer)
<http security="none" pattern="/javax.faces.resource/**" />
See also Spring Security 3.0.5.
Or when you're using PicketLink, see PrimeFaces based application with PicketLink does not show style in login page.

PreRenderView incrementally called on every postback

I have an issue with the order and number of executions of an f:event type="preRenderView".
During my search here I found as usual answers from BalusC in this and this post related to my problem - still it leaves two questions for me:
When I put one f:event type="preRenderView" in the template file (for managing common tasks like checks about the user state which applies for all my views) and another f:event type="preRenderView" in each view (for handling view specific initializations), I wonder why the listener method from the view is called before the one from the template.
When I put the whole <f:metadata><f:event [..] /></f:metadata> after ui:define as suggested, it gets called twice after redirecting to that page from the login page, but when I put it one level higher after ui:composition it only gets called once.
Update: Example
The following example demonstrates the behaviour above:
This is the template file template_test.xhtml, containing a listener for preRenderViewevent calling a common method in a handler for all views:
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xml:lang="de" lang="de" xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:ui="http://java.sun.com/jsf/facelets">
<h:head>
<link rel="stylesheet" type="text/css" href="../resources/css/style.css" />
</h:head>
<h:body>
<f:event type="preRenderView" listener="#{testHandler.initCommon()}" />
<div id="content">
<ui:insert name="content" />
</div>
</h:body>
</html>
This is the view file test.xhtml, containing also a listener for preRenderViewevent calling a view specific method in a handler and a command button redirecting via a handler method:
<?xml version="1.0" encoding="UTF-8"?>
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:ui="http://java.sun.com/jsf/facelets"
template="template_test.xhtml">
<ui:define name="content">
<f:metadata>
<f:event type="preRenderView"
listener="#{testHandler.initIndividual()}"></f:event>
</f:metadata>
<h:form>
<h:commandButton value="Redirect" action="#{testHandler.redirect()}" />
</h:form>
</ui:define>
</ui:composition>
This is the handler class TestHandler.java containing the 3 methods:
package test;
import java.io.Serializable;
import javax.enterprise.context.SessionScoped;
import javax.inject.Named;
#Named
#SessionScoped
public class TestHandler implements Serializable {
private static final long serialVersionUID = -2785693292020668741L;
public void initCommon() {
System.out.println("Common init called.");
}
public void initIndividual() {
System.out.println("Init for individual page called.");
}
public String redirect() {
return "test/test.xhtml?faces-redirect=true";
}
}
Now, this is what I see in my tomcat log when requesting the test page:
Init for individual page called.
Common init called.
Init for individual page called.
This shows no. 1, that the event handler from the view is called before the one from the template and no. 2, that the event handler from the view is called twice.
It also shows a 3rd point (that's why I included a button with a redirect to the same page) showing what happens if the page gets requested by redirect - the individual page gets called even more times:
Init for individual page called.
Common init called.
Init for individual page called.
Init for individual page called.
Both no. 2 and 3 can be prevented by either putting the whole metadata section above the ui:define or by adding a dummy parameter to the view's metadata section which is not included in the URL:
<f:metadata>
<f:viewParam name="dummyToDenySecondRedirect" />
<f:event type="preRenderView"
listener="#{testHandler.initIndividual()}"></f:event>
</f:metadata>
Can someone tell me the reason for those cases?
I can reproduce it. This is caused by the presence of /WEB-INF/beans.xml and implicitly thus CDI. It even occurs when you switch back to standard JSF annotations while keeping the beans.xml file. This is already reported as both issue 1771 and issue 2162. However, due to absence of a concrete WAR file reproducing the issue and low votes, the Mojarra developers didn't bother to look closer at it.
I have reported it once again as issue 2719. The problem can be reproduced with a smaller example:
<!DOCTYPE html>
<html lang="en"
xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:ui="http://java.sun.com/jsf/facelets"
>
<f:metadata>
<f:event type="preRenderView" listener="#{bean.preRenderView}" />
</f:metadata>
<h:head>
<title>preRenderView fail</title>
</h:head>
<h:body>
<p>On initial request, you'll see the listener being invoked twice instead of only once.</p>
<p>On every postback by the below button, you'll see the listener being invoked once more.</p>
<h:form>
<h:commandButton value="submit" />
</h:form>
<p>Note however that this increments every time you issue the postback.</p>
<p>If you remove <code>/WEB-INF/beans.xml</code> and redeploy, then the issue will disappear.</p>
</h:body>
</html>
and
package com.example;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.RequestScoped;
#ManagedBean
#RequestScoped
public class Bean {
public void preRenderView() {
System.out.println("preRenderView called");
}
}
A missing resource may also cause the listener to be called twice. I'm using MyFaces 2.2 here:
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:ui="http://java.sun.com/jsf/facelets">
<f:metadata>
<f:event type="preRenderView" listener="#{testController.update()}" />
</f:metadata>
<h:head>
<script type="text/javascript" src="#{resource['/js/missing.js']}" />
<title>Test</title>
</h:head>
<h:body>
<p>TestController.update() is called twice.</p>
</h:body>
</html>
Obviously, you shouldn't include any missing or obsolete resources in the first place. But let's say you have (by mistake) and your listener gets called twice on and on, you have no chance to find the actual cause of that problem. JSF shouldn't do this.

How to redirect root of the project to specific page in a Primefaces+JSF2.0 application using JBOSS 7

I have a Primefaces+JSF web site whose home page is
localhost:81/Mywebapp/login.jsf
I want to redirect the user to that home page if he goes to: localhost:81/Mywebapp/ so he doesnt need to write the complete URL.
How can I do that? I suppose it is some configuration in JBoss
Any help? thanks
Actually it should be in your web.xmlfile, try to put to it's end this entry
<welcome-file-list>
<welcome-file>/login.jsf</welcome-file>
</welcome-file-list>
EDIT
I also solved this once by making a new index.jsp like this
<%#page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>JSP Page</title>
</head>
<body>
<jsp:forward page="/login.jsf" />
</body>
</html>
Or put there a html file with this meta
<meta http-equiv="Refresh" content= "0; URL=login.jsf"/>
and set one of them as your welcome file. One of these solutions should do the job for you:-)
Sorry for the second answer, the formatting in the comments doesn't really cut it:
<welcome-file-list>
<welcome-file>index.xhtml</welcome-file>
</welcome-file-list>
...
<context-param>
<param-name>javax.faces.DEFAULT_SUFFIX</param-name>
<param-value>.xhtml</param-value>
</context-param>
...
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>*.xhtml</url-pattern>
<url-pattern>*.jsf</url-pattern>
<url-pattern>subdir/*</url-pattern>
</servlet-mapping>
Peter's answer should work just fine, but if you're really concerned about the extensions (it doesn't really matter) then just add the places you want mapped under the servlet. This maps *.xhtml, *.jsf and anything under 'subdir/'.
If you had a hard file:
- index.xhtml
Myapp/index.xhtml and
Myapp/index.jsf
would map to the same file. xhtml is since your default suffix is xhtml
I hope this helps, honestly, with Primefaces 2 I'd definitely be using xhtml as that's the spec. With 3 it doesn't matter as much, but I still stay with xhtml as it isn't something I'd normally have on my server.
Best of luck (Petr's forwarding trick isn't a bad idea--it can really help in tough situations)
You can always do this with URL rewriting engines like PrettyFaces. You have to activate it in your web.xml and then define rewriting rules like this:
<url-mapping id="login">
<pattern value="/login" />
<view-id value="/legacy/user/login.xhtml" />
</url-mapping>
Because you mentioned explicitly login.jsf I think it's a good idea to think about including a security framework which is doing this (and many other things) for you. Seam security provides typesafe annotations for this:
#ViewConfig
public interface SeamPages
{
static enum Pages0
{
#ViewPattern("/jsf/admin/important.xhtml")
#UrlMapping(pattern="/admin/important")
#LoginView("/jsf/access/loginRequired.xhtml")
#AccessDeniedView("/jsf/access/accessDenied.xhtml")
#RestrictAtPhase(PhaseIdType.RESTORE_VIEW)
#LoggedIn
ENUM0;
}
}
This will solve three common requirements:
The URL /yourApp/admin/important will be redirected to the JSF page /jsf/admin/important.xhtml.
If the user is not #LoggedIn he will be redirect to /jsf/access/loginRequired.xhtml
IF the user does not have the rights to access the page he will be redirected to /jsf/access/accessDenied.xhtml

<a href> link navigation doesn't detect templates in JSF 2.0 Facelets pages

<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:ui="http://java.sun.com/jsf/facelets">
<h:body>
<title><ui:define name="title">Page 2</ui:define></title>
<ui:composition template="template/common/commonLayout.xhtml">
<ui:define name="content">
This is the content of Page 2 page<br/>
<h:form prependId="false">
<h:commandButton id="goToIndex" value="Go to Index" action="index" />
</h:form>
Index
</ui:define>
</ui:composition>
</h:body>
</html>
I have two identical facelets pages: index.xhtml and page2.xhtml which link to each other. I also have a template file. There is no difference in the code between index and page2, apart from the name of the pages in the title, content text and commandButton values.
When I click on the goToIndex button implemented by the form to navigate to index.xhtml, everything works as expected: it goes to index.xhtml. However, when I click on the link implemented by the [a href] link to navigate to index.xhtml, it goes to index.xhtml but seems to ignore all the template settings for the page, including any form tag. The only thing rendered is the text confined in the "content" definition, but without any css formatting whatsoever.
This thing happens both way round. "index -> page2" and "pag2 -> index"
Any idea why this occurs?
The page that is called by <a href ...> isn't processed by the faces servlet and therefore not correctly translated and no css/js included.
Look in your web.xml and check how the faces servlet is mapped. There you might find something like:
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>/faces/*</url-pattern>
</servlet-mapping>
You could change the pattern to:
<url-pattern>*.xhtml</url-pattern>
Then all files with the xhtml prefix will be processed by the faces servlet. However this could cause problems if in you project the xhtml prefix is used for other purposes than facelets.
Another way would be to use h:link instead of a:href:
<h:link value="Index" outcome="index" >
where the outcome attribute takes the target page without .xhtml.

JSF2.0: EL are not resolved in a Composite Component taglib

I'm trying to create a custom composite component taglib in my office but i get a strange issue with EL. It seems expressions as #{cc.attrs.[var] } are already resolve as empty.
I try to create my taglib in a jar. In my jar i have my files ordered as following:
|_ /
.....|_ META-INF
..........|_ compo.taglib.xml
..........|_ resources
...............|_ components
....................|_ hello.xhtml
compo.taglib.xml contains:
<facelet-taglib xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facelettaglibrary_2_0.xsd"
version="2.0">
<namespace>http://www.example.com/jsf/compo</namespace>
<composite-library-name>compo</composite-library-name>
<tag>
<tag-name>hello</tag-name>
<source>./components/hello.xhtml</source>
</tag>
</facelet-taglib>
hello.xhtml contains:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:composite="http://java.sun.com/jsf/composite">
<composite:interface name="hello" displayName="hello">
<composite:attribute name="name" required="true" type="String"/>
</composite:interface>
<composite:implementation >
hello #{cc.attrs.name}!
</composite:implementation>
</html>
My web project contains in WEB-INF lib my taglib as a jar, jsf-impl.jar and jsf-api.jar (from Mojarra) my page is simply that:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:comp="http://www.example.com/jsf/compo" >
<body>
<comp:hello name="John"></comp:hello>
</body>
</html>
At rendering i see "hello !" but not "hello John!". Attributes values seems be lost somewhere. I try this sample on tomcat 6.0.29 and Websphere 7.
I made something wrong?
Have you tested your control in web application rather than from taglib (jar file)?
I can only guess but I think your attribute is not showing because you named it name. In some cases "name" attribute is beeing used by JSF (for example in f:attribute or f:param or even ui:param uses attribute name). Try to replace attribute name with oder word.
You need to look here and check if attribute name is available.
Yes this case appears also with other attributes.
I tried with the component in web application and issue doesn't appear.
I also tried with the component in a jar with default namespace: issue doesn't appear. I think there is bug when using composite component in a jar with custom namespace.

Resources