More Related Content
Similar to Best Practices for JSF, Gameduell 2013 (20)
More from Edward Burns (20)
Best Practices for JSF, Gameduell 2013
- 3. Program Agenda
Review of the JSF Lifecycle
Conversion and Validation
JSF Navigation Review
3
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.
- 4. The following is intended to outline our general product direction. It is intended
for information purposes only, and may not be incorporated into any contract.
It is not a commitment to deliver any material, code, or functionality, and should
not be relied upon in making purchasing decisions. The
development, release, and timing of any features or functionality described for
Oracle’s products remains at the sole discretion of Oracle.
4
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.
- 6. Review: The Lifecycle Orchestrates MVC
The Baseball and Apple Pie of Web apps
• Data Conversion and Validation
• Page Flow
• Database integration
• I18N, L10N, A11Y
• Support CSS, Markup based
layout
• User Friendliness!
6
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.
- 7. Review: The Lifecycle Orchestrates MVC
The Baseball and Apple Pie of Web apps
7
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.
- 8. Review: The Lifecycle Orchestrates MVC
The Baseball and Apple Pie of Web apps
• The JSF Lifecycle uses some elements of the
strategy design pattern
– Define a family of algorithms
– Encapsulate each one
– Make them interchangeable
• For each Lifecycle phase, traverse the
UIComponent hierarchy and take the
appropriate action.
• Inversion of control in the extreme
• Analogy with Maven: work with the framework, not against it.
8
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.
- 9. Review: The Lifecycle Orchestrates MVC
Additional details added
9
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.
- 10. Interacting with the Lifecycle
Phase Listeners and System Events
Phase Listeners
– coarse grained
– Not aware of individual components
– act before and after each lifecycle phase
System Event
– fine grained
– can be attached to an individual component instance
– act during each lifecycle phase
10
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.
- 11. Interacting with the Lifecycle
Phase Listeners
Similar in concept to Servlet Filter, but able to act within the JSF
lifecycle
How to implement them
– Provide an implementation of javax.faces.event.PhaseListener
– MethodExpression that takes a javax.faces.event.PhaseEvent
11
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.
- 12. PhaseListener
Implementing the Interface javax.faces.event.PhaseListener
public class MyPhaseListener implements PhaseListener {
public PhaseId getPhaseId() {
return (PhaseId.ANY_PHASE);
}
public void afterPhase(PhaseEvent event) {
System.out.println("afterPhase(" + event.getPhaseId() + ")");
}
public void beforePhase(PhaseEvent event) {
System.out.println("beforePhase(" + event.getPhaseId() + ")");
}
}
12
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.
- 13. PhaseListener
Declare to the Runtime
For all pages: faces-config.xml
<lifecycle>
<phase-listener>standard.MyPhaseListener</phase-listener>
</lifecycle>
Per-page: <f:phaseListener>
type attribute: fully qualified class name
binding attribute: expression that evaluates to the instance
13
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.
- 14. PhaseListener
How to impact the execution of the lifecycle
FacesContext.renderResponse()
– Skip to Render Response Phase
FacesContext.responseComplete()
– Do no further lifecycle processing on this request.
14
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.
- 15. Interacting with the Lifecycle
System Events
Publish/Subscribe event bus for things that happen during the JSF
Lifecycle, not application specific
Inspired by Solaris Dtrace, Linux strace, truss, etc.
Listeners can be registered at three scopes
– component UIComponent.subscribeToEvent()
– view UIViewRoot.subscribeToEvent()
– application Application.subscribeToEvent()
Publish is always with Application.publishEvent()
15
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.
- 17. Interacting with the Lifecycle
System Events
1.
2.
Implement the listener interface
Register for the event
–
<f:event> tag
–
faces-config.xml
<application>
<system-event-listener>
<system-event-listener-class>com.foo.MyListener
</system-event-listener-class>
<system-event-class>javax.faces.event.PreRenderViewEvent
</system-event-class>
</system-event-listener>
</application>
17
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.
- 19. Conversion and Validation
Type Safety for the UI
How does JSF handle the concept of “value”?
– Apply Request Values
unconverted string value pushed into UIComponent instances via
decode() method
– Process Validations
Value is converted with Converter and validated with Validator(s)
– Update Model Values
Value is pushed to value expression (if any)
– Render Response
Value is pulled from value expression
19
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.
- 20. Conversion and Validation
Type Safety for the UI
Behavior Based Interfaces
– ValueHolder
Anything that displays a value
– EditableValueHolder
When that value is editable by the end user.
20
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.
- 22. Converter
Standard Converters in package javax.faces.Convert
Throw ConverterException to indicate conversion failure
Failure added as per-component FacesMessage, other
components continue to be processed.
Skip to Render Response phase if one or more
FacesMessage is present
22
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.
- 23. Converter
Implementing the interface javax.faces.convert.Converter
public static class CustomConverter implements Converter {
public Object getAsObject(FacesContext context, UIComponent component, String value)
{}
public String getAsString(FacesContext context, UIComponent component, Object value)
{}
}
23
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.
- 24. Converter
Declare to the Runtime
faces-config.xml
– by id
<converter>
<converter-id>creditCardConverter</converter-id>
<converter-class>carstore.CreditCardConverter</converter-class>
</converter>
– by type
<converter>
<converter-for-class>java.util.Date</converter-for-class>
<converter-class>com.mycompany.MyThirdConverter</converter-class>
</converter>
24
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.
- 25. Converter
Declare to the Runtime
@FacesConverter annotation
– value attribute is the converter id
– forClass attribute is the class converted by this converter
Important subtlety
– Due to the nature of annotation scanning, a single usage of
@FacesConverter may only have one or the other of value and forClass.
25
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.
- 26. Associating a Converter with a UIComponent
Several ways
Implicit converter, based on the type of the property referenced by the
EL Expression
Explicit converter
– <f:converter>
converterId attribute
binding attribute
– converter attribute on a UIComponent
Subtlety with <h:selectManyListbox>
– Must use <f:converter> for all types not handled by package
javax.faces.convert converters
26
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.
- 27. Associating a Converter with a UIComponent
Several ways
Programmatically: call ValueHolder.setConverter( )
27
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.
- 28. Validators
Standard Validators in package javax.faces.validator
Throw ValidatorException to indicate validation
failure
Failure added as per-component
FacesMessage, other components continue to be
processed.
Skip to Render Response phase if one or more
FacesMessage is present
28
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.
- 29. Validators
Implementing the interface javax.faces.validator.Validator
public class CustomValidator1 implements Validator {
public void validate(FacesContext context, UIComponent component, Object value) throws
ValidatorException {
}
}
Why the checked exception?
– Validation is a business level concern, make it more explicit
29
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.
- 30. Validators
Tip
When programming custom Validators and Converters, program
defensively.
Check inbound arguments for null.
Avoid throwing non-expected exceptions
30
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.
- 31. Validators
Declaring a Validator to the runtime
faces-config.xml
<validator>
<validator-id>CreditCardValidator</validator-id>
<validator-class>com.foo.CreditCardValidator</validator-class>
</validator>
@FacesValidator annotation
– value attribute is the id
– isDefault is boolean
31
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.
- 32. Validators
Empty String Considerations
Context parameter
javax.faces.INTERPRET_EMPTY_STRING_SUBMITTED_VALUES_AS_NULL
– true: if the incoming value is the empty string, will automatically call
UIInput.setSubmittedValue(null)
– false or not set: Allow the empty string to pass through
32
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.
- 33. Validators
Default Validator
Added to all EditableValueHolder instances in every page
Declared in faces-config.xml
<application>
<default-validators>
<validator-id>MyValidator</validator-id>
</default-validators>
<application/>
Empty <default-validators/> causes the list to be cleared
Declared with @FacesValidator annotation isDefault attribute
33
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.
- 34. Validators
Bean Validator
The javax.faces.validate.BeanValidator validator is the default default
Validator
It is the gateway to JSR-303 Bean Validation
Validates the JavaBeans property referenced by the component
Validation expressed as “constraint” annotation on the property
Property vs whole bean validation
34
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.
- 35. Validators
Bean Validator Standard Constraints
@NotNull(groups = Order.class)
@Size(min = 1, message =
"{validator.notEmpty}", groups = Order.class)
@CreditCard(groups = Order.class)
public String getCreditCard() {
return creditCard;
}
35
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.
- 36. Bean Validator
Making your own constraints
1.
Annotate your annotation
@Documented
@Constraint(validatedBy = CreditCardConstraintValidator.class)
@Target({ElementType.METHOD, ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface CreditCard {
// message string should be {constraint.creditCard}
String message() default "{validator.creditCard}”;
//CreditCardVendor vendor default ANY;
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
36
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.
- 37. Bean Validator
Making your own constraints
2.
Implement your constraint
public class CreditCardConstraintValidator
implements ConstraintValidator<CreditCard, String> {
private Pattern basicSyntaxPattern;
public void initialize(CreditCard parameters) {
basicSyntaxPattern = Pattern.compile("^[0-9 -]*$");
}
public boolean isValid(String value, ConstraintValidatorContext ctxt) {
if (value == null || value.length() == 0) {return true;}
if (!basicSyntaxPattern.matcher(value).matches()) { return false;}
return luhnCheck(stripNonDigits(value));
}
}
37
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.
- 38. Bean Validator
Disabling Bean Validator
Context param
javax.faces.validator.DISABLE_BEAN_VALIDATOR
set to true
38
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.
- 39. Bean Validator
DEMOs
Basic Bean Validator
Version 1.1 Method
and Parameter
Validation
39
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.
- 40. Bean Validator
Groups
Groups
Validates all but this one
Validates these only
Exposed to JSF via <f:validateBean validationGroups=“”>
40
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.
- 41. Associating a Validator with a UIComponent
Several ways
Nest validator tag inside component
Programmatically, call
EditableValueHolder.addValidator( )
41
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.
- 43. How to Declare Navigation
Explicit Navigation
– Declared via XML rules in faces-
config.xml file
Implicit Navigation
– Relies on filename of pages
– No need for rules in faces-config.xml
43
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.
- 44. Explicit Navigation
Designed to be well suited to developer
tools, hence syntax is verbose
“action” is returned from all
ActionSource components
– Explicitly hard coded in the page
– Returned via a Value Expression
44
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.
- 45. Implicit Navigation
A reaction to all that verbosity
from-view-id is the current view
If there exists a page that is equivalent to the value of the current
action, the navigation is performed.
45
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.
- 46. How Navigation Is Performed
POST vs GET
JSF 1.0
– All navigation was POSTback based
form does HTTP POST
server does RequestDispatcher.forward()
sends back new page, from old URL
ABUSE OF HTTP!
JSF 2.0
– Adds POST REDIRECT GET
46
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.
- 47. Further Navigation Enhancements
JSF 2.2 Faces Flows
JSF 1.0
– All navigation was POSTback based
form does HTTP POST
server does RequestDispatcher.forward()
sends back new page, from old URL
ABUSE OF HTTP!
JSF 2.0
– Adds POST REDIRECT GET
47
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.
- 51. The preceding is intended to outline our general product direction. It is intended
for information purposes only, and may not be incorporated into any contract.
It is not a commitment to deliver any material, code, or functionality, and should
not be relied upon in making purchasing decisions. The
development, release, and timing of any features or functionality described for
Oracle’s products remains at the sole discretion of Oracle.
51
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.