end"); }"> end"); }">
Download presentation
Presentation is loading. Please wait.
Published byMilton Eaton Modified over 9 years ago
1
JavaServer Faces Anti-Patterns Dennis Byrne - ThoughtWorks dennisbyrne@apache.org
2
Validating Setter iterationBean com.thoughtworks.Iteration request start #{sprintBean.currentStart} end #{sprintBean.currentEnd} last hack
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("start"); if(end == null) throw new NullPointerException("end"); if(start.after(end)) throw new IllegalStateException("start > end"); }
4
Validating Setter Solutions org.springframework.web.jsf.DelegatingVariableResolver org.apache.myfaces.el.unified.resolver.GuiceResolver 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 comma separated list of JSF conf files javax.faces.CONFIG_FILES /WEB-INF/faces-config.xml com.thoughtworks.PhaseListenerImpl
7
XML Hell /home.xhtml contact_us /contact.xhtml /site_map.xhtml contact_us /contact.xhtml * contact_us /contact.xhtml
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 threadUnsafe org.apache.myfaces.book.ThreadUnsafeConverter session threadUnsafe org.apache.myfaces.book.ThreadUnsafeConverter
10
Facelets Migration public class WidgetTag extends UIComponentELTag{ private String title, styleClass = "default_class"; protected void setProperties(UIComponent component) { super.setProperties(component); Widget span = (Widget) component; span.setStyleClass(styleClass); span.setTitle(title == null ? "no title" : title); FacesContext ctx = FacesContext.getCurrentInstance(); Map session = ctx.getExternalContext().getSessionMap(); span.setStyle((String) session.get("style")); }
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("id"); FacesContext ctx = FacesContext.getCurrentInstance(); ExternalContext ectx = ctx.getExternalContext(); String id = ectx.getRequestParameterMap().get("id");
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 <h:commandLink action="#{projectBean.viewProject}" value="view project"/> Project Manager #{project.manager.name} Project Name #{project.name}
17
N + 1- N public class OpenTransactionInApplicationPhaseListener implements PhaseListener { public void afterPhase(PhaseEvent event) { try { ObjectRelationalUtility.startTransaction(); } catch (Throwable throwable) { /* sans error handling */ } } public void beforePhase(PhaseEvent event) { try { ObjectRelationalUtility.commitTransaction(); } catch (Throwable throwable) { ObjectRelationalUtility.rollbackTransaction(); } public PhaseId getPhaseId(){return PhaseId.INVOKE_APPLICATION;} }
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.