Creating ICEfaces application example connecting beans and Facelets - jsf-2

I'm new in developing web applications and I installed the ICEfaces plugin. I found this tutorial to learn how to work with it and the first given example dont work in my IDE.
Its about the last part of the tutorial where it shows how to use a dateTimeEntry in a webapp.
So I followed the instructions so that my index.xhtml looks like this:
<?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:ui="http://java.sun.com/jsf/facelets"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:icecore="http://www.icefaces.org/icefaces/core"
xmlns:ace="http://www.icefaces.org/icefaces/components"
xmlns:ice="http://www.icesoft.com/icefaces/component">
<h:body>
<form>
<ace:dateTimeEntry id="dateTimeEntryId"
value="#{yourBean.selectDateProperty}" timeZone="Canada/Mountain"
pattern="MMM/dd/yyyy" style="width: 729px; " renderAsPopup="true">
</ace:dateTimeEntry><br />
</form>
</h:body>
</html>
And my java bean like this:
package org.icefaces.view;
import java.io.Serializable;
import java.util.Date;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import org.icefaces.ace.event.DateSelectEvent;
#ManagedBean(name= "yourBean")
#ViewScoped
public class YourBean implements Serializable {
/**
*
*/
private static final long serialVersionUID = 5058131064162864510L;
private Date selectDateProperty = new Date(System.currentTimeMillis());
public Date getSelectDateProperty() {
return selectDateProperty;
}
public void setSelectDateProperty(Date selectDateProperty) {
this.selectDateProperty = selectDateProperty;
}
public void dateSelectListener(DateSelectEvent event) {
setSelectDateProperty(event.getDate());
}
}
The structure of the project looks like this:
The point is, that in the tutorial there is no location given where to save the java beans. So I thougt it has to saved in the java resources directory, but I'm not sure because the app dont work. I just get a blank screen. The server and the configuration of it is valid I think because I can drop some Img or buttons and see the result in the browser. So I think I did not really understand how the java beans are connected with the xhtml files. I thougt it works with ManagedBean - attribute but I'm not sure about that.

Complete list of sample codes you can find here
http://anonsvn.icesoft.org/repo/icefaces3/trunk/icefaces/samples

Well I found out, that the connection of the javabeans and the variables in the xhtml file has to created in faces-config.xml in this form:
<managed-bean>
<managed-bean-name> [bean-name-of-java-class] </managed-bean-name>
<managed-bean-class> [fullpath-to-java-file] </managed-bean-class>
<managed-bean-scope>[scope]</managed-bean-scope>
</managed-bean>

Related

Why is JSF 2 managed bean not available in result page?

I have a very simple app. One bean annotated with #Named #SessionScoped and 2 web pages. home.xhtml and list.xhtml. When I set searchForm.hostanme on the first page, and access it again on the 2nd page. I can see from sysout statements that hostname is getting set, but there is a space where that value should be on the list.xhtml page. It's disappearing between home and list. Why?
home.xhtml
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html lang="en" xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html">
<h:head></h:head>
<h:form>
<h:outputText value="Hi Mama" />
<h:inputText value="#{searchForm.hostname}" />
<h:commandButton action="list?faces-redirect=true" value="Devices" />
<h:commandButton action="#{searchForm.reset}" value="Reset" immediate="true" type="reset" />
</h:form>
</html>
list.xhtml
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html lang="en" xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html">
<h:outputText value="Device is #{searchForm.hostname}" />
</html>
SearchForm.java
import javax.enterprise.context.RequestScoped;
import javax.inject.Named;
#Named
#RequestScoped
public class SearchForm {
String hostname;
public String getHostname() {
return hostname;
}
public void setHostname(String hostname) {
System.out.println("hostname is "+ hostname);
this.hostname = hostname;
}
public String reset(){
System.out.println("RESETTING");
System.out.println("hostname is "+ hostname);
return "/index.xhtml";
}
}
I'm thinking it might be a scoping issue, but I've tried several scopes and still searchForm.hostname is not avaible by the time I navigate to the list.xhtml page.
I've been reading and reading and reading up on JSF2, but I still can't resolve I hope is a simple problem.
I have a beans.xml file is in WEB-INF.
I come from a seam 2 background so decided I was comfortable with ConversationScoped in this context. It worked like a charm.
Some more thoughts that might help a confused person like me.
As I commented above, I grappled with a similar issue before in this question. As the comments above suggest, this is a scope issue. I realized that it is not only a scoping issue, it is an issue of confusion between CDI and JSF2 managed beans.
Both have a unique set of scopes, but there is some overlap, and in order to not be scratching your head over what should really not be a difficult problem, it is important to
Decide whether to use CDI beans or JSF2 managed beans
Thoroughly learn the scopes assocated with either type of bean
Know which one you are selecting when eclipse offers you 2 choices!
That last one has messed me up more times than I should admit.
Whether to use CDI or JSF2 just google "cdi vs. jsf2". I chose CDI since most things I read said to use CDI. I'm not sure it really makes a difference for my simple app.
Learn your scopes!! There are many articles about scopes, unfortunately I don't understand them as well as I should.
This is a classic for JSF2 users: Communication in JSF2 and I found this helpful as well. (notice same author - BalusC is a good resource for anything JSF2)
As for CDI just stick with the tutorial on Oracle's website.
And as for which library to import -- both JSF and CDI have a SessionScoped, and I think also RequestScoped:
CDI scopes are in javax.enterprise.context.SessionScoped
JSF scopes are in javax.faces.bean.SessionScoped
I consistently just take the first thing eclipse offers me. It can really screw you up so pay attention!

