JavaServer Faces Anti-Patterns and Pitfalls

Loading...

Flash Player 9 (or above) is needed to view presentations.
We have detected that you do not have it on your computer. To install it, go here.

0 comments

Post a comment

    Post a comment
    Embed Video
    Edit your comment Cancel

    1 Favorite

    JavaServer Faces Anti-Patterns and Pitfalls - Presentation Transcript

    1. JavaServer Faces Anti-Patterns Dennis Byrne - ThoughtWorks [email_address] http://notdennisbyrne.blogspot.com
    2. Validating Setter
        • <managed-bean>
        • <managed-bean-name>iterationBean</managed-bean-name>
        • <managed-bean-class> com.thoughtworks.Iteration
        • </managed-bean-class>
        • <managed-bean-scope> request </managed-bean-scope>
        • <managed-property>
        • <property-name> start </property-name>
        • <value> #{sprintBean.currentStart} </value>
        • </managed-property>
        • <managed-property>
        • <property-name> end </property-name>
        • <value> #{sprintBean.currentEnd} </value>
        • </managed-property>
        • <managed-property>
        • <property-name>last</property-name>
        • <value>hack</value>
        • </managed-property>
        • </managed-bean>
    3. Validating Setter
      • public class Iteration {
      • private Calendar start, end; // injected
      • // sans setters and getters for start, end
      • public void setLast(String last) {
      • if(start == null)
      • throw new NullPointerException(&quot;start&quot;);
      • if(end == null)
      • throw new NullPointerException(&quot;end&quot;);
      • if(start.after(end))
      • throw new IllegalStateException(&quot;start > end&quot;);
      • }
      • }
    4. Validating Setter Solutions
      • <application>
      • <variable-resolver>
      • org.springframework.web.jsf.DelegatingVariableResolver
      • </variable-resolver>
      • </application>
      • <application> <el-resolver>
      • org.apache.myfaces.el.unified.resolver.GuiceResolver
      • </el-resolver>
      • </application>
      • public class Iteration {
      • private Calendar start, end; // injected
      • @PostConstruct
      • public void initialize() {
      • // domain validation logic here ...
      • }
      • }
    5. The Map Trick
      • #{requestScopedMap.key} // calls get(‘key’)
      • #{requestScopedMap[‘key’]}
      • public class MapTrick implements java.util.Map {
      • public Object get(Object key) {
      • return new BusinessLogic().doSomething(key);
      • }
      • public void clear() { }
      • public boolean containsKey(Object arg) { return false; }
      • public boolean isEmpty() { return false; }
      • public Set keySet() { return null; }
      • public Object put(Object key, Object value) { return null; }
      • public void putAll(Map arg) { }
      • public Object remove(Object arg) { return null; }
      • public int size() { return 0; }
      • }
    6. déjà vu PhaseListener
        • <context-param>
        • <description>
        • comma separated list of JSF conf files
        • </description>
        • <param-name> javax.faces.CONFIG_FILES </param-name>
        • <param-value>
        • /WEB-INF/faces-config.xml
        • </param-value>
        • </context-param>
        • <lifecycle>
        • <phase-listener>
        • com.thoughtworks.PhaseListenerImpl
        • </phase-listener>
        • </lifecycle>
    7. XML Hell
        • <navigation-rule> <from-view-id>/home.xhtml</from-view-id>
        • <navigation-case>
        • <from-outcome>contact_us</from-outcome>
        • <to-view-id>/contact.xhtml</to-view-id>
        • </navigation-case>
        • </navigation-rule>
        • <navigation-rule> <from-view-id>/site_map.xhtml</from-view-id>
        • <navigation-case>
        • <from-outcome>contact_us</from-outcome>
        • <to-view-id>/contact.xhtml</to-view-id>
        • </navigation-case>
        • </navigation-rule>
        • <navigation-rule><from-view-id> * </from-view-id>
        • <navigation-case> <!-- global nav rule -->
        • <from-outcome>contact_us</from-outcome>
        • <to-view-id>/contact.xhtml</to-view-id>
        • </navigation-case>
        • </navigation-rule>
    8. Thread Safety
          • javax.faces.event.PhaseListener
          • javax.faces.render.Renderer
          • Managed Beans
          • javax.faces.convert.Converter
          • javax.faces.validator.Validator
          • javax.faces.FacesContext
          • JSF Tags
    9. Thread Safety
      • <h:inputText value=&quot;#{managedBean.value}&quot; converter=&quot;#{threadUnsafe}&quot; />
      • <managed-bean>
      • <managed-bean-name>threadUnsafe</managed-bean-name>
      • <managed-bean-class>
      • org.apache.myfaces.book.ThreadUnsafeConverter
      • </managed-bean-class>
      • <managed-bean-scope> session </managed-bean-scope>
      • </managed-bean>
      • <h:inputText value=&quot;#{managedBean.value}&quot; >
      • <f:converter converterId=&quot;threadUnsafe&quot; > <!-- Always Safe -->
      • </h:inputText>
      • <converter>
      • <converter-id>threadUnsafe</converter-id>
      • <converter-class>org.apache.myfaces.book.ThreadUnsafeConverter
      • </converter-class>
      • </converter>
    10. Facelets Migration
      • public class WidgetTag extends UIComponentELTag{
      • private String title, styleClass = &quot;default_class&quot;;
      • protected void setProperties(UIComponent component) {
      • super.setProperties(component);
      • Widget span = (Widget) component;
      • span.setStyleClass(styleClass);
      • span.setTitle(title == null ? &quot;no title&quot; : title);
      • FacesContext ctx = FacesContext.getCurrentInstance();
      • Map session = ctx.getExternalContext().getSessionMap();
      • span.setStyle((String) session.get(&quot;style&quot;));
      • }
      • }
    11. Law of Demeter
      • A “Train Wreck” - sensitive to changes in domain model
      • employee. getDepartment().getManager()
      • .getOffice().getAddress().getZip();
      • An EL “Train Wreck” - sensitive to changes in domain model
      • #{employee. department.manager.office.address.zip }
      • Encapsulated, insensitive to changes in domain model
      • #{employee.officeManagersZipCode}
    12. Vendor Lock-in
      • import org.apache.myfaces.component.html.ext.HtmlInputHidden;
      • import org.apache.myfaces.component.html.ext.HtmlInputText;
      • import org.apache.myfaces.component.html.ext.HtmlOutputText;
      • public class ImplementationDependentManagedBean {
        • private HtmlInputText input ;
        • private HtmlInputHidden hidden ;
        • private HtmlOutputText output ;
        • /* getters and setters omitted */
        • public boolean recordTotal(ActionEvent event) {
        • long total = ((Long)input.getValue()).longValue();
        • total += ((Long)hidden.getValue()).longValue();
        • total += ((Long)output.getValue()).longValue();
        • return new JmsUtil().broadcastTotal(total);
        • }
      • }
    13. Vendor Lock-in Solution
      • import javax.faces.component.ValueHolder;
      • public class RefactoredManagedBean {
      • private ValueHolder input ;
      • private ValueHolder hidden ;
      • private ValueHolder output ;
      • /* getters & setters ommitted */
      • public boolean recordTotal(ActionEvent event) {
      • long total = 0;
      • ValueHolder[] vh = new ValueHolder[] {input, hidden, output};
      • for(ValueHolder valued : vh)
      • total += ((Long)valued.getValue()).longValue();
      • return new JmsUtil().broadcastTotal(total);
      • }
      • }
    14. Portlet ClassCastException
      • FacesContext ctx = FacesContext.getCurrentInstance();
      • ExternalContext ectx = ctx.getExternalContext();
      • ServletRequest request = ( ServletRequest )ectx .getRequest();
      • String id = request.getParameter(&quot;id&quot;);
      • FacesContext ctx = FacesContext.getCurrentInstance();
      • ExternalContext ectx = ctx.getExternalContext();
      • String id = ectx.getRequestParameterMap().get(&quot;id&quot;);
    15. OpenTransactionInViewFilter
        • public void doFilter(ServletRequest request,
      • ServletResponse response, FilterChain chain){
        • try {
        • ObjectRelationalUtility.startTransaction();
        • chain.doFilter(request, response);
        • ObjectRelationalUtility.commitTransaction();
        • } catch (Throwable throwable) {
        • try {
        • ObjectRelationalUtility.rollbackTransaction();
        • } catch (Throwable _throwable) {
        • /* sans error handling */
        • }
        • }
        • }
    16. N + 1
        • <!-- One trip to the database for the master record ... -->
        • <h:dataTable value=&quot;#{projectBean.projects}&quot; var=&quot;project&quot;>
        • <h:column>
        • <h:commandLink action=&quot;#{projectBean.viewProject}&quot;
        • value=&quot;view project&quot;/>
        • </h:column>
        • <h:column>
        • <!-- ... and + N trips for each child record -->
        • <f:facet name=&quot;header&quot;>Project Manager</f:facet>
        • #{project .manager.name }
        • </h:column>
        • <h:column>
        • <f:facet name=&quot;header&quot;>Project Name</f:facet>
        • #{project.name}
        • </h:column>
        • </h:dataTable>
    17. N + 1- N
      • public class OpenTransactionInApplicationPhaseListener
      • implements PhaseListener {
      • public void beforePhase(PhaseEvent event) {
      • try {
      • ObjectRelationalUtility.startTransaction();
      • } catch (Throwable throwable) { /* sans error handling */ }
      • }
      • public void afterPhase(PhaseEvent event) {
      • try {
      • ObjectRelationalUtility.commitTransaction();
      • } catch (Throwable throwable) {
      • ObjectRelationalUtility.rollbackTransaction();
      • }
      • }
      • public PhaseId getPhaseId(){return PhaseId.INVOKE_APPLICATION ;}
      • }
    18. Thanks
      • Dennis Byrne - ThoughtWorks
      • [email_address]
      • http://notdennisbyrne.blogspot.com

    + Dennis ByrneDennis Byrne, 2 years ago

    custom

    806 views, 1 favs, 1 embeds more stats

    Here are my slides from ApacheCon 2007

    More info about this document

    © All Rights Reserved

    Go to text version

    • Total Views 806
      • 805 on SlideShare
      • 1 from embeds
    • Comments 0
    • Favorites 1
    • Downloads 28
    Most viewed embeds
    • 1 views on http://localhost

    more

    All embeds
    • 1 views on http://localhost

    less

    Flagged as inappropriate Flag as inappropriate
    Flag as inappropriate

    Select your reason for flagging this presentation as inappropriate. If needed, use the feedback form to let us know more details.

    Cancel
    File a copyright complaint
    Having problems? Go to our helpdesk?

    Categories