I have an h:selectOneMenu and an a4j:commandButton, the latter of which reRenders a component called content which looks like this:
<rich:panel id="content">
<a4j:include viewId="#{MyBacking.viewId}" />
</rich:panel>
When the response is rendered and the component loads the content of the new JSP page, the tabs contained in that page use a skin that is different from the rest of the app (I think default blue).
I've noticed that after the included code is loaded, if I hit refresh, although this causes the bean to reissue the page contents, the skin is properly assigned.
My web xml says:
<context-param>
<param-name>org.richfaces.SKIN</param-name>
<param-value>glassX</param-value>
</context-param>
<context-param>
<param-name>org.richfaces.CONTROL_SKINNING</param-name>
<param-value>enable</param-value>
</context-param>
<context-param>
<param-name>org.richfaces.CONTROL_SKINNING_CLASSES</param-name>
<param-value>enable</param-value>
</context-param>
Is this effect because RichFaces is in some way not in control of the rendering of the tabs at this point?
How can I ensure the tabs conform to the skin? All the documentation is relating to overriding a skin, and I'd rather not have to override and skin with the skin that it should already have.
Thanks
I am not sure if it will solve your problem, however you can try to force Richfaces to avoid using the default skin by setting a specific web.xml parameter:
<context-param>
<param-name>org.richfaces.LoadStyleStrategy</param-name>
<param-value>ALL</param-value>
</context-param>
You can find more details about this property here.
edited, to set the correct param-value, as stated in the comments.
I've just noticed I'd included a styleClass parameter - and because the jsp is now included didn't have access to the css facet reference.
Related
I want to show detail exception along with stack trace on error page if the project stage is development
web.xml entry -
<context-param>
<param-name>javax.faces.PROJECT_STAGE</param-name>
<param-value>Development</param-value>
</context-param>
else if Project stage is Production then I want to show a custom message to user.
web.xml entry-
<context-param>
<param-name>javax.faces.PROJECT_STAGE</param-name>
<param-value>Production</param-value>
</context-param>
Is there any way to achieve this?
The JSF project stage is available by Application#getProjectStage(). The JSF application is in turn available by FacesContext#getApplication(). The JSF context is in EL available by #{facesContext}.
So, this should do in the error page:
<c:choose>
<c:when test="#{facesContext.application.projectStage eq 'Development'}">
<!-- Print stack trace here -->
</c:when>
<c:otherwise>
<!-- Print custom message here -->
</c:otherwise>
</c:choose>
Been try to learn JSF, and sometimes I see the URL is *.jsf and sometimes is *.xhtml or /faces/*. Can someone fill my knowledge, please? When I create a JSF using Facelet, the file extension is .xhtml, so where does .jsf URL extension come from?
The .jsf extension is where the FacesServlet is during the JSF 1.2 period often mapped on in the web.xml.
<servlet-mapping>
<servlet-name>facesServlet</servlet-name>
<url-pattern>*.jsf</url-pattern>
</servlet-mapping>
The .xhtml extension is of the actual Facelets file as you've physically placed in the webcontent of your webapp, e.g. Webapp/WebContent/page.xhtml.
If you invoke this page with the .jsf extension, e.g. http://localhost:8080/webapp/page.jsf then the FacesServlet will be invoked, locate the page.xhtml file and parse/render its JSF components. If the FacesServlet isn't invoked, then the enduser would end up getting the raw XHTML source code (which can be seen by rightclick, View Source).
Sometimes a *.faces extension or /faces/* foldermapping is been used. But this was from back in the JSF 1.0/1.1 ages. You're free to choose and use whatever mapping you'd like to let FacesServlet listen on, even if it's a nothing-saying *.xyz. The actual page itself should always have the .xhtml extension, but this is configureable by the following <context-param> in web.xml:
<context-param>
<param-name>javax.faces.DEFAULT_SUFFIX</param-name>
<param-value>.xml</param-value>
</context-param>
This will change the FacesServlet to locate page.xml instad of (default) page.xhtml.
More recently, with JSF/Facelets 2.0 a *.xhtml mapping is been used. In JSF/Facelets 1.x it was not possible to use the same mapping extension as the physical file. It would result in an infinite loop. But since JSF/Facelets 2.0 it is possible and this allows you to call the page by http://localhost:8080/webapp/page.xhtml.
<servlet-mapping>
<servlet-name>facesServlet</servlet-name>
<url-pattern>*.xhtml</url-pattern>
</servlet-mapping>
This way you don't need to configure some security restrictions to hide the raw source files away for cases whenever the enduser changes for example .jsf in URL to .xhtml in browser address bar. Only tooling (IDEs and plugins) and learning resources still need to catch up the advocated move from *.jsf to *.xhtml. As per JSF 2.3, the FacesServlet will by default be autoregistered on *.xhtml too (next to /faces/*, *.faces and *.jsf). This is backported to Mojarra 2.2.11.
See also:
Can we use regular expressions in web.xml URL patterns?
Set default home page via <welcome-file> in JSF project
JSF returns blank/unparsed page with plain/raw XHTML/XML/EL source instead of rendered HTML output
What is the difference between creating JSF pages with .jsp or .xhtml or .jsf extension
Which XHTML files do I need to put in /WEB-INF and which not?
Customize FacesServlet <url-pattern> to get rid of .xhtml extension
I have Login.xhtml and Home.xhtml. I configured the url pattern in web.xml as follows
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>/faces/*</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>Login.xhtml</welcome-file>
</welcome-file-list>
When I run the whole project, the login page URL is like this http://localhost:8080/fran/Login.xhtml , here fran is my project name..
However, I would like it to be http://localhost:8080/fran/Login/ instead of http://localhost:8080/fran/Login.xhtml.
How can I achieve this? Is it possible to customize the <url-pattern> for every page to get rid of the .xhtml extension?
If your sole reason is to get rid of the .xhtml extension, then there are various ways depending on the JSF version you're using.
JSF 2.3+
JSF 2.3 offers a new API to collect all views: the ViewHandler#getViews(). Combine this with ServletRegistration#addMapping() in a ServletContextListener as below.
#FacesConfig
#WebListener
public class ApplicationConfig implements ServletContextListener {
#Override
public void contextInitialized(ServletContextEvent event) {
addExtensionLessMappings(event.getServletContext(), FacesContext.getCurrentInstance());
}
private void addExtensionLessMappings(ServletContext servletContext, FacesContext facesContext) {
servletContext
.getServletRegistrations().values().stream()
.filter(servlet -> servlet.getClassName().equals(FacesServlet.class.getName()))
.findAny()
.ifPresent(facesServlet -> facesContext
.getApplication()
.getViewHandler()
.getViews(facesContext, "/", ViewVisitOption.RETURN_AS_MINIMAL_IMPLICIT_OUTCOME)
.forEach(view -> facesServlet.addMapping(view))
);
}
}
Effectively, this is an oneliner. Source: Arjan Tijms' Blog and The Definitive Guide to JSF.
If you're using MyFaces as JSF 2.3 implementation, then this can be transparently activated by solely the following web.xml context parameter:
<context-param>
<param-name>org.apache.myfaces.AUTOMATIC_EXTENSIONLESS_MAPPING</param-name>
<param-value>true</param-value>
</context-param>
Mojarra does not have an equivalent yet.
JSF 2.2-
Use OmniFaces FacesViews. It offers a zero-configuration way to achieve that by placing the view files in /WEB-INF/faces-views/ folder. Otherwise, if you intend to not modify your project structure and want to keep your view files at the usual place and still benefit of extensionless URLs, then it's a matter of adding the following context parameter:
<context-param>
<param-name>org.omnifaces.FACES_VIEWS_SCAN_PATHS</param-name>
<param-value>/*.xhtml</param-value>
</context-param>
In case you don't want to use OmniFaces, but rather want to homegrow your own, just look at source code of OmniFaces. It's open source under Apache 2.0 License. It's only not an oneliner.
Take a look at prettyfaces: Pretty URLs for JavaServer Faces ,
Look at the 2. Create pretty-config.xml example in the main page
And take a look at the Chapter 2. Get Started
Just a little complement to mr. #balusc excelent answer about MyFaces on JSF 2.3... (Edit: not really a complement as one can not complement what's complete, but just a workaround for tomcat/tomee users to deal with this tomcat bug).
Using MyFaces 2.3.6, I received a Exception talking about servlet specification and ServletContextListener:
java.lang.UnsupportedOperationException: Section 4.4 of the Servlet 3.0 specification does not permit this method to be called from a ServletContextListener that was not defined in web.xml, a web-fragment.xml file nor annotated with #WebListener
Following the stack i saw this line:
at org.apache.myfaces.webapp.StartupServletContextListener.contextInitialized(StartupServletContextListener.java:103)
And after adding that listener to web.xml all worked fine:
<listener>
<listener-class>org.apache.myfaces.webapp.StartupServletContextListener</listener-class>
</listener>
In the composite:interface I have defined an attribute like this:
<composite:attribute name="myAttribute" required="true"/>
Now when I use my composite component like this, without defining any attributes:
<myTag:myCC/>
I would expect an error to occur. It doesn't. What could I possibly be missing?
It will only occur if your JSF project stage is set to Development as follows in web.xml:
<context-param>
<param-name>javax.faces.PROJECT_STAGE</param-name>
<param-value>Development</param-value>
</context-param>
It defaults to Production. Don't be surprised if you start to see several other errors/warnings related to "development mistakes" after setting the above context parameter.
In your specific case you should get an exception during opening the page something like this when you omit the required attribute:
javax.faces.view.facelets.TagException: /test.xhtml #22,19 <my:composite> The following attribute(s) are required, but no values have been supplied for them: foo.
at com.sun.faces.facelets.tag.composite.InterfaceHandler.validateComponent(InterfaceHandler.java:232)
at com.sun.faces.facelets.tag.composite.InterfaceHandler.apply(InterfaceHandler.java:125)
at javax.faces.view.facelets.CompositeFaceletHandler.apply(CompositeFaceletHandler.java:95)
...
This is what I have in the output HTML document (produced by JSF 2.0/Mojarra 2.0.3):
<input type="hidden" name="javax.faces.ViewState"
id="javax.faces.ViewState" value="4267906931114993858:-6309146738430577631"
autocomplete="off" />
My document should be XHTML 1.1 compliant, where attribute autocomplete is not valid and id attribute is duplicated over all forms. How to instruct JSF to produce everything strictly compliant to XHTML?
See.
<context-param>
<param-name>com.sun.faces.autoCompleteOffOnViewState</param-name>
<param-value>false</param-value>
</context-param>
<context-param>
<param-name>com.sun.faces.enableViewStateIdRendering</param-name>
<param-value>false</param-value>
</context-param>
The non unique use if the ID javax.faces.ViewState is a bug that appears Oracle will not fix. They have closed these tickets. No workaround.
How to instruct JSF to produce
everything strictly compliant to
XHTML?
That's not a matter of "instructing" the JSF implementation with a simple flag. It's something that has to be continuously checked and thus only possible when it's considered important by the project. XHTML strict imposes a lot of restrictions and is probably therefore generally not considered worth supporting - see this bug. Note also that any component library you use also has to support it.
You'll have a lot more luck with XHTML 1.0 Transitional - I can confirm that MyFaces does produce valid XHTML 1.0 Transitional (once you set the context param org.apache.myfaces.RENDER_VIEWSTATE_ID to false).
There is a solution to this problem, it was created in version 1.2_14 of JSF. I think the problem is related to the way that Firefox operates during the reset event (input type=reset) on hidden fields. There is a problem where the client viewState that is on a hidden field gets an inconsistent state. The solution for this problem was disabled the auto-complete in a strict way (and this is not XHTML compliant). The most interesting thing is that until 1.2_14 almost everybody lived with this potential error. So the JSF-RI implementation (Mojarra project) allowed a developer to disable this option using a parameter that you can edit in your web.xml, and this auto complete won't print anymore.
<context-param>
<description>Put your description here :)</description>
<param-name>com.sun.faces.autoCompleteOffOnViewState</param-name>
<param-value>false</param-value>
</context-param>
It is really difficult to produce valid XHTML pages with component based frameworks like JSF, but at least a solution exists for this problem.
It's not a good idea to disable autocomplete="off" for ViewState hidden input fields, because then Firefox doesn't refresh the ViewState-Id on page refresh. This causes unusable JSF forms and functionalities.
See this post for details.