Custom component in JSF2 not being called

I'm creating a custom tag in my application but for some reason it's not working, I followed this tutorial (which is the clearest one that I found to put here as reference) but, like other tutorials that I did, my custom tag ins not called.
WEB-INF/example.taglib.xml
<?xml version="1.0" encoding="UTF-8"?>
<facelet-taglib
xmlns="http://java.sun.com/xml/ns/javaee"
version="2.0">
<namespace>http://example.com/facelettags</namespace>
<tag>
<tag-name>hello</tag-name>
<handler-class>example.MenuTagHandler</handler-class>
</tag>
</facelet-taglib>
My tag handler class
package example;
public class MenuTagHandler extends TagHandler {
private String name = "Anonymous";
public MenuTagHandler(TagConfig config) {
//other constructor stuff
Logger.getLogger(MenuTagHandler.class).info("aaaa");
//other constructor stuff
}
#Override
public void apply(FaceletContext context, UIComponent parent) throws IOException {
Logger.getLogger(MenuTagHandler.class).info("aaaa");
UIComponentBase c = new UIComponentBase() {
#Override
public void encodeEnd(FacesContext ctx) throws IOException {
ResponseWriter w = ctx.getResponseWriter();
w.write(String.format(
"<p>Hello %s! I am FaceletTag.</p>",
name));
}
// abstract method in base, must override
#Override
public String getFamily() {
return "com.example.facelettag.test";
}
};
parent.getChildren().add(c);
}
}
My .xhtml file
<?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">
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:exampler="http://example.com/facelettags" >
<example:hello />
</ui:composition>
The rendered result is
<example:hello></example:hello>
Unfortunately nothing is printed in the log, does anyone have any idea on why it is not calling the tag handler?
If the *.taglib.xml file is not inside the /META-INF of a JAR file which is placed in /WEB-INF/lib and thus won't be automatically detected and registered (like as in case of all those 3rd party JSF component libraries like PrimeFaces, RichFaces, etc), then you'd need to manually register it in webapp's web.xml as follows:
<context-param>
<param-name>javax.faces.FACELETS_LIBRARIES</param-name>
<param-value>/WEB-INF/example.taglib.xml</param-value>
</context-param>
Unrelated to the concrete problem, please note that what you've so far is not a custom component. This is a custom taghandler which in turn creates an anonymous instance of UIComponentBase. This is not necessarily the "best" practice. If you do not need to perform any actions related to the component tree during view build time, then you do not need the taghandler part at all. Just create a fullworthy #FacesComponent class instead.
See also:
When to use <ui:include>, tag files, composite components and/or custom components?

JSF, Composite Component: method call with default attribute value as parameter

