best practices for jsf, gameduell 2013
DESCRIPTION
Ed was asked to create a high level presentation regarding JSF best practices to present to a company that makes heavy use of JSF 2.0.TRANSCRIPT
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.1
JSF Best PracticesEdward Burns@edburns http://slideshare.net/edburns/Consulting Member of Staff, Oracle
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.3
Program Agenda
Review of the JSF Lifecycle
Conversion and Validation
JSF Navigation Review
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.
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.5
Lifecycle Review
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.6
Review: The Lifecycle Orchestrates MVCThe 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!
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.7
Review: The Lifecycle Orchestrates MVCThe Baseball and Apple Pie of Web apps
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.8
Review: The Lifecycle Orchestrates MVCThe 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 theUIComponent hierarchy and take theappropriate action.
• Inversion of control in the extreme• Analogy with Maven: work with the framework, not against it.
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.9
Review: The Lifecycle Orchestrates MVCAdditional details added
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.10
Interacting with the Lifecycle
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
Phase Listeners and System Events
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.11
Interacting with the Lifecycle
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
Phase Listeners
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.12
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() + ")");
}
}
Implementing the Interface javax.faces.event.PhaseListener
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.13
PhaseListener
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
Declare to the Runtime
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.14
PhaseListener
FacesContext.renderResponse()– Skip to Render Response Phase
FacesContext.responseComplete()– Do no further lifecycle processing on this request.
How to impact the execution of the lifecycle
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.15
Interacting with the Lifecycle
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()
System Events
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.16
Inte
ract
ing
wit
h
the
Lif
ecyc
leS
yste
m E
ven
ts
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.17
Interacting with the Lifecycle
1. Implement the listener interface
2. 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>
System Events
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.18
Conversion and Validation
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.19
Conversion and Validation
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
Type Safety for the UI
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.20
Conversion and Validation
Behavior Based Interfaces– ValueHolder
Anything that displays a value
– EditableValueHolder When that value is editable by the end user.
Type Safety for the UI
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.21
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.22
ConverterStandard 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
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.23
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) {}
}
Implementing the interface javax.faces.convert.Converter
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.24
Converter
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>
Declare to the Runtime
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.25
Converter
@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.
Declare to the Runtime
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.26
Associating a Converter with a UIComponent
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
Several ways
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.27
Associating a Converter with a UIComponent
Programmatically: call ValueHolder.setConverter( )
Several ways
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.28
Validators
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
Standard Validators in package javax.faces.validator
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.29
Validators
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
Implementing the interface javax.faces.validator.Validator
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.30
ValidatorsTip
When programming custom Validators and Converters, program defensively.
Check inbound arguments for null. Avoid throwing non-expected exceptions
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.31
Validators
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
Declaring a Validator to the runtime
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.32
Validators
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
Empty String Considerations
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.33
Validators
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
Default Validator
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.34
Validators
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
Bean Validator
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.35
ValidatorsBean 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;
}
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.36
Bean Validator
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 {};}
Making your own constraints
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.37
Bean Validator
2. Implement your constraintpublic class CreditCardConstraintValidatorimplements 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));}}
Making your own constraints
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.38
Bean Validator
Context paramjavax.faces.validator.DISABLE_BEAN_VALIDATOR set to true
Disabling Bean Validator
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.39
Bean Validator
Basic Bean Validator Version 1.1 Method
and Parameter Validation
DEMOs
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.40
Bean Validator
Groups
Validates all but this one
Validates these only
Groups
Exposed to JSF via <f:validateBean validationGroups=“”>
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.41
Associating a Validator with a UIComponent
Nest validator tag inside component Programmatically, call EditableValueHolder.addValidator( )
Several ways
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.42
JSF Navigation Review
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
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
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.45
Implicit Navigation
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.
A reaction to all that verbosity
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.46
How Navigation Is Performed
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
POST vs GET
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.47
Further Navigation Enhancements
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
JSF 2.2 Faces Flows
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.48
What’s in a Flow? Flow Nodes
Further Navigation Enhancements JSF 2.2 Faces Flows
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.49
PDF 7.5.1
Further Navigation Enhancements JSF 2.2 Faces Flows
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.50
Questions?
Ed Burns@edburns
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.
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.52