JSF and Apache MyFaces in Action - ApacheCon
JSF and Apache MyFaces in Action - ApacheCon
JSF and Apache MyFaces in Action - ApacheCon
Create successful ePaper yourself
Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.
<strong>JSF</strong> <strong>and</strong> <strong>Apache</strong> <strong>MyFaces</strong> <strong>in</strong><br />
<strong>Action</strong><br />
Ernst Fastl (irian.at - Austria)
Agenda<br />
• Introduction to <strong>JSF</strong><br />
• Introduction to <strong>Apache</strong> <strong>MyFaces</strong><br />
• Build<strong>in</strong>g an <strong>Apache</strong> <strong>MyFaces</strong> Application<br />
• Get <strong>in</strong> touch with the <strong>JSF</strong>-Request-Lifecycle<br />
• Us<strong>in</strong>g <strong>and</strong> Writ<strong>in</strong>g Converters <strong>and</strong> Validators<br />
• Some enhanced stuff (if time is there ☺)<br />
1
Web-Development (generally)<br />
• Web-Apps become more <strong>and</strong> more important<br />
• More <strong>and</strong> more complexity<br />
• Ajax, validation (server vs. client), ...<br />
• Higher customer requirement over the years<br />
• Rich user experience (easy to use)<br />
• Ergonomics vs. functionality<br />
• There is always the time ...<br />
2
3<br />
Web development (Java)
Servlets<br />
...<br />
Collection customers = db.getCustomers();<br />
Pr<strong>in</strong>tWriter writer = response.getWriter();<br />
writer.pr<strong>in</strong>tln("");<br />
Iterator it = customers.iterator();<br />
while(it.hasNext()) {<br />
writer.pr<strong>in</strong>tln(""); writer.pr<strong>in</strong>tln("");<br />
writer.pr<strong>in</strong>tln(((Customer)customers.next()).getCus<br />
tomerNumber());<br />
writer.pr<strong>in</strong>tln(""); writer.pr<strong>in</strong>tln("");<br />
}<br />
writer.pr<strong>in</strong>tln("");<br />
...<br />
4
JavaServer Pages<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
5
6<br />
Model 1
7<br />
Model 2
Java-Web-Frameworks<br />
• Lot’s of Model-2 based frameworks out there (too<br />
many)<br />
• <strong>Apache</strong> Struts<br />
• WebWork (soon Struts' <strong>Action</strong>2 Framework)<br />
• Stripes<br />
• Cocoon<br />
• <strong>and</strong> many many more ...<br />
• still some „homegrown“<br />
8
Problems<br />
• Java delivers not enough for webapps.<br />
• It is hard to <strong>in</strong>tegrate several frameworks<br />
(sometimes not possible)<br />
• Every framework has its special idea to solve<br />
the problem<br />
• Examples:<br />
• Struts vs. Cocoon<br />
• Struts vs. Tapestry<br />
• Struts vs. Stripes<br />
• Struts vs. ... (what’s your first choice?)<br />
9
• St<strong>and</strong>ard is miss<strong>in</strong>g!<br />
What’s up ... ?<br />
• for a web framework<br />
• for an unified API to build Java Web<br />
Components<br />
• SOLUTION:<br />
• JavaServer Faces ! ☺<br />
10
• <strong>JSF</strong> is a ...<br />
<strong>JSF</strong> <strong>in</strong> a nutshel<br />
• ... Java-Technology for Web-Apps<br />
• ... component-based framework<br />
• ... event-driven framework<br />
• ... RAD<br />
• ... <strong>in</strong>dustrial st<strong>and</strong>ard<br />
11
Technology for Web-apps<br />
• <strong>JSF</strong> supports:<br />
• the Web designer <strong>in</strong> creat<strong>in</strong>g simple templates for<br />
his application<br />
• the Java developer <strong>in</strong> writ<strong>in</strong>g backend code, which<br />
is simply <strong>in</strong>dependent from the Web server<br />
• Tool-vendors through its st<strong>and</strong>ardized platform<br />
12
Technology for Web-apps<br />
• <strong>JSF</strong> supports:<br />
• the Web designer <strong>in</strong> creat<strong>in</strong>g simple templates for<br />
his application<br />
• the Java developer <strong>in</strong> writ<strong>in</strong>g backend code, which<br />
is simply <strong>in</strong>dependent from the Web server<br />
• Tool-vendors through its st<strong>and</strong>ardized platform<br />
13
component driven framework<br />
• <strong>JSF</strong> has build<strong>in</strong>g components<br />
• def<strong>in</strong>e these components <strong>in</strong>side a JSP<br />
file, for <strong>in</strong>stance<br />
• the ‚render<strong>in</strong>g‘ transforms these<br />
components to markup like HTML 4.0.1<br />
<br />
<br />
14
event driven framework<br />
• Events <strong>in</strong> <strong>JSF</strong>:<br />
• components generate events<br />
• enforces a method call<br />
("action" <strong>and</strong> "event“ h<strong>and</strong>ler)<br />
• the state of the web app changes due to<br />
that caused event<br />
15
event driven framework<br />
registers at<br />
causes<br />
triggers<br />
event-source event event-listener<br />
16
Rapid Application Development<br />
• 4 layers:<br />
• basic component architecture<br />
• set of st<strong>and</strong>ard components<br />
• application <strong>in</strong>frastructure<br />
• the RAD tool itself<br />
<strong>JSF</strong> st<strong>and</strong>ardizes the first three po<strong>in</strong>ts <strong>and</strong><br />
allows the creation of RAD tools<br />
17
Why JavaServer Faces?<br />
• <strong>in</strong>dustrial st<strong>and</strong>ard (backed by JCP)<br />
• JSR 127 (<strong>JSF</strong> 1.0 <strong>and</strong> <strong>JSF</strong> 1.1) 2004<br />
• JSR 252 (<strong>JSF</strong> 1.2) - 2006 (Java EE 5.0)<br />
• <strong>JSF</strong> 1.2 – better <strong>in</strong>teraction with JSP 2.1 <strong>and</strong> bugfixes<br />
• <strong>JSF</strong> 2.0 (architecture, AJAX, more UI components, ..)<br />
Question is … when … 2006, 2007 ?<br />
• Java EE 5.0<br />
• BIG support<br />
• IDEs (Sun, Eclipse, Oracle, …)<br />
• 3rd party UI-components (Oracle, <strong>Apache</strong> <strong>MyFaces</strong>)<br />
18
Implementation: <strong>Apache</strong> <strong>MyFaces</strong><br />
• First free open source implementation ☺<br />
• Founders:<br />
• Manfred Geiler (OEKB)<br />
• Thomas Spiegl (irian.at - Austria)<br />
• Biggest <strong>JSF</strong> user community<br />
19
20<br />
<strong>JSF</strong> – MVC Framework (1)
<strong>JSF</strong> – MVC Framework (2)<br />
• Model: objects <strong>and</strong> properties of application<br />
(bus<strong>in</strong>ess tier b<strong>in</strong>d<strong>in</strong>gs)<br />
• View: Renderers take care of the view. That<br />
might be HTML (or XUL, or WML)<br />
• Controller: FacesServlet / <strong>JSF</strong> – <strong>in</strong>frastructure<br />
def<strong>in</strong>es the flow of the application<br />
21
Reusability<br />
• <strong>JSF</strong> allows the resuse of …<br />
• … components<br />
• Reuse of widgets, once created<br />
• … views<br />
• possible to to build a layout based on subviews<br />
• … your design<br />
• components support the design<br />
• Creation of a “Corporate Design”<br />
✂ Reuse for your next project<br />
22
Integration (1)<br />
• <strong>JSF</strong> is flexible; extensible <strong>and</strong> can be adopted<br />
• Fit’s <strong>in</strong>to several st<strong>and</strong>ards<br />
• Based upon JSPs <strong>and</strong> Servlets<br />
• Frameworks ontop of <strong>JSF</strong>...<br />
• Seam, Facelets, Shale, ...<br />
• Part of a big spec. Java Enterprise Edition 5.0<br />
• Java EE 5 enforces app servers to ship a <strong>JSF</strong><br />
implementation.<br />
• Today it is already shipped by JBoss <strong>and</strong> SUN<br />
23
Integration (2)<br />
• Integration with web portals (JSR 168) possible<br />
• Page conta<strong>in</strong>s several subapplications (portlets)<br />
• JSR-168 bridges (RI, <strong>MyFaces</strong>, <strong>Apache</strong> Portals)<br />
• Supported by other web frameworks<br />
• Struts classic (Struts 1.2 <strong>and</strong> Struts 1.3)<br />
• Struts Integration Library (Craig McClanahan)<br />
• SAF2 (Struts <strong>Action</strong>s2 Framework)<br />
• special FacesInterceptors<br />
• Blog entry by Don Brown available<br />
• Cocoon has <strong>JSF</strong> support<br />
24
Tools<br />
• run time:<br />
• every servlet conta<strong>in</strong>er<br />
• Every Java EE 5.0 compliant Application Server has<br />
<strong>JSF</strong> „out of the box“.<br />
• design time:<br />
• Sun One Studio Creator<br />
• Eclipse <strong>and</strong> MyEclipse, Exadel Studio<br />
• Oracle JDeveloper<br />
25
Development process<br />
• with proper tools:<br />
• Drag&Drop:<br />
• Drag your components from a pallet to the page<br />
• wire the components to “back<strong>in</strong>g beans”<br />
• create a persistence layer<br />
26
References<br />
• Companies us<strong>in</strong>g <strong>Apache</strong> <strong>MyFaces</strong><br />
http://wiki.apache.org/myfaces/Companies_Us<strong>in</strong>g_<strong>MyFaces</strong><br />
• Austria (for <strong>in</strong>stance):<br />
• OeKB: Roncalli, ADAS, QMS,<br />
Gruppenkalender, Zeiterfassung<br />
• Prisma Kreditversicherungen: Prismanet,<br />
PrismaCIS<br />
• IRIAN GesmbH: http://www.irian.at<br />
27
Example<br />
• Wake up aga<strong>in</strong> …<br />
28
<strong>JSF</strong> – Hello World (JSP file)<br />
<br />
<br />
<br />
<br />
Input Name Page <br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
29
<strong>JSF</strong> <strong>and</strong> JSP<br />
• <strong>JSF</strong> Spec describes the support of JSP<br />
• Alternatives possible (Facelets)<br />
• JSP-Support via Taglibs<br />
• Core (the frameworks core)<br />
• like validation, conversion<br />
• HTML (renders “simple” markup (HTML 4.0.1)<br />
• , , ...<br />
30
<strong>JSF</strong> – Hello World (JavaBean)<br />
public class GetNameBean {<br />
Str<strong>in</strong>g userName;<br />
public Str<strong>in</strong>g getUserName() {<br />
return userName; }<br />
public void setUserName(Str<strong>in</strong>g name) {<br />
userName = name; }<br />
public Str<strong>in</strong>g sayHello<strong>Action</strong>(){<br />
return "sayhello"; }<br />
}<br />
31
<strong>JSF</strong> – XML Config (1)<br />
<br />
<br />
Input Value Holder<br />
<br />
GetNameBean<br />
demo.GetNameBean<br />
session<br />
<br />
userName<br />
java.lang.Str<strong>in</strong>g<br />
<br />
<br />
<br />
32
<strong>JSF</strong> – XML Config (2)<br />
<br />
/pages/<strong>in</strong>putname.jsp<br />
<br />
/pages/greet<strong>in</strong>g.jsp<br />
<br />
<br />
33
Practice – Hello World<br />
• Modify the Example to take firstName<br />
<strong>and</strong> sirName<br />
• If you need help, SCREAM!<br />
34
<strong>JSF</strong> Request Life-Cycle<br />
• What’s under the hood of a <strong>JSF</strong> request?<br />
35
<strong>JSF</strong> Request Lifecyle<br />
Response<br />
complete<br />
C L I E N T<br />
Faces<br />
request<br />
Faces<br />
response<br />
Restore<br />
View<br />
Render<br />
Response<br />
Apply<br />
Request<br />
Values<br />
Render Response<br />
Process<br />
Events<br />
Response<br />
complete<br />
Process<br />
Events<br />
Invoke<br />
Application<br />
Conversion<br />
<strong>and</strong><br />
Validation<br />
Response<br />
complete<br />
Process<br />
Events<br />
Process<br />
events<br />
Update<br />
Model<br />
Response<br />
complete<br />
Conversion Errors<br />
Render Response<br />
Validation / Conversion Errors<br />
Render Response<br />
36
<strong>JSF</strong> Lifecycle – first request<br />
C L I E N T<br />
Faces<br />
request<br />
Faces<br />
response<br />
Restore<br />
View<br />
Render<br />
Response<br />
No view available<br />
Apply<br />
Request<br />
Values<br />
Process<br />
Events<br />
Process<br />
Events<br />
Invoke<br />
Application<br />
Conversion<br />
<strong>and</strong><br />
Validation<br />
Process<br />
Events<br />
Process<br />
events<br />
Update<br />
Model<br />
Create View<br />
37
<strong>JSF</strong> Lifecycle – Validation fails<br />
C L I E N T<br />
Faces<br />
request<br />
Faces<br />
response<br />
Restore<br />
View<br />
Render<br />
Response<br />
Apply<br />
Request<br />
Values<br />
Process<br />
Events<br />
Process<br />
Events<br />
Invoke<br />
Application<br />
Conversion<br />
<strong>and</strong><br />
Validation<br />
Process<br />
Events<br />
Process<br />
events<br />
Update<br />
Model<br />
Validation / Conversion Errors<br />
Render Response<br />
38
Restore View – Phase 1<br />
• build<strong>in</strong>g the component tree<br />
• first request (non-postback):<br />
• go to „Render Response“-Phase (Phase 6)<br />
• Use the template; create the tree dur<strong>in</strong>g pars<strong>in</strong>g the<br />
template<br />
• save the tree <strong>in</strong> the „state“<br />
• Postback:<br />
• Create the tree from the „state“<br />
• Execute the lifecycle<br />
39
Apply Request Values – Phase 2<br />
• decod<strong>in</strong>g:<br />
•processDecodes() called recursively on each<br />
component <strong>in</strong> the tree (Start<strong>in</strong>g at UIViewRoot)<br />
• every component takes care of it’s value (read<strong>in</strong>g<br />
HTTP-parameters, Cookies, Headers, etc.)<br />
• Saves the submitted value us<strong>in</strong>g<br />
setSubmittedValue()<br />
40
Process Validations – Phase 3<br />
• Calls listener for the ValueChangeEvent<br />
• conversion (!) <strong>and</strong> validation<br />
• processValidators(); called recursively, starts with UIViewRoot<br />
• getSubmittedValue(); like “21.11.2005”<br />
• converts to an object of class java.util.Date<br />
• enforce validation by call<strong>in</strong>g the registered validators<br />
• save the correct value („local-value“) by call<strong>in</strong>g setValue()<br />
• Error occurs on conversion or validation:<br />
GO TO Render-Response-Phase<br />
41
Update Model Values – Phase 4<br />
• processUpdates(); (aga<strong>in</strong> start<strong>in</strong>g on<br />
UIViewRoot)<br />
• component value is converted <strong>and</strong> valid; so it<br />
should be pushed to the model<br />
• us<strong>in</strong>g the correspond<strong>in</strong>g back<strong>in</strong>g bean<br />
• #{bean.property}<br />
• Call<strong>in</strong>g the setter<br />
• setProperty()<br />
42
Invoke Application – Phase 5<br />
• processApplication() (UIViewRoot…)<br />
• event h<strong>and</strong>l<strong>in</strong>g for:<br />
•action / actionListener<br />
• executed<br />
• sequence:<br />
• first actionListener(s)<br />
• call<strong>in</strong>g action method<br />
43
Render Response – Phase 6<br />
• Navigation: NavigationH<strong>and</strong>ler determ<strong>in</strong>ates<br />
the next „view“ (a JSP page for <strong>in</strong>stance)<br />
• ViewH<strong>and</strong>ler takes over – <strong>in</strong> case of JSP the<br />
(JSP)ViewH<strong>and</strong>ler enforces a forward<br />
• JSP page gets parsed by the JSP conta<strong>in</strong>er.<br />
Perform<strong>in</strong>g a lookup for each component’s<br />
• Renderer.Call<strong>in</strong>g several methods are called:<br />
• encodeBeg<strong>in</strong>(); encodeChildren(); encodeEnd();<br />
• Start<strong>in</strong>g at UIViewRoot<br />
44
Chang<strong>in</strong>g the lifecycle (1)<br />
• immediate property<br />
• UIComm<strong>and</strong> components:<br />
• action is called immediately. No validation or model update.<br />
• Use it for a cancel button<br />
• UIInput components:<br />
• components value will be validated <strong>and</strong> converted <strong>in</strong> Apply Request<br />
Values<br />
• a ValueChangeEvent is generated <strong>and</strong> it’s listener is called after”Apply<br />
Request Values”<br />
• call<strong>in</strong>g facesContext.renderResponse() <strong>in</strong>side a ValueChangeListener<br />
go to “RenderResponse”<br />
• No conversion <strong>and</strong> validation of other (non immediate) components!<br />
45
Chang<strong>in</strong>g the lifecycle (2)<br />
• Optional Validation Framework<br />
• for each request<br />
• optional switch<strong>in</strong>g validation on/off<br />
•„required“-attribute own validator<br />
• many additional features<br />
• Project: <strong>JSF</strong>-Comp at sourceforge.net<br />
46
Chang<strong>in</strong>g the lifecycle (3)<br />
• No usage of <strong>JSF</strong> validation facility<br />
• Do it yourself <strong>in</strong>side the action method<br />
• WARNING: converter is still needed<br />
• Maybe: special converter, which doesn’t<br />
generate a error message<br />
47
Chang<strong>in</strong>g the lifecycle (4)<br />
• Go to “Render-Response” by call<strong>in</strong>g:<br />
public void renderResponse();<br />
• Stopp<strong>in</strong>g the <strong>JSF</strong> lifecycle by call<strong>in</strong>g:<br />
public void responseComplete();<br />
48
PhaseListener - configuration<br />
• <strong>JSF</strong> provides a special Listener for the lifecycle<br />
• PhaseListener executed at the beg<strong>in</strong>n<strong>in</strong>g <strong>and</strong> at<br />
the end of a phase.<br />
• register <strong>in</strong> faces-config.xml:<br />
<br />
<br />
org.apache.confs.eu.PhaseListener<br />
<br />
<br />
49
PhaseListener - Sample<br />
public class DebugPhaseListener<br />
implements PhaseListener<br />
{<br />
public void beforePhase(PhaseEvent event){}<br />
}<br />
public void afterPhase(PhaseEvent event){<br />
System.out.pr<strong>in</strong>tln("afterPhase");<br />
}<br />
public PhaseId getPhaseId(){<br />
return PhaseId.ANY_PHASE;<br />
// return PhaseId.INVOKE_APPLICATION;<br />
}<br />
50
Exercise - Phaselistener<br />
• Create your own PhaseListener clazz.<br />
• Use it to debug your <strong>JSF</strong> web app.<br />
• Register it to your faces-config.<br />
• Play with the application <strong>and</strong> look what‘s<br />
go<strong>in</strong>g on!<br />
• HElP? Ask!<br />
51
terms ...<br />
… from the <strong>JSF</strong> world<br />
52
terms (1)<br />
• Component<br />
• Renderer<br />
• Converter<br />
• Validator<br />
• Event / EventListener<br />
• Message / FacesMessage<br />
• <strong>Action</strong> Method<br />
• Model Objects<br />
• View<br />
• Navigation System /<br />
NavigationH<strong>and</strong>ler<br />
• Back<strong>in</strong>g Bean / Managed Bean<br />
• Value B<strong>in</strong>d<strong>in</strong>g<br />
53
Components<br />
• <strong>in</strong>teraction with the user<br />
• server side (compared to Sw<strong>in</strong>g or SWT)<br />
• support for IDEs b/c of JavaBean st<strong>and</strong>ard<br />
• std. components: renderer <strong>in</strong>dependent<br />
• know their state (StateHolder <strong>in</strong>terface)<br />
• stored <strong>in</strong> a tree structure (parent-client)<br />
• unique id<br />
54
Components<br />
• <strong>in</strong>teraction with the user<br />
• server side (compared to Sw<strong>in</strong>g or SWT)<br />
• support for IDEs b/c of JavaBean st<strong>and</strong>ard<br />
• std. components: renderer <strong>in</strong>dependent<br />
• know their state (StateHolder <strong>in</strong>terface)<br />
• stored <strong>in</strong> a tree structure (parent-client)<br />
• unique id<br />
55
Renderer<br />
• called by the component<br />
• renders a special markup (HTML or WML)<br />
• all Renderers belong to a RenderKit<br />
• Renderer takes care of:<br />
• Encod<strong>in</strong>g <strong>and</strong> Decod<strong>in</strong>g<br />
56
digression: render<strong>in</strong>g<br />
• Direct implementation model<br />
• Component -> encodeEnd -> HTML<br />
• Delegated implementation model<br />
• Component -> encodeEnd-> Renderer-<br />
>encodeEnd -> for <strong>in</strong>stance HTML<br />
57
Converters<br />
• data type <strong>in</strong> HTTP, HTML is “Str<strong>in</strong>g”<br />
• <strong>JSF</strong> back<strong>in</strong>g beans: all type are possible<br />
• Due to this, convert<strong>in</strong>g mechanism needed<br />
• used for i18n <strong>and</strong> l10n<br />
• converter choice based on data type<br />
• custom converters<br />
58
connect<strong>in</strong>g a converter<br />
• as child element:<br />
<br />
<br />
<br />
• build-<strong>in</strong> custom converter:<br />
<br />
59
st<strong>and</strong>ard DateTimeConverter<br />
• for date / time values:<br />
<br />
60
st<strong>and</strong>ard NumberConverter<br />
• <br />
61
Example - converters<br />
• Us<strong>in</strong>g the st<strong>and</strong>ard converters<br />
• convert<strong>in</strong>g a date<br />
• your birthdate<br />
• convert the <strong>in</strong>put <strong>and</strong> the output<br />
• convert<strong>in</strong>g a number<br />
• your salary ☺<br />
• use the NumberConverter<br />
• Need help? Scream!!<br />
62
custom converter (1)<br />
• implements javax.faces.convert.Converter<br />
• optional (has arguments to save)<br />
javax.faces.component.StateHolder<br />
• implements the methods:<br />
•getAsStr<strong>in</strong>g();<br />
•getAsObject();<br />
• on error:<br />
•throw new ConverterException(<br />
FacesMessage msg)<br />
63
custom converter (2)<br />
• JSP-Tag possible (extends ConverterTag)<br />
• not needed for Facelets...<br />
• JavaBean constructor that calls <strong>in</strong>side<br />
setConverterId()<br />
• only setter for its properties<br />
• overwrite createConverter()<br />
• register <strong>in</strong> faces-config.xml / tag.tld<br />
• register <strong>in</strong> tag.tld (only JSP)<br />
64
Overwrit<strong>in</strong>g a converter<br />
• all converter are describe <strong>in</strong> faces-config.xml<br />
• replace a st<strong>and</strong>ard convert with your custom:<br />
<br />
<br />
java.util.Date<br />
<br />
<br />
org.apache.confs.eu.MyDateTimeConverter<br />
<br />
<br />
65
Exercise – custom converter<br />
• Write your first custom converter<br />
• Implement it <strong>in</strong>side your back<strong>in</strong>g bean<br />
• Convert<strong>in</strong>g a TelephonNumber.java object<br />
• Str<strong>in</strong>g countryCode<br />
• Str<strong>in</strong>g areaCode<br />
• Str<strong>in</strong>g number<br />
• Help needed ? ☺<br />
66
validation<br />
• Checks the converted value aga<strong>in</strong>st a special rule<br />
• st<strong>and</strong>ard: done on the server (client side is possible…)<br />
• per component approach<br />
• validation error generates a FacesMessage<br />
• diplayed with or <br />
• custom validators possible<br />
67
connect<strong>in</strong>g a validator<br />
• validation for m<strong>and</strong>atory values:<br />
<br />
• validation aga<strong>in</strong>s a special scope (here a range):<br />
<br />
<br />
<br />
68
st<strong>and</strong>ard validators<br />
• length:<br />
<br />
• range (long):<br />
<br />
• range (double):<br />
<br />
maxiumum<br />
69
comb<strong>in</strong><strong>in</strong>g validators<br />
• it’s possible to comb<strong>in</strong>e validators<br />
• sample:<br />
<br />
<br />
<br />
<br />
70
Example – validator<br />
• us<strong>in</strong>g the st<strong>and</strong>ards<br />
• declare a field you want as m<strong>and</strong>atory<br />
• required<br />
• check the length of your zip code<br />
• validateLength<br />
• Ask if you need help!<br />
71
custom validation (1)<br />
• pretty easy to def<strong>in</strong>e a custom validator<br />
• implement a method like<br />
public void validate(FacesContext, UIComponent,<br />
Object) throws ValidatorException<br />
• wire the validation to the component:<br />
<br />
72
custom validation (2)<br />
public void validate(<br />
FacesContext context,<br />
UIComponent component,<br />
Object value) throws ValidatorException<br />
{<br />
if(value <strong>in</strong>stanceof Str<strong>in</strong>g)<br />
{<br />
Str<strong>in</strong>g strValue = (Str<strong>in</strong>g) value;<br />
}<br />
}<br />
if(!(strValue.equals(“yes") &&<br />
!(strValue.equals("no"))<br />
{<br />
throw new ValidatorException(<br />
new FacesMessage(messageText, null));<br />
}<br />
73
custom validation(3)<br />
• implement the <strong>in</strong>terface<br />
javax.faces.validator.validator<br />
• Optional (arguments?)<br />
javax.faces.component.StateHolder<br />
• overwrite method:<br />
•validate();<br />
• On error:<br />
•throw new ValidatorException(<br />
FacesMessage msg)<br />
74
custom validation (4)<br />
• JSP-Tag possible (extends ValidatorTag)<br />
• not needed when us<strong>in</strong>g Facelets<br />
• JavaBean constructor<br />
• setter for the properties<br />
• overwrite createValidator()<br />
<strong>and</strong> call setValidatorId()<br />
• register <strong>in</strong> faces-config.xml<br />
• register <strong>in</strong> tag.tld (no need when us<strong>in</strong>g<br />
Facelets)<br />
75
H<strong>and</strong>s-on: custom validation<br />
• create a simple custom validator <strong>in</strong>side of your<br />
back<strong>in</strong>g bean<br />
• check if the submitted value is a email address<br />
• We don‘t want you to use that RegExpr. stuff, so<br />
simple check if „@“ is <strong>in</strong>side the submitted Str<strong>in</strong>g.<br />
• Questions ?<br />
76
Events / EventListener<br />
• fired due an event<br />
• <strong>JSF</strong> def<strong>in</strong>es four st<strong>and</strong>ard events:<br />
• FacesEvent (abstract)<br />
• ValueChangeEvent<br />
• <strong>Action</strong>Event<br />
• PhaseEvent<br />
• DataModelEvent (not a FacesEvent)<br />
77
ValueChangeListener (1)<br />
• UIInput’s "valueChangeListener" attribut<br />
• Usage:<br />
<br />
• the back<strong>in</strong>g bean:<br />
public void processValueChange(ValueChangeEvent event)<br />
{<br />
HtmlInputText sender =<br />
(HtmlInputText)event.getComponent();<br />
sender.setReadonly(true);<br />
changePanel.setRendered(true);<br />
}<br />
78
ValueChangeListener (2)<br />
• Us<strong>in</strong>g the JSP-Tag:<br />
<br />
<br />
<br />
• The „example.TestListener“:<br />
public class TestListener implements ValueChangeListener<br />
{<br />
public void processValueChange(ValueChangeEvent event)<br />
throws AbortProcess<strong>in</strong>gException {<br />
HtmlInputText sender = (HtmlInputText)event.getComponent();<br />
sender.setReadonly(true);<br />
changePanel.setRendered(true);<br />
}<br />
}<br />
79
Example - ValueChangeEvent<br />
• Let‘s check some submitted values<br />
• use the valueChangeListener attribute<br />
• Pr<strong>in</strong>t old <strong>and</strong> new value by us<strong>in</strong>g<br />
System.out.pr<strong>in</strong>tln();<br />
• HELP ?!?<br />
80
<strong>Action</strong>Event<br />
• UIComm<strong>and</strong>’s "action" attribut<br />
• usage:<br />
• hard coded Str<strong>in</strong>g (like “success“)<br />
• use <strong>JSF</strong>’ MethodB<strong>in</strong>d<strong>in</strong>g<br />
"#{actionBean.newDetail}"<br />
• back<strong>in</strong>g bean needs:<br />
public Str<strong>in</strong>g newDetail()<br />
81
<strong>Action</strong>Listener<br />
• UIComm<strong>and</strong>’s "actionListener" attribut<br />
• usage:<br />
• MethodB<strong>in</strong>d<strong>in</strong>g.<br />
"#{actionBean.newDetailListener}"<br />
• the method:<br />
public void<br />
newDetailListener(<strong>Action</strong>Event e)<br />
82
Example – <strong>Action</strong><br />
Events<br />
• add the „actionListener“ attribute to your<br />
button/l<strong>in</strong>k component<br />
• create the method <strong>and</strong> do some<br />
System.out.pr<strong>in</strong>tln();<br />
• create the Method for the „action“ attribute<br />
• add some System.out.pr<strong>in</strong>tln(); to your action<br />
method too<br />
• What‘s happen<strong>in</strong>g?<br />
83
eturn value from action method<br />
• return value:<br />
• used to def<strong>in</strong>e the next view<br />
• described <strong>in</strong> faces-config.xml as<br />
• a “Navigation-Rules”<br />
• from-view-id<br />
• or global<br />
• action source (method <strong>and</strong> outcome)<br />
• to-view-id<br />
84
Messages<br />
• created when conversion/validation fails<br />
• st<strong>and</strong>ard messages def<strong>in</strong>ed:<br />
javax.faces.Messages.properties<br />
• JSP-Tag used for display<strong>in</strong>g them:<br />
<br />
!!!<br />
85
Messages<br />
• st<strong>and</strong>ard messages don’t fit to every use-case<br />
• validation message:<br />
• "{0}": Input required.<br />
• overwrite them easily <strong>in</strong> your ResourceBundle<br />
• javax.faces.component.UIInput.REQUIRED_d<br />
etail = {0} please enter a value<br />
86
Messages<br />
• provid<strong>in</strong>g custom messages (due to log<strong>in</strong> error)<br />
• FacesContext.getCurrentInstance()<br />
.addMessage(clientId, FacesMessage)<br />
• clientId = component’s id (or null for global)<br />
• new FacesMessage(FacesMessage.Severity<br />
summary, detail)<br />
•WARN, INFO, FATAL, ERROR<br />
87
ack<strong>in</strong>g beans / managed beans<br />
• POJO – Pla<strong>in</strong> Old Java Objects<br />
• Java Beans<br />
•„public“ constructor with no args<br />
•„private“ properties<br />
•„getter“/“setter“<br />
• declare them <strong>in</strong> faces-config.xml<br />
88
ack<strong>in</strong>g beans / managed beans<br />
• possible scopes<br />
• application (one <strong>in</strong>stance per application)<br />
• session (one <strong>in</strong>stance per session/user)<br />
• request (one <strong>in</strong>stance per request)<br />
• none (bean created due to a reference)<br />
89
ValueB<strong>in</strong>d<strong>in</strong>g / ValueExpression<br />
• ValueB<strong>in</strong>d<strong>in</strong>g<br />
• Wire attribute to a back<strong>in</strong>g bean<br />
• usage<br />
<br />
• property "surName" from the bean "user"<br />
90
<strong>JSF</strong> St<strong>and</strong>ard Components<br />
• components, components, components ...<br />
91
st<strong>and</strong>ard components - Text<br />
• outputText<br />
<br />
• <strong>in</strong>putText<br />
<br />
92
st<strong>and</strong>ard components - UIComm<strong>and</strong><br />
• comm<strong>and</strong>L<strong>in</strong>k<br />
<br />
• comm<strong>and</strong>Button<br />
<br />
93
st<strong>and</strong>ard components - OutputL<strong>in</strong>k<br />
• HtmlComm<strong>and</strong>L<strong>in</strong>k used for postbacks.<br />
• L<strong>in</strong>k<strong>in</strong>g other websites:<br />
<br />
• Caution!: state get’s lost, s<strong>in</strong>ce this is not a postback<br />
• HTTP parameters:<br />
<br />
<br />
<br />
94
st<strong>and</strong>ard components - UIForm<br />
• <br />
st<strong>and</strong>ard components - UIPanel<br />
• Do<strong>in</strong>g Layout with <strong>JSF</strong><br />
• renders a HTML span element:<br />
• …<br />
• renders a HTML table:<br />
• …<br />
• amount of components must be a multiple of<br />
„columns“<br />
• If not use empty <br />
96
st<strong>and</strong>ard components – UIData<br />
• best for present<strong>in</strong>g structured data (like java.util.List)<br />
• horizontal: every column is def<strong>in</strong>ed by a UIColumn<br />
component<br />
• vertical: each row represents one item of the<br />
structured data<br />
• Facets () allow def<strong>in</strong><strong>in</strong>g header <strong>and</strong> footer<br />
97
st<strong>and</strong>ard components - UIData<br />
• Example:<br />
<br />
<br />
<br />
<br />
<br />
98
st<strong>and</strong>ard components - Image<br />
• usage:<br />
<br />
• No component for an “ImageMaps”<br />
def<strong>in</strong>ed <strong>in</strong>side the <strong>JSF</strong> Spec.<br />
99
st<strong>and</strong>ard components - UIInput<br />
• text <strong>in</strong>put<br />
• <br />
• password <strong>in</strong>put<br />
• <br />
• hidden field:<br />
• <br />
• textareas<br />
• <br />
100
st<strong>and</strong>ard components - Label<br />
• Label for a component<br />
<br />
<br />
• <strong>Apache</strong> <strong>MyFaces</strong>: label text can be used <strong>in</strong><br />
FacesMessage<br />
101
st<strong>and</strong>ard components - Format<br />
• parameterised output:<br />
<br />
<br />
<br />
<br />
• Important for i18n <strong>and</strong> l10n<br />
102
st<strong>and</strong>ard components -<br />
UISelectBoolean<br />
• <strong>in</strong>put field for boolean/Boolean values<br />
• like:<br />
<br />
103
st<strong>and</strong>ard components - UISelectMany<br />
• Choose more than one <strong>in</strong>put value<br />
• JSP tags:<br />
• <br />
• <br />
• <br />
• rendered as<br />
• list of checkboxes,<br />
• html listbox,<br />
• or as a menu (not that good one…)<br />
104
st<strong>and</strong>ard components - UISelectOne<br />
• Choose one value<br />
• components:<br />
• <br />
• <br />
• <br />
• rendered:<br />
• list of radio fields,<br />
• listbox,<br />
• or as a combobox<br />
105
st<strong>and</strong>ard components – UISelectItem(s)<br />
• use them <strong>in</strong> or<br />
<br />
• like:<br />
•<br />
•<br />
•Array, Collection mit SelectItem<br />
•Map.put(Str<strong>in</strong>g, SelectItem);<br />
106
st<strong>and</strong>ard components – UISelectItem(s)<br />
• comb<strong>in</strong>e the <br />
• use for an empty entry<br />
• pick the real choices from a java.util.List<br />
• <br />
<br />
<br />
<br />
107
Creat<strong>in</strong>g <strong>JSF</strong> views<br />
• All JSP-Tags of <strong>JSF</strong> must be <strong>in</strong>side the root:<br />
<br />
(UIViewRoot).<br />
• If you need or wrap<br />
them with:<br />
(UINam<strong>in</strong>gConta<strong>in</strong>er)<br />
• Needed for Tiles <strong>in</strong>tegration too!<br />
108
MessageBundles<br />
• i18n:<br />
<strong>JSF</strong> 1.1 workarounds - verbatim<br />
• the “<strong>JSF</strong> <strong>and</strong> JSP” comb<strong>in</strong>ation has problems, when us<strong>in</strong>g pla<strong>in</strong><br />
HTML <strong>in</strong>side your page<br />
• embedded HTML output is rendered directly; <strong>JSF</strong> goes to a buffer…<br />
• work around:<br />
• wrap all pla<strong>in</strong> HTML <strong>in</strong>side a<br />
• …<br />
• simply adds a HtmlOutputText component<br />
• fixed <strong>in</strong> <strong>JSF</strong> 1.2 spec<br />
110
Unified Expression Language<br />
• Value- <strong>and</strong> Method-Expressions<br />
111
• JSP EL<br />
• <strong>JSF</strong> EL<br />
Unified EL<br />
<strong>JSF</strong> 1.2 Unified EL<br />
• <strong>JSF</strong> EL Syntax refers to JSP EL<br />
• but: <strong>JSF</strong> EL – expressions are evaluated<br />
deferred, JSP – EL immediate<br />
112
Samples for the UL (1)<br />
• value="#{user.username}„<br />
• value="#{person.address.street}"<br />
• rendered="#{user.username != null}„<br />
• value="#{bill.sum *13.7603}"<br />
• style="#{grid.displayed ?<br />
’display:<strong>in</strong>l<strong>in</strong>e;’ : ’display:none;’}"<br />
• value="Hallo Benutzer #{user.username}"<br />
113
Samples for the UL (2)<br />
•action="#{user.storeUser}"<br />
•actionListener="#{dtBean.delete<br />
Row}"<br />
•value="#{mapBean[’<strong>in</strong>dex’]}"<br />
•value="#{mapBean[user.username]<br />
}"<br />
•value="#{listBean[5]}"<br />
114
Configuration<br />
• <strong>JSF</strong> configured <strong>in</strong> a proper way<br />
115
configuration (1)<br />
• required: copy <strong>JSF</strong>/<strong>MyFaces</strong> jar-files to WEB-<br />
INF/lib<br />
• register FacesServlet <strong>in</strong>side web.xml<br />
• edit your faces-config.xml file for further <strong>JSF</strong><br />
configurations like<br />
• back<strong>in</strong>g beans<br />
• components …<br />
116
faces-config.xml – managed beans<br />
• managed beans:<br />
<br />
The one <strong>and</strong> only<br />
HelloBean.<br />
helloBean<br />
<br />
<br />
org.apache.hello.HelloBean<br />
<br />
request<br />
<br />
<br />
• Scope: application, session, request, none<br />
117
faces-config.xml – navigation rules<br />
• the navigation rules:<br />
<br />
<br />
/limit_list.jsp <br />
<br />
<br />
show_item<br />
/limit_detail.jsp<br />
<br />
<br />
<br />
118
faces-config.xml - enhanced<br />
• <strong>JSF</strong> is customisable<br />
• <strong>in</strong>side element<br />
• provid<strong>in</strong>g of custom <strong>Action</strong>Listener,<br />
ViewH<strong>and</strong>ler, NavigationH<strong>and</strong>ler,<br />
ELResolver, StateManager possible<br />
• sett<strong>in</strong>g of l10n<br />
• this is a central po<strong>in</strong>t!<br />
119
web.xml – what is needed?<br />
• FacesServlet:<br />
<br />
Faces Servlet<br />
<br />
<br />
javax.faces.webapp.FacesServlet<br />
<br />
1<br />
<br />
<br />
Faces Servlet<br />
<br />
/faces/*<br />
<br />
<br />
<br />
120
web.xml – <strong>JSF</strong> config<br />
<br />
<br />
javax.faces.CONFIG_FILES<br />
<br />
/WEB-INF/examples-config.xml<br />
<br />
<br />
Comma separated list of URIs of<br />
(additional) faces config files.<br />
(e.g. /WEB-INF/my-config.xml)<br />
See <strong>JSF</strong> 1.0 PRD2, 10.3.2<br />
<br />
<br />
121
web.xml – state sav<strong>in</strong>g<br />
<br />
<br />
javax.faces.STATE_SAVING_METHOD<br />
<br />
client<br />
<br />
State sav<strong>in</strong>g method: "client" or<br />
"server" (= default)See <strong>JSF</strong><br />
Specification 2.5.2<br />
<br />
<br />
122
<strong>Apache</strong> <strong>MyFaces</strong><br />
First Free Open Source <strong>JSF</strong> Implementation<br />
123
<strong>JSF</strong> Implementations<br />
• Sun (RI)<br />
• IBM<br />
• <strong>Apache</strong> <strong>MyFaces</strong><br />
• Simplica (based on <strong>Apache</strong> <strong>MyFaces</strong>)<br />
• additionally, there are several 3rd party UI components that<br />
should run with any implementation.<br />
124
<strong>Apache</strong> <strong>MyFaces</strong><br />
• Founded <strong>in</strong> 2002 by Manfred Geiler <strong>and</strong> Thomas<br />
Spiegl, CEO of IRIAN.at<br />
• sourceforge <strong>and</strong> LGPL based<br />
• In July 2004: move to <strong>Apache</strong> Software<br />
Foundation (Incubator)<br />
• S<strong>in</strong>ce February 2005 TLP (myfaces.apache.org)<br />
• 25 developers<br />
• currently 1.1.1<br />
125
<strong>MyFaces</strong> provides:<br />
• Implementation of <strong>JSF</strong>-API<br />
• javax.faces.** Classes<br />
• Implementation of <strong>JSF</strong> Spec<br />
• org.apache.myfaces.** Classes<br />
• Custom Components<br />
• Scrollable Table, Validator, Tree components …<br />
• Custom extensions<br />
• Built-<strong>in</strong> Tiles-Support, RenderKit for WML/WAP<br />
• Support for Portlet Spec (JSR 168)<br />
• <strong>MyFaces</strong> apps runs <strong>in</strong> Pluto, JBoss Portal <strong>and</strong> some others.<br />
126
JAR files of <strong>Apache</strong> <strong>MyFaces</strong><br />
• myfaces-impl.jar<br />
• myfaces-jsf-api.jar<br />
• tomahawk.jar<br />
• s<strong>and</strong>box.jar<br />
• myfaces-all.jar (all <strong>in</strong> one jar file –<br />
except s<strong>and</strong>box)<br />
127
<strong>MyFaces</strong> compatibility (tested)<br />
• Java 1.4 <strong>and</strong> Java5<br />
• Tomcat (4.1.x, 5.0.x <strong>and</strong> 5.5.x)<br />
• JBoss (3.2.x <strong>and</strong> 4.0.x)<br />
• JRun4<br />
• Bea Weblogic 8.1<br />
• Jonas 3.3.6 w/ Tomcat<br />
• Res<strong>in</strong> 2.1.x<br />
• Jetty 4.2<br />
• Websphere 5.1.2<br />
• OC4J<br />
128
• ExtensionsFilter<br />
<strong>MyFaces</strong> Internals I<br />
• used dur<strong>in</strong>g upload (parses Multipart<br />
requests)<br />
• adds resources (images, js,...) that are<br />
needed by components (easier to reuse<br />
components)<br />
• good performance<br />
129
<strong>MyFaces</strong> Internals II<br />
• special Servlet Context parameter<br />
• ALLOW_JAVASCRIPT<br />
• DETECT_JAVASCRIPT<br />
• AUTO_SCROLL<br />
• PRETTY_HTML<br />
• dummy form for comm<strong>and</strong>L<strong>in</strong>ks<br />
130
<strong>MyFaces</strong> <strong>in</strong> <strong>Action</strong><br />
• several custom components<br />
• custom validator components<br />
• custom extensions<br />
131
Custom calendar component<br />
• Renders as a form:<br />
<br />
• Renders as a popup:<br />
<br />
• Sample<br />
132
Custom Upload Component<br />
• Upload is not part of <strong>JSF</strong> spec (currently)<br />
• uses Servlet Filter (<strong>MyFaces</strong>‘ Extension Filter)<br />
• special <strong>in</strong>terface<br />
(org.apache.myfaces.custom.fileupload.UploadedFile)<br />
<br />
Tree Component (Tree2)<br />
• <strong>MyFaces</strong> provides two tree components<br />
• def<strong>in</strong>e your data <strong>in</strong>side a back<strong>in</strong>g bean<br />
• TreeNode (Interface)<br />
• TreeNodeBase (Implementation class)<br />
• def<strong>in</strong>e your layout <strong>in</strong> a <strong>JSF</strong> page via facets<br />
• Navigation via Comm<strong>and</strong>L<strong>in</strong>k component<br />
• client <strong>and</strong> server toggle<br />
134
Tree Component Java code<br />
private TreeNode tree;<br />
tree = new<br />
TreeNodeBase(„folder“,“navi“,true);<br />
tree.getChildren().add(<br />
new TreeNodeBase(„doc“,“entry“,false)<br />
)<br />
135
Tree Component JSP<br />
<br />
<br />
<br />
<br />
<br />
<br />
...<br />
Sample<br />
136
Tabbed Pane<br />
• Tab control as known from classic GUIs<br />
• Conta<strong>in</strong>s two custom <strong>JSF</strong> tags<br />
• <br />
• <br />
• reuses st<strong>and</strong>ard UI components<br />
• for <strong>in</strong>stance <br />
• click on a tab ends up <strong>in</strong> a request, but tab saves the<br />
state of the nested <strong>in</strong>put fields<br />
137
Tabbed Pane JSP code<br />
<br />
<br />
<br />
<br />
...<br />
<br />
<br />
...<br />
<br />
<br />
<br />
• Sample<br />
138
custom Table component<br />
• <strong>MyFaces</strong> conta<strong>in</strong>s a custom table component<br />
• extends UIData (st<strong>and</strong>ard component)<br />
• preserveDataModel<br />
• preserveRowState<br />
• sortColumn<br />
• sortAscend<strong>in</strong>g<br />
• preserveSort<br />
• renderedIfEmpty<br />
• rowIndexVar<br />
139
scrollable Table component<br />
<br />
<br />
<br />
<br />
...<br />
<br />
Sample<br />
140
sortable Table component<br />
• needs <strong>MyFaces</strong> attributes:<br />
• sortColumn=“#{sorter.sort}”<br />
• sortAscend<strong>in</strong>g=“#{sorter.asc}”<br />
• preserveSort=“true”<br />
• uses <strong>MyFaces</strong> Back<strong>in</strong>gBean needs<br />
method (sort()) that conta<strong>in</strong>s a Comparator impl.<br />
• call sort() before return the data model.<br />
• here: call <strong>in</strong>side of getWorkers();<br />
• Sample<br />
141
Us<strong>in</strong>g *Legacy* JavaScript<br />
• <strong>JSF</strong> Components us<strong>in</strong>g IDs:<br />
<br />
<br />
<br />
generates foo:bar<br />
• document.getElementById();<br />
• special forceId Attribute (<strong>JSF</strong> 1.2 conta<strong>in</strong>s a similar<br />
concept):<br />
<br />
<br />
<br />
generates bar<br />
142
Custom Validators<br />
• nest them <strong>in</strong>side Input Components<br />
<br />
<br />
<br />
• ISBN ()<br />
• CreditCard ()<br />
• Regular Expression<br />
<br />
• Equal<br />
<br />
<br />
<br />
<br />
143
<strong>JSF</strong> – compos<strong>in</strong>g pages<br />
• St<strong>and</strong>ard provides a pla<strong>in</strong> subview component<br />
• or <br />
• realizes the Composite View Pattern<br />
• bound to file names (e.g. footer.jsp)<br />
• good framework for compos<strong>in</strong>g pages<br />
• Tiles (used <strong>in</strong> Struts, Velocity or pla<strong>in</strong> JSP)<br />
144
<strong>MyFaces</strong> Tiles <strong>in</strong>tegration<br />
• custom ViewH<strong>and</strong>ler for Tiles<br />
• must be registed <strong>in</strong> faces-config.xml<br />
• needs tiles configuration location as<br />
ContextParameter (web.xml)<br />
• looks up *.tiles mapp<strong>in</strong>gs <strong>in</strong> tiles def<strong>in</strong>ition file<br />
• page def<strong>in</strong>itions are described <strong>in</strong> tiles.xml<br />
• known issues<br />
• none-tiles pages must be wrapped <strong>in</strong>side of tiles config<br />
145
<strong>MyFaces</strong>/Tiles - def<strong>in</strong>itions<br />
<br />
<strong>MyFaces</strong>/Tiles – master template<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<strong>MyFaces</strong>‘ WML RenderKit<br />
• supports basic <strong>JSF</strong> components to render <strong>in</strong><br />
WAP devices<br />
• supports WML <strong>and</strong> not XHTML MP (WAP2.0)<br />
• add WML RenderKit to faces-config.xml<br />
• uses XDoclet to generate components, tag<br />
classes <strong>and</strong> tld file<br />
• contribution from Jiri Zaloudek<br />
148
WML RenderKit - code<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<strong>MyFaces</strong> – Portlet support<br />
• Built-<strong>in</strong>-support for JSR 168<br />
• contribution by Stan Silvert (JBoss Group)<br />
• what must a user do?<br />
• Make sure your <strong>JSF</strong> <strong>MyFaces</strong> application runs as a st<strong>and</strong>-alone servlet.<br />
• Remove any redirects from your faces-config.xml. Portlets can not<br />
h<strong>and</strong>le these.<br />
• Create a Portlet WAR as per the <strong>in</strong>structions for your Portlet<br />
conta<strong>in</strong>er. Make sure it conta<strong>in</strong>s everyth<strong>in</strong>g that was <strong>in</strong>cluded <strong>in</strong> step<br />
1.<br />
• Update your portlet.xml<br />
150
<strong>MyFaces</strong> – portlet.xml<br />
<br />
org.apache.myfaces.portlet.<strong>MyFaces</strong>GenericPortlet<br />
<br />
<br />
default-view<br />
/some_view_id_from_faces-config<br />
<br />
<br />
default-view-selector<br />
com.foo.MyViewSelector<br />
<br />
151
Long term visions for <strong>MyFaces</strong><br />
• Big TLP for <strong>JSF</strong> <strong>in</strong> general<br />
• <strong>Apache</strong> Faces<br />
• <strong>MyFaces</strong> provides only API <strong>and</strong> impl<br />
• <strong>MyFaces</strong> should be a subproject of <strong>Apache</strong> Faces<br />
• more a dream, currently :-)<br />
• <strong>JSF</strong> 1.2 compliant implementation<br />
• WML RenderKit <strong>in</strong>tegration ... :-)<br />
152
Writ<strong>in</strong>g Custom Components<br />
If the st<strong>and</strong>ard doesn‘t solve your Problems<br />
...<br />
153
Preparations<br />
• What is your super class ?<br />
UIOutput, UIInput, UISelectOne,<br />
UISelectMany, UIComm<strong>and</strong>, UIPanel<br />
• classification: component family,<br />
component type <strong>and</strong> renderer type to be<br />
def<strong>in</strong>ed<br />
154
Examples:<br />
• org.apache.myfaces.HtmlInputText<br />
• component type: org.apache.myfaces.HtmlInputText<br />
• component family: javax.faces.Input<br />
• renderer type: org.apache.myfaces.Text<br />
• javax.faces.component.html.HtmlInputText<br />
• component type: javax.faces.HtmlInputText<br />
• component family: javax.faces.Input<br />
• renderer type: javax.faces.Text<br />
155
Examples<br />
• org.apache.myfaces.custom.tabbedpane.HtmlPanelTabbedPane<br />
• component type: org.apache.myfaces.HtmlPanelTabbedPane<br />
• component family: javax.faces.Panel<br />
• Renderertyp: org.apache.myfaces.TabbedPane<br />
• org.apache.myfaces.custom.navmenu.UINavigationMenuItem<br />
• Komponententyp: org.apache.myfaces.NavigationMenuItem<br />
• Komponentenfamilie: javax.faces.SelectItem<br />
• Renderertyp: null<br />
156
classification by:<br />
• component class:<br />
• UIComponent.getComponentType();<br />
• UIComponent.getComponentFamily();<br />
• <strong>in</strong> constructor: super.setDefaultRendererType(<br />
DEFAULT_RENDERER_TYPE);<br />
• JSP-Tag class<br />
• UIComponentTag.getComponentType();<br />
• UIComponentTag.getRendererType();<br />
157
Tag-Library-Def<strong>in</strong>ition TLD<br />
• st<strong>and</strong>ard JSP taglib file:<br />
<br />
<br />
comm<strong>and</strong>Button<br />
<br />
org.apache.myfaces.taglib.html.ext.HtmlComm<strong>and</strong>ButtonTag<br />
<br />
JSP<br />
<br />
Extended st<strong>and</strong>ard comm<strong>and</strong>Button<br />
<br />
<br />
action<br />
false<br />
false<br />
java.lang.Str<strong>in</strong>g<br />
<br />
…<br />
<br />
158
A JSP-Tag class for <strong>JSF</strong><br />
components<br />
• setXXX() for each propety<br />
• release() method:<br />
set every property back to “null”<br />
• implement the setProperties(); method<br />
159
A <strong>JSF</strong>/JSP-Tag class<br />
protected void setProperties(UIComponent component)<br />
{<br />
super.setProperties(component);<br />
setStr<strong>in</strong>gProperty(component,<br />
HTML.TABINDEX_ATTR, _tab<strong>in</strong>dex);<br />
setStr<strong>in</strong>gProperty(component,<br />
HTML.TYPE_ATTR, _type);<br />
set<strong>Action</strong>Property(component, _action);<br />
set<strong>Action</strong>ListenerProperty(component,<br />
_actionListener);<br />
setBooleanProperty(component,<br />
<strong>JSF</strong>Attr.IMMEDIATE_ATTR, _immediate);<br />
setStr<strong>in</strong>gProperty(component, <strong>JSF</strong>Attr.IMAGE_ATTR,<br />
_image);<br />
}<br />
160
component class<br />
• JavaBean std. (getter/setter for property)<br />
• Caution! Take care of <strong>JSF</strong>’s ValueB<strong>in</strong>d<strong>in</strong>g<br />
• Overwrite restoreState() <strong>and</strong> saveState() to be<br />
able to save the component state<br />
• if needed methods for EventListener (like<br />
JavaBean std.)<br />
161
the getter / setter<br />
public void setValue(Object value)<br />
{<br />
_value = value;<br />
}<br />
public Object getValue()<br />
{<br />
if (_value != null) return _value;<br />
ValueB<strong>in</strong>d<strong>in</strong>g vb = getValueB<strong>in</strong>d<strong>in</strong>g("value");<br />
return vb != null ?<br />
(Object)vb.getValue(getFacesContext()) : null;<br />
}<br />
162
StateHolder’s saveState<br />
public Object saveState(FacesContext context)<br />
{<br />
}<br />
Object values[] = new Object[6];<br />
values[0] = super.saveState(context);<br />
values[1] = saveAttachedState(context,<br />
methodB<strong>in</strong>d<strong>in</strong>g<strong>Action</strong>Listener);<br />
values[2] = saveAttachedState(context,<br />
actionExpression);<br />
values[3] = immediate ? Boolean.TRUE :<br />
Boolean.FALSE;<br />
values[4] = immediateSet ? Boolean.TRUE :<br />
Boolean.FALSE;<br />
values[5] = value;<br />
return (values);<br />
163
StateHolder’s restoreState<br />
public void restoreState(FacesContext context,<br />
Object state)<br />
{<br />
//Die Variable "state" speichert den Zust<strong>and</strong><br />
//der Komponente als Feld von Objekten<br />
Object values[] = (Object[]) state;<br />
}<br />
//Rücksichern des vererbten Status<br />
super.restoreState(context, values[0]);<br />
//Rücksichern der Attribute der Komponente<br />
methodB<strong>in</strong>d<strong>in</strong>g<strong>Action</strong>Listener = (MethodB<strong>in</strong>d<strong>in</strong>g)<br />
restoreAttachedState(context, values[1]);<br />
actionExpression =<br />
(MethodExpression) restoreAttachedState(context, values[2]);<br />
immediate = ((Boolean) values[3]).booleanValue();<br />
immediateSet = ((Boolean) values[4]).booleanValue();<br />
value = values[5];<br />
164
Renderer<br />
public abstract class Renderer {<br />
public void decode(FacesContext context,<br />
UIComponent component{}<br />
public void encodeBeg<strong>in</strong>(FacesContext context,<br />
UIComponent component)<br />
throws IOException {}<br />
public void encodeChildren(FacesContext context,<br />
UIComponent component)<br />
throws IOException {}<br />
public void encodeEnd(FacesContext context,<br />
UIComponent component)<br />
throws IOException {}<br />
165
Renderer<br />
public Str<strong>in</strong>g convertClientId(FacesContext<br />
context, Str<strong>in</strong>g clientId) {}<br />
public boolean getRendersChildren() {}<br />
public Object getConvertedValue(FacesContext<br />
context, UIComponent component,<br />
Object submittedValue)<br />
throws ConverterException {}<br />
}<br />
166
Renderer - encodeEnd<br />
RendererUtils.checkParamValidity(facesContext,<br />
uiComponent, UIComm<strong>and</strong>.class);<br />
Str<strong>in</strong>g clientId = uiComponent.getClientId(facesContext);<br />
ResponseWriter writer = facesContext.getResponseWriter();<br />
writer.startElement(HTML.INPUT_ELEM, uiComponent);<br />
writer.writeAttribute(HTML.ID_ATTR, clientId,<br />
<strong>JSF</strong>Attr.ID_ATTR);<br />
writer.writeAttribute(HTML.NAME_ATTR, clientId,<br />
<strong>JSF</strong>Attr.ID_ATTR);<br />
…<br />
167
Alternatives<br />
Instead of custom components ...<br />
168
substitute the renderer<br />
• a renderer implements<br />
• encod<strong>in</strong>g (encodeXXX())<br />
• decod<strong>in</strong>g (decode())<br />
• convert<strong>in</strong>g process<br />
• You can substitute a renderer. Often this<br />
helps!<br />
169
substitute the renderer<br />
• this is done global<br />
• for each objects of a component<br />
• the new renderer will be used every time!<br />
• with the used RenderKit<br />
• a RenderKit conta<strong>in</strong>s all used renderers.<br />
• Only one RenderKit per <strong>JSF</strong> app<br />
• possible to change …<br />
170
substitute the renderer<br />
• faces-config.xml:<br />
<br />
HTML_BASIC<br />
<br />
<br />
javax.faces.Output<br />
<br />
javax.faces.Label<br />
<br />
mypackage.RequiredLabelRenderer<br />
<br />
<br />
<br />
171
the renderer class<br />
public class RequiredLabelRenderer extends HtmlLabelRenderer {<br />
protected void encodeBeforeEnd( FacesContext facesContext, ResponseWriter<br />
writer, UIComponent uiComponent) throws IOException {<br />
Str<strong>in</strong>g forAttr = getFor(uiComponent);<br />
if(forAttr!=null) {<br />
UIComponent forComponent =<br />
uiComponent.f<strong>in</strong>dComponent(forAttr);<br />
if(forComponent <strong>in</strong>stanceof UIInput &&<br />
((UIInput) forComponent).isRequired()) {<br />
writer.startElement(HTML.SPAN_ELEM, null);<br />
writer.writeAttribute(HTML.ID_ATTR,<br />
uiComponent.getClientId(facesContext)+<br />
"RequiredLabel",null);<br />
writer.writeAttribute(HTML.CLASS_ATTR,<br />
"requiredLabel",null);<br />
writer.writeText("*",null);<br />
writer.endElement(HTML.SPAN_ELEM);<br />
}}}}<br />
172
provide a JSP-Tag<br />
• without a new Tag every
substitute component class<br />
• component conta<strong>in</strong>s properties<br />
• encod<strong>in</strong>g, decod<strong>in</strong>g <strong>and</strong> conversion is also<br />
<strong>in</strong>cluded <strong>in</strong>to a component!<br />
• validation customisable<br />
• You can replace a component globally, means<br />
for all JSP-Tags (like the renderer).<br />
174
substitute component class<br />
• faces-config.xml:<br />
<br />
<br />
javax.faces.HtmlInputText<br />
<br />
mypackage.SpecialHtmlInputText<br />
<br />
<br />
175
the component class<br />
public class SpecialHtmlInputText extends<br />
HtmlInputText {<br />
public SpecialHtmlInputText()<br />
{<br />
super();<br />
}<br />
}<br />
setConverter(ConverterFactory.<br />
getSpecialConverter());<br />
176
component b<strong>in</strong>d<strong>in</strong>g<br />
• ValueB<strong>in</strong>d<strong>in</strong>g != component b<strong>in</strong>d<strong>in</strong>g<br />
• uses <strong>JSF</strong> EL:<br />
• „b<strong>in</strong>d<strong>in</strong>g=„#{bean.myComponent}“<br />
• return of special / own components,<br />
which fit the desired type, is possible<br />
177
component b<strong>in</strong>d<strong>in</strong>g<br />
• JSP:<br />
component b<strong>in</strong>d<strong>in</strong>g<br />
public static f<strong>in</strong>al class OutputTextWithBreaks extends HtmlOutputText<br />
{<br />
public OutputTextWithBreaks()<br />
{<br />
super();<br />
}<br />
public void encodeEnd(FacesContext context) throws<br />
IOException<br />
{<br />
Str<strong>in</strong>g text = RendererUtils.getStr<strong>in</strong>gValue(<br />
context, this);<br />
text = HTMLEncoder.encode(text, true, true);<br />
}<br />
}<br />
//Erstellen aller Zeilenumbrüche<br />
text = text.replaceAll("\r","");<br />
renderOutputText(context, this, text, false);<br />
179
Tips & Tricks<br />
That should be helpful ...<br />
180
dynamic relies not on a JSP<br />
add<strong>in</strong>g components to the component tree:<br />
public void addControls(<strong>Action</strong>Event actionEvent)<br />
{<br />
Application application =<br />
FacesContext.getCurrentInstance().getApplication();<br />
List children = controlPanel.getChildren();<br />
children.clear();<br />
for (<strong>in</strong>t count = 0; count < numControls; count++)<br />
{<br />
HtmlOutputText output = (HtmlOutputText)application.<br />
createComponent(HtmlOutputText.COMPONENT_TYPE);<br />
output.setValue(" " + count + " ");<br />
output.setStyle("color: blue");<br />
children.add(output);<br />
}<br />
}<br />
181
<strong>Action</strong>Listener for Navigation<br />
• <strong>in</strong>side the <strong>Action</strong>Listener:<br />
FacesContext.getCurrentInstance().<br />
getApplication().getNavigationH<strong>and</strong>ler().<br />
h<strong>and</strong>leNavigation(<br />
FacesContext.getCurrentInstance(),<br />
null, outcome);<br />
• Needs:<br />
• global navigation-rule for the Str<strong>in</strong>g outcome<br />
182
Us<strong>in</strong>g HTML <strong>in</strong>side OutputText<br />
• the tag:<br />
• <br />
• Problem: HTML will be „escaped“<br />
• like: <br/><br />
• work around:<br />
• <br />
183
pass<strong>in</strong>g arguments with the EL<br />
• EL expressions are powerful, but …<br />
… don’t take arguments<br />
• work around:<br />
• back<strong>in</strong>g bean implements Map <strong>in</strong>terface<br />
• On a Map.get(„key“) call, the method get’s<br />
called <strong>and</strong> a argument is passed throuhg („key“)<br />
• usage: #{mapBean[‚key‘]}<br />
184
Master Detail (1)<br />
• Liste:<br />
<br />
...<br />
<br />
...<br />
<br />
• us<strong>in</strong>g comm<strong>and</strong>L<strong>in</strong>k for edit<strong>in</strong>g the details<br />
• actionListener <strong>in</strong>stead of action<br />
185
Master Detail (2)<br />
• back<strong>in</strong>g bean:<br />
public void editItem(<strong>Action</strong>Event ev)<br />
{<br />
UIData datatable =<br />
f<strong>in</strong>dParentHtmlDataTable(<br />
ev.getComponent());<br />
Item item = (Item)<br />
datatable.getRowData()<br />
//edit the item...<br />
}<br />
186
Master Detail (3)<br />
• helper method:<br />
private HtmlDataTable f<strong>in</strong>dParentHtmlDataTable(<br />
UIComponent component)<br />
{<br />
if (component == null)<br />
{<br />
return null;<br />
}<br />
if (component <strong>in</strong>stanceof HtmlDataTable)<br />
{<br />
return (HtmlDataTable) component;<br />
}<br />
return f<strong>in</strong>dParentHtmlDataTable(<br />
component.getParent());<br />
}<br />
187
Master Detail (4)<br />
• other possibilities:<br />
• (well, ok…)<br />
• <strong>Apache</strong> <strong>MyFaces</strong>: <br />
• <br />
• When an action is called the “value” is set to a<br />
back<strong>in</strong>g bean’s property<br />
• <br />
188
show<strong>in</strong>g/ hid<strong>in</strong>g components<br />
• „rendered“ attribute:<br />
• should a component be rendered ?<br />
• JSP: <br />
• replacement for „c:if“ or ugly Java code (scriptlets)<br />
• Warn<strong>in</strong>g:<br />
• rendered evaluated dur<strong>in</strong>g each phase<br />
• also on a postback (no decod<strong>in</strong>g for not rendered components)<br />
189
L<strong>in</strong>ks<br />
• <strong>MyFaces</strong> AJAX examples<br />
• http://www.irian.at/open_source.jsf<br />
(s<strong>and</strong>box components)<br />
• AJAX web resources<br />
• http://www.adaptivepath.com<br />
• http://www.ajax<strong>in</strong>fo.com/<br />
• http://www.ajaxpatterns.org/Ajax_Frameworks<br />
• http://www.ajaxdeveloper.org<br />
190
Literature<br />
• Mann, Kito D. (2005): Java Server Faces <strong>in</strong> <strong>Action</strong>. Mann<strong>in</strong>g,<br />
Greenwich<br />
• Hall, Marty (2001): <strong>JSF</strong>. A quick <strong>in</strong>troduction to JavaServer Faces.<br />
http://www.coreservlets.com/<strong>JSF</strong>-Tutorial/<br />
• Bergsten, Hans (2004): JavaServer Faces. O'Reilly.<br />
• Dudney, Bill et. al (2004): Master<strong>in</strong>g JavaServer Faces. Wiley<br />
• Ed Burns et.al (2004): JavaServer Faces (Version 1.1.)<br />
Specification.<br />
191