I am new to JSF and still learning. I tried searching for a solution to my specific problem described below but I could not find anything. If it because I was searching for the wrong things, please point me in the right direction, but hopefully it is something that hasn't been answered and an answer can benefit everyone.
The following example illustrates the problem I came across. The example is simplified to focus on the problem and to hide the complexities of the actual project in which the problem occurred.
Consider the following pages / classes:
/resources/test/custom.xhtml;
/test/CharsetProvider.java;
/test/CharsetHello.java;
/testWith.xhtml;
/testWithout.xhtml;
/resources/test/custom.xhtml
This is composite component with one attribute with a default value. The component simply takes the attribute value and passes it as an argument to the CDI bean described below in order obtain the model object used for output.
<?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:cc="http://java.sun.com/jsf/composite"
xmlns:h="http://java.sun.com/jsf/html">
<cc:interface>
<cc:attribute name="charset"
default="#{charsetProvider.defaultCharset}"
type="java.nio.charset.Charset" />
</cc:interface>
<cc:implementation>
<h:outputText value="#{charsetProvider.createCharsetHello(cc.attrs.charset).hello}"/>
</cc:implementation>
</html>
test/CharsetProvider.java
This is a CDI bean that simply contains a default value used throughout the application and has a method that creates an object used as the model for a component. The reason I use a CDI bean instead of a backing bean is because in my specific project the default value needs to be injected at runtime, but backing beans are not candidates for injection.
package test;
import java.nio.charset.Charset;
import javax.annotation.PostConstruct;
import javax.faces.bean.SessionScoped;
import javax.inject.Named;
#Named
#SessionScoped
public class CharsetProvider {
private Charset defaultCharset;
#PostConstruct
protected void postConstruct() {
this.defaultCharset = Charset.forName("UTF-8");
}
public Charset getDefaultCharset() {
return defaultCharset;
}
public Charset getCharsetForName(String name) {
return Charset.forName(name);
}
public CharsetHello createCharsetHello(Charset cs) {
return new CharsetHello(cs);
}
}
test/CharsetHello.java
This is the "model" object. It simply converts "Hello world!" to a byte array and back using the given charset.
package test;
import java.nio.charset.Charset;
public class CharsetHello {
private static final String HW = "Hello World!";
private final byte[] data;
private final Charset cs;
public CharsetHello(Charset cs) {
this.cs = cs;
this.data = CharsetHello.HW.getBytes(this.cs);
}
public String getHello() {
return new String(this.data, this.cs);
}
}
testWith.xhtml
This is a test page that uses the composite component defined above by specifying a value for the component's attribute. The page renders properly, i.e. "Hello World!" prints on the screen.
<?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:test="http://java.sun.com/jsf/composite/test">
<h:head>
<title>Test</title>
</h:head>
<h:body>
<test:custom charset="#{charsetProvider.getCharsetForName('UTF-16')}" />
</h:body>
</html>
testWithout.xhtml
This is a test page that does not pass a custom value to the component's attribute, intending to use the default value.
<?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:test="http://java.sun.com/jsf/composite/test">
<h:head>
<title>Test</title>
</h:head>
<h:body>
<test:custom />
</h:body>
</html>
The page above results in a JSF error page with the following message:
/resources/test/custom.xhtml #14,94 value="#{charsetProvider.createCharsetHello(cc.attrs.charset).hello}": Cannot convert UTF-8 of type class java.lang.String to class java.nio.charset.Charset
It seems that in the last case the default value is converted to a java.lang.String before being passed to the method.
First off, is this the expected behaviour and why?
If this is the expected behaviour, can you suggest a different implementation?
Thank you in advance!
This problem has exactly the same ground as this problem: FacesConverter forClass don't work with Composite Componet. The composite attribute value type is in Mojarra incorrectly been evaluated as java.lang.Object instead of the actual model type.
It's been reported as Mojarra issue 2568. It works in MyFaces 2.1.9.

Why is my ViewScoped bean not surviving h:commandButton?

