When I wrote this chapter, I did not think of many difficulties. Now, let's simply say:
1. Adding the namespace in the taglib. xml file looks pretty good, but it brings a lot of trouble-EL expression failure. This is my post on java.net with another programmer.
Http://www.java.net/forum/topic/glassfish/glassfish-webtier/el-composite-component-taglib-jsf20
Currently, my solution is to bypass this problem and only use the standard namespace, that is, http://java.sun.com/jsf/composite/tag_folder_path. At the same time, I simply searched the source code of PrimeFaces and found that it was not implemented using Composite Component, because no xhtml file was found.
2. <The Complete Reference-Java Server Faces2.0>
A. Chapter 2, page 2,
Public class loginPanel extends UINamingContainer
This line of code is totally wrong. The correct one should be
Public class loginPanel extends UIInput implements UINamingContainer
B. The book does not provide examples to demonstrate how to package a Composite Component with a Backing class into a jar package. Therefore, the code snippets provided in the book are untrusted.
The alias of cc in c.xhtml is the same as that of the default cc.
<Html xmlns = "http://www.w3.org/1999/xhtml" xmlns: h = "http://java.sun.com/jsf/html"
Xmlns: cc = "http://java.sun.com/jsf/composite">
<Cc: interface/>
<Cc: implementation>
<H: panelGrid columns = "3">
<H: outputLabel for = "# {cc. clientId}: userid" value = "Userid:"/>
<H: inputText required = "true"
RequiredMessage = "Userid is required" id = "userid"/>
<H: message for = "# {cc. clientId}: userid"/>
<H: outputLabel for = "# {cc. clientId}: password" value = "Password:"/>
<H: inputSecret required = "true"
RequiredMessage = "Password is required" id = "password"/>
<H: message for = "# {cc. clientId}: password"/>
<H: outputText value = "On Login, Go :"
Rendered = "#{! Empty cc. facets. loginOutcomeChoiceList} "/>
<H: commandButton id = "loginButton" value = "Login"/>
<H: messages for = "# {cc. clientId}"/>
</H: panelGrid>
</Cc: implementation>
</Html>
In the above Code, xmlns: cc = "http://java.sun.com/jsf/composite is easy to mislead people, it is generally recommended to use xmlns: composite instead of xmlns: cc. In the # {cc.} syntax, cc is a predefined Java object, representing the top-level object NamingContainer of Composite Component.
A lot of questions are not understood until you read the third edition of <Core JSF>.
Okay. Start now.
First, implement the htmlinput2.xhtml code:
<? 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: f = "http://java.sun.com/jsf/core"
Xmlns: h = "http://java.sun.com/jsf/html"
Xmlns: ui = "http://java.sun.com/jsf/facelets"
Xmlns: composite = "http://java.sun.com/jsf/composite">
<Composite: interface componentType = "HtmlInput2">
<Composite: editableValueHolder name = "inputField" target = "in"/>
<Composite: valueHolder name = "outputField" target = "out"/>
</Composite: interface>
<Composite: implementation>
<H: inputText id = "in" required = "true"/>
<H: commandButton id = "clickButton" value = "Click Me! "/>
<H: outputText id = "out"/>
</Composite: implementation>
</Html>
Composite: interface specifies componentType, JSF runtime uses it to find HtmleInput2 class in the faces-config.xml file, which implements the NamingContainer interface and inherits the UIInput class. JSF runtime creates this class as the top-level object of Customized component.
<Component>
<Component-type> HtmlInput2 </component-type>
<Component-class> com. freebird. component. HtmlInput2 </component-class>
</Component>
If componentType is not specified, JSF runtime searches for htmlinput2.java Based on the xhtml file name htmlinput2. If it is found and the NamingContainer interface is implemented, the class is created after the UIInput class is inherited, use it as the top-level object of Customized component.
If not, JSF runtime creates the default implementation class of the NamingContainer interface as the top-level object.
When should we specify compnentType? When you want some java code background to help tag process some behavior.
For more information, see <Core JSF> Chapter 9 of the third edition.
Now let's take a look at the implementation of the HtmleInput2 class:
Package com. freebird. component;
Import javax. faces. component. NamingContainer;
Import javax. faces. component. UIOutput;
Import javax. faces. component. UIInput;
Import javax. faces. event. ActionEvent;
Import java. util. logging. Level;
Import java. util. logging. Logger;
Import java. io. FileWriter;
Import java. io. BufferedWriter;
Import java. io. FileReader;
Import java. io. BufferedReader;
Import java. io. File;
Import javax. faces. component. FacesComponent;
Import javax. faces. event. ActionListener;
Import javax. faces. convert. ConverterException;
Import javax. faces. context. FacesContext;
Import java. io. IOException;
Import javax.faces.component.html. HtmlInputText;
Import javax.faces.component.html. HtmlOutputText;
Import javax. enterprise. context. ApplicationScoped;
Import java. util. Map;
/**
* Describe class HtmlInput2 here.
*
*
* Created: Sat Jan 1 16:08:53 2011
*
* @ Author <a href = "chenshumailto: chenshu @ csdesktop"> chenshu </a>
* @ Version 1.0
/
Public class HtmlInput2 extends UIInput implements NamingContainer {
Public HtmlInput2 (){
GetLogger (). info ("HtmlInput2 constructor ");
}
@ Override
Public String getFamily (){
Return "javax. faces. NamingContainer ";
}
Private Logger getLogger (){
Return Logger. getLogger (HtmlInput2.class. getName ());
}
Public void print (ActionEvent event ){
GetLogger (). info ("enter print method ");
}
Public void encodeBegin (FacesContext context) throws IOException {
Map requestMap = context. getExternalContext (). getRequestParameterMap ();
String clientId = getClientId (context );
GetLogger (). info ("clientId:" + clientId );
String inputValue = (String) requestMap. get (clientId + ": in ");
HtmlInputText input = (HtmlInputText) findComponent ("in ");
If (null = input ){
GetLogger (). info ("cant find input component instance ");
Super. encodeBegin (context );
Return;
}
HtmlOutputText output = (HtmlOutputText) findComponent ("out ");
If (null = output ){
GetLogger (). info ("cant find output component instance ");
Output. setValue ("null ");
Super. encodeBegin (context );
Return;
}
&