how to Hide JSF URL after the application name? - jsf

i have a jsf application and i want hide the url and keep just the name of application in URL while swiching between pages .
thats the url that i have :
> http://localhost:8080/PlanificationDrapageWeb/faces/admin/adminHome.xhtml
> http://localhost:8080/PlanificationDrapageWeb/faces/cuisson/Home.xhtml
and thats what i want always have :
> http://localhost:8080/PlanificationDrapageWeb/
how can i get this result ??

As MaVRoSCy said you can use Prettyfaces to rewrite your URLs. Their docs are very useful and very clear. Here are steps to follow (without Maven dependencies approach):
1) Download latest jar depending on your JSF version and put it in your project classpath.
2) Add following to web.xml
<filter>
<filter-name>Pretty Filter</filter-name>
<filter-class>com.ocpsoft.pretty.PrettyFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>Pretty Filter</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>FORWARD</dispatcher>
<dispatcher>REQUEST</dispatcher>
<dispatcher>ERROR</dispatcher>
</filter-mapping>
3) Create under WEB-INF a file: pretty-config.xml that will define your prettyfaces mappings, like this one:
<pretty-config xmlns="http://ocpsoft.com/prettyfaces/3.3.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://ocpsoft.com/prettyfaces/3.3.0
http://ocpsoft.com/xml/ns/prettyfaces/ocpsoft-pretty-faces-3.3.0.xsd">
<url-mapping id="accueil">
<pattern value="/" />
<view-id value="/path-to-yourpage.xhtml" />
</url-mapping>
<url-mapping id="error">
<pattern value="/" />
<view-id value="/tpath-to-yourpage2.xhtml" />
</url-mapping>
</pretty-config>
4) Now when defining outcome in your managed beans, you should return pretty:idOfURLMapping. For example: pretty:accueil will redirect to the first defined page above and normally it would display http://localhost:8080/PlanificationDrapageWeb/ as URL.
Finally, notice that you should use this only if it's a functional requirement. Otherwise I would use URLs without extensions as BalusC mentioned (his method or if you want advanced Prettyfaces functionalities).
EDIT
It seems that Prettyfaces does not work for this situation. Sorry for your time wasting.
Now I would suggest another possible solution, since BalusC's answer was deleted.
1) You create a new managed bean of session scope, let's call it: PageManagedBean:
public class PageManagedBean {
private String includedPage = "/pages/accueil.xhtml";
//Setters and getters
}
2) Create a master layout page (Facelets templating):
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:p="http://primefaces.org/ui">
<h:head>
<ui:insert name="head"></ui:insert>
</h:head>
<h:body>
<div class="pagewidth">
<ui:include src="shared/header.xhtml"/>
<!-- Content -->
<div class="page_content">
<div class="page_content_inner">
<div class="container">
<ui:include id="pageLivre" src="#{pageManagedBean.includedPage}"/>
</div>
</div>
</div>
<div class="page_content_footer"/>
<ui:include src="shared/footer.xhtml"/>
</div>
</h:body>
Now when you want to change page, you just change PageManagedBean.includedPage value.

Try using prettyFaces.
PrettyFaces is an OpenSource URL-rewriting library with enhanced
support for JavaServer Faces – JSF 1.1, 1.2 and 2.0 – enabling
creation of bookmark-able, pretty URLs.
See also this UrlRewriteFilter with Glassfish a couple ways more on how to do this.
Front your GlassFish instance with Apache and use mod_rewrite
Use Tuckey's Url Rewrite Filter

Related

Omnifaces Taglib not found within EL in CustomComponent