Deploying on JBoss AS 7.1.0.Final.
I have a very simple test app. It was working as expected until the other day (famous last words) and is no longer doing the most basic thing, namely setting the value of the input component and using it in the action component. I have stripped this thing down to the basics and can not figure out what is going on.
index.xhtml is here
<!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:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html">
<h:head>
<title>contacts</title>
</h:head>
<h:form>
<h:outputLabel value="Message:" />
<h:inputText value="#{contactView.siteCode}" />
<h:commandButton action="#{contactView.save}" value="Save" />
</h:form>
</html>
ViewScoped bean is here
#Named
#ViewScoped
public class ContactView implements Serializable {
public ContactView() {
}
private String siteCode;
public String getSiteCode() {
System.out.println("getSiteCode: "+ siteCode);
return siteCode;
}
public void setSiteCode(String siteCode) {
System.out.println("setSiteCode: "+ siteCode);
this.siteCode = siteCode;
}
public String save(){
System.out.println("Saving sitecode: " + siteCode);
return "index.jsf";
}
}
What am I doing wrong? When I click on the save button I get this in the output
10:50:37,663 INFO [stdout] (http--0.0.0.0-8080-2) setSiteCode: 22
10:50:37,663 INFO [stdout] (http--0.0.0.0-8080-2) Saving sitecode: null
10:50:37,663 INFO [stdout] (http--0.0.0.0-8080-2) getSiteCode: null
That's because the bean is managed by CDI #Named, not by JSF #ManagedBean. JSF scope annotations of the package javax.faces.bean only works on beans managed by JSF. On a CDI managed bean, you need to use CDI annotations from javax.enterprise.context instead. However, CDI doesn't have a concept of the view scope. Closest is #ConversationScoped, but this is more complex to manage. When you don't specify a scope on a CDI managed bean, it will default to the request scope.
Make sure that your bean is managed by JSF whenever you want to use #ViewScoped.
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
#ManagedBean
#ViewScoped
public class ContactView implements Serializable {
// ...
}
Further, you also need to make sure that your action methods return null or void whenever you want to retain the view scope.

Accessing JSF2 composite component attributes in backing component

I'm developing a JSF2/Primefaces app and I'm having trouble with accessing attributes defined in an interface of a composite component in this component's backing bean.
My component is defined as follows:
<!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:composite="http://java.sun.com/jsf/composite">
<composite:interface componentType="testComponent">
<composite:attribute name="text" required="true" type="java.lang.String" />
</composite:interface>
<composite:implementation>
<h:outputText value="Passed text is: #{cc.attrs.text}" />
</composite:implementation>
</html>
It is stored in a file called text.xhtml located in: application/src/main/webapp/resources/my_component directory.
I use this component on another page (which is a Facelets composition element) like so:
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:myc="http://java.sun.com/jsf/composite/my_component"
template="./resources/templates/template.xhtml">
<ui:define name="content">
<h:form id="products">
<myc:test id="test" text="A text" />
</h:form>
</ui:define>
</ui:composition>
The backing component class is defined as follows:
package my.application.component;
import javax.faces.component.FacesComponent;
import javax.faces.component.UINamingContainer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
#FacesComponent ( value="testComponent" )
public class TestComponent extends UINamingContainer {
Logger log = LoggerFactory.getLogger(TestComponent.class);
public TestComponent() {
log.debug("TestComponent constructor");
log.debug("getAttributes().size(): " + getAttributes().size());
}
}
The component itself works as expected. The using page renders Passed text is: A text output.
Also, logger output displays log messages from TestComponent constructor, so it seems that the component xml definition is correctly bound with the TestComponent class.
Now, the problem is that the getAttributes() method invoked in TestComponent constructor always returns a zero-sized map.
If I understand this correctly, I should be able to access the text attribute declared in component's interface using a call:
getAttributes().get("text");
in the TestComponent class, but it always returns null as the attributes map is empty.
I also tried to access the text attribute using a call:
String text = FacesContext.getCurrentInstance().getApplication().
evaluateExpressionGet(FacesContext.getCurrentInstance(), "#{cc.attrs.text}", String.class));
but it also resolves to null.
What am I doing wrong? Any tips will be much appreciated as I have no idea what to try next.
/Tukasz.
My guess is that the constructor is too early to reference those attributes.
JSF will construct an instance of the backing component first, and will then at some point give it a reference to its attributes. In a method that's called later, eg the encode method, you should have access to them.

Resources