12.06.2015 Views

JSF and Apache MyFaces in Action - ApacheCon

JSF and Apache MyFaces in Action - ApacheCon

JSF and Apache MyFaces in Action - ApacheCon

SHOW MORE
SHOW LESS

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: &lt;br/&gt;<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

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!