I am currently upgrading a webapp from JBoss 7.1 to Wildfly 10.1, where I stumbled over a rather tricky problem concerning taglib resolution within an expression language within a custom component.
I managed to isolate the problem, which apparently boils down to the fact, that JSFs ExpressionBuilder cannot find the correct name spaces defined in my custom component and therefore complains that it does not know anything about the Omnifaces taglib:
javax.el.ELException: Function 'of:format1' not found
at com.sun.el.lang.ExpressionBuilder.visit(ExpressionBuilder.java:275)
at com.sun.el.parser.SimpleNode.accept(SimpleNode.java:172)
at com.sun.el.lang.ExpressionBuilder.prepare(ExpressionBuilder.java:227)
at com.sun.el.lang.ExpressionBuilder.build(ExpressionBuilder.java:238)
at com.sun.el.lang.ExpressionBuilder.createValueExpression(ExpressionBuilder.java:295)
at com.sun.el.ExpressionFactoryImpl.createValueExpression(ExpressionFactoryImpl.java:112)
at org.jboss.weld.util.el.ForwardingExpressionFactory.createValueExpression(ForwardingExpressionFactory.java:53)
at org.jboss.weld.el.WeldExpressionFactory.createValueExpression(WeldExpressionFactory.java:48)
at org.jboss.weld.util.el.ForwardingExpressionFactory.createValueExpression(ForwardingExpressionFactory.java:53)
at org.jboss.weld.el.WeldExpressionFactory.createValueExpression(WeldExpressionFactory.java:48)
at com.sun.faces.facelets.el.ELText.parse(ELText.java:411)
at com.sun.faces.facelets.el.ELText.parse(ELText.java:342)
Funny enough, that only happens if I inline the evaluation of a nested EL expression within of:format1.
A minimal example, where the problem can be reproduced, can be found at a Bitbucket repository, but here's the relevant code of my custom component:
<?xml version="1.0" encoding="UTF-8"?>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:c="http://java.sun.com/jsp/jstl/core"
xmlns:cc="http://xmlns.jcp.org/jsf/composite"
xmlns:of="http://omnifaces.org/functions">
<h:head>
<title>Testing EL</title>
</h:head>
<h:body>
<cc:interface>
<cc:attribute name="model" type="sandbox.eltest.model.Entity" required="true" />
</cc:interface>
<cc:implementation>
<div id="#{cc.clientId}">
<c:set var="value" value="#{cc.attrs.model.value}" />
#{of:format1('Hello {0}', value)} <!-- Prints "Hello World" correctly -->
#{of:format1('Hello {0}', cc.attrs.model.value)} <!-- THROWS javax.el.ELException -->
</div>
</cc:implementation>
</h:body>
</html>
The second version with the inlined cc.attrs.model.value used to work in JBoss 7.1. What am I missing here on Wildfly 10.1?

Custom tag attributes are leaking into children

Our application is using Mojarra 2.1.29-03 and we are having a problem with attributes in our custom tags as they are being copied to nested tags as well.
For example, given the following tag definition:
cc.taglib.xml
<?xml version="1.0" encoding="UTF-8" ?>
<facelet-taglib version="2.0" 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">
<namespace>http://temp.com/jsf/customcomponents</namespace>
<tag>
<tag-name>wrapper</tag-name>
<source>wrapper.xhtml</source>
<attribute>
<description>The style class for the component</description>
<name>styleClass</name>
</attribute>
</tag>
</facelet-taglib>
wrapper.xhtml
<?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">
<ui:component xmlns:ui="http://java.sun.com/jsf/facelets">
<div style="border: 1px solid black; margin: 5px;">
<p>styleClass: #{styleClass}</p>
<ui:insert />
</div>
</ui:component>
</html>
And a client page:
<?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:h="http://java.sun.com/jsf/html" xmlns:cc="http://temp.com/jsf/customcomponents">
<h:body>
<cc:wrapper styleClass="cc-style">
<cc:wrapper />
</cc:wrapper>
</h:body>
</html>
The result is as follows:
styleClass: cc-style
styleClass: cc-style
... so the styleClass attribute is also being applied to the inner tag even though the client page does not set it.
We have noted that we can workaround this by processing all our client pages to set styleClass="" if it is not explicitly set but this is an approach we would like to avoid (it's a very ugly solution and cannot be enforced going forward).
Is this a bug? Is there any way to work around it other than that mentioned above - preferably with the workaround in the tag rather than the client pages?
Thanks
Ivor
This is not strictly a bug, but this is indeed unintuitive and undesired behavior which should have been addressed in the JSF/Facelets spec.
The work around solution is not trivial, a custom taghandler is needed to clear out the Facelet scope. JSF utility library OmniFaces has since version 2.1 exactly such one: <o:tagAttribute> (source code here).
Usage (do note that prolog, doctype and html tags are unnecessary, this is the file in its entirety):
<ui:composition
xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:o="http://omnifaces.org/ui"
>
<o:tagAttribute name="styleClass" />
<div style="border: 1px solid black; margin: 5px;">
<p>styleClass: #{styleClass}</p>
<ui:insert />
</div>
</ui:composition>
Unrelated to the concrete problem, this is not a custom component, but a tagfile. And, in JSF 2.x, the term "cc" is usually associated with composite components, which is a completely different subject altogether. To get your knowledge and terminology right (so that you don't confuse yourself or others while reading your or other's code), head to When to use <ui:include>, tag files, composite components and/or custom components?
For info we identifed an alternative approach that might be of use to others as it is slightly easier to implement and understand.
First I need to add a bit of context to the situation that we found ourselves in ... we had recently migrated from 2.1.12 to 2.1.29-03 and as part of that process we changed one of our building blocks from a composite component (which has isolated scope for its attributes) to a custom tag (which has the behaviour described above). The same behaviour regarding custom tag attributes existed in 2.1.12 but we were unaware of it so we considered the following approach instead as it would restore the behaviour we had prior to migration because we would only need to apply it to the component that we changed.
wrapper.xhtml (I've changed the namespace to 'ct' rather than 'cc')
<ui:component xmlns:ct="http://temp.com/jsf/customtags" xmlns:ui="http://java.sun.com/jsf/facelets">
<ct:tagAttribute name="styleClass" />
<div style="border: 1px solid black; margin: 5px;">
<p>styleClass: #{styleClass}</p>
<ct:eraseAttribute name="styleClass" />
<ui:insert />
</div>
</ui:component>
Where tagAttribute is the solution suggested by BalusC to prevent the tag inheriting attributes from its parents and in addition we call eraseAttribute tag before calling ui:insert to remove the attribute from scope (this obviously requires that the custom tag is finished with the attribute). This means that this one tag neither inherits nor leaks attributes and other tags could remain unchanged and maintain the same behaviour they had prior to migration.
ct.taglib.xhtml (snippet)
<tag>
<tag-name>eraseAttribute</tag-name>
<handler-class>com.temp.jsf.customtags.EraseTagAttribute</handler-class>
<attribute>
<name>name</name>
<required>true</required>
<type>java.lang.String</type>
</attribute>
</tag>
EraseTagAttribute.java
package com.temp.jsf.customtags;
import java.io.IOException;
import javax.faces.component.UIComponent;
import javax.faces.view.facelets.FaceletContext;
import javax.faces.view.facelets.TagConfig;
import javax.faces.view.facelets.TagHandler;
public class EraseTagAttribute extends TagHandler {
private final String name;
public EraseTagAttribute(TagConfig config) {
super(config);
name = getRequiredAttribute("name").getValue();
}
public void apply(FaceletContext context, UIComponent parent) throws IOException {
context.getVariableMapper().setVariable(name, null);
}
}
Ultimately we did not use it however as we felt the answer provided by BalusC (which we applied to every attribute in all our custom tags) was the correct and cleaner approach even though it might have additional consequences in our very specific situation.

JSF 1.2 : Can I create reusable component inside JSF view

Is possible to something like this in jsf?
<ui:composition>
<x:reusableCode id="editScreen">InnerHtml ... </x:reusableCode>
code...
<x:use component="editScreen"/>
</ui:composition
I know I can create my own component and register it in jsf tagLib, but I need reusable HTML only in on jsf view file.
In Facelets 1.x you can create a tag file for this purpose.
Here's a basic kickoff example. Create /WEB-INF/tags/some.xhtml:
<ui:composition
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:ui="http://java.sun.com/jsf/facelets"
>
<h:outputText value="#{foo}" />
</ui:composition>
Define it in /WEB-INF/my.taglib.xml:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE facelet-taglib PUBLIC
"-//Sun Microsystems, Inc.//DTD Facelet Taglib 1.0//EN"
"http://java.sun.com/dtd/facelet-taglib_1_0.dtd">
<facelet-taglib>
<namespace>http://example.com/jsf/facelets</namespace>
<tag>
<tag-name>some</tag-name>
<source>/WEB-INF/tags/some.xhtml</source>
</tag>
</facelet-taglib>
Register it in /WEB-INF/web.xml:
<context-param>
<param-name>facelets.LIBRARIES</param-name>
<param-value>/WEB-INF/my.taglib.xml</param-value>
</context-param>
(note, when you have multiple, use semicolon ; to separate them)
Finally just declare it in your main page templates.
<ui:composition
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:my="http://example.com/jsf/facelets"
>
<my:some foo="value1" />
<my:some foo="value2" />
<my:some foo="value3" />
</ui:composition>
A more advanced example can be found here: How to make a grid of JSF composite component? Note: JSF 2.0 targeted, but with minor changes based on above example it works as good on Facelets 1.x.

ERROR: tag handler class for "rich:modalPanel" (org.richfaces.taglib.ModalPanelTag) was not found on the Java Build Path

I am trying richface 4. It seems tags class are not setting on JAVA build path. I am getting this error for all rich component: "ERROR: tag handler class for * (org.richfaces.taglib.*) was not found on the Java Build Path"
For a4j component also, for all component i am getting same error "The tag handler class for "a4j:" (org.ajax4jsf.taglib.html.jsp.) was not found on the Java Build Path"
For richface4, i performed following actoin:
1) Added following jars:
annotations-4.0.0.Final.jar
cssparser-0.9.5.jar
guava-r08-gwt.jar
guava-r08.jar
jsf-api.jar
jsf-impl.jar
richfaces-components-api-4.1.0.Final.jar
richfaces-components-ui-4.1.0.Final.jar
richfaces-core-api-4.1.0.Final.jar
richfaces-core-impl-4.1.0.Final.jar
sac-1.3.jar
commons-beanutils-1.8.3.jar
commons-collections-3.2.1.jar
commons-digester-2.1-sources.jar
commons-digester-2.1.jar
commons-discovery-0.4.jar
jhighlight-1.0.jar
jsf-facelets-1.1.14.jar
web.xml is default generated and NO new element is added. As it is not required to change in RF4 (which is required in RF3.3).
JSP file is
<?xml version="1.0" encoding="ISO-8859-1" ?>
<jsp:root xmlns:jsp="http://java.sun.com/JSP/Page" xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:f="http://java.sun.com/jsf/core" xmlns:h="http://java.sun.com/jsf/html" xmlns:a4j="http://richfaces.org/a4j" xmlns:rich="http://richfaces.org/rich" version="2.0">
<jsp:directive.page language="java"
contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1" />
<jsp:text>
<![CDATA[ <?xml version="1.0" encoding="ISO-8859-1" ?> ]]>
</jsp:text>
<jsp:text>
<![CDATA[ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> ]]>
</jsp:text>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
<title>TESTING</title>
</head>
<body>
<f:view>
<h:form>
<a4j:commandLink
value="Opss! I forgot password"
reRender="forgetPasswordPanel"
oncomplete="#{rich:component('forgetPasswordPanel')}.show()">
</a4j:commandLink>
</h:form>
<rich:modalPanel id="forgetPasswordPanel" autosized="true" width="380">
<f:facet name="header">
<h:outputText value="Reset Password"/>
</f:facet>
</rich:modalPanel>
</f:view>
</body>
</html>
</jsp:root>
i further investigated this issue and found that taglib(tld file) doesn't contain tag-class for many rich and a4j component and richFace4.1 jar does not have corrosponding java class for them (which is in richFaces 3.3 jars).
Am i missing some jars ? What else should i do to work with richface4 ?
You seem to be trying to upgrade a RichFaces 3.3 web application to RichFaces 4.1. You need to do many more changes than only replacing the JAR files. You can find the exact migration steps in their own documentation: RichFaces 3.3.x to 4.x migration guide.
For example, JSP is been deprecated and replaced by Facelets, you'd need to rewrite your JSPs to be XHTMLs. The <rich:modalPanel> is been replaced by <rich:popupPanel>, you need to find and replace all those tags accordingly. The reRender attribute is been replaced by update attribute. Etcetera. Also that jsf-facelets-1.1.14.jar which is of Facelets 1.x should be removed from the /WEB-INF/lib. JSF 2.x libraries already ships with the right Facelets 2.x implementation bundled.
See also:
Migrating from JSF 1.2 to JSF 2.0

Glassfish not display JSF components

On my index.xhtml I have Java Server Face components which are displayed correctly and use a managed bean. But if I link to any other page or even a page with the EXACT same code those pages will not display these components, only the text.
Suppose index.xhtml is like this and displays correctly:
<?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:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core">
<h:head>
<title>Facelet Title</title>
</h:head>
<h:body>
<h:form>
<h:inputText value="#{user.name}"/>
<h:commandButton action="#{user.submit}" value="Submit" />
</h:form>
</h:body>
</html>
If I add a link to any other page (even one with the same code) JSF components are not displayed for them. Is this because the other pages perhaps can't 'see' the managed bean? Or something else?
Thanks for your help.
It looks like the pages which you want to call are not processed by the Faces Servlet.
In the web.xml of your application you define the url-pattern of server requests that will be processed by this servlet. By default this is often /faces/*. This means that the link that you call must contain this pattern in order to be processed by the Faces Servlet.
If you create your project with Netbeans, the mapping usually looks like the following:
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>/faces/*</url-pattern>
</servlet-mapping>
So try to use links that contain this url pattern or use relative links instead.
If you use h:link instead of a:href, the url-pattern is automatically prepended:
<h:link value="My other page" outcome="otherpage" />
will be rendered as:
My other page

Resources