Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Training: Day Four - Struts, Tiles, Renders and...

Sponsored · Ship Features Fearlessly Turn features on and off without deploys. Used by thousands of Ruby developers. →

Training: Day Four - Struts, Tiles, Renders and Faces.

This is the fourth in our four part training sessions introducing FenixEdu development for new collaborators.

In this last session, we introduce our two presentation frameworks present in fenix, Struts and Faces, the presentation plugin Tiles and our rendering library Renders

Avatar for Artur Ventura

Artur Ventura

October 15, 2013

More Decks by Artur Ventura

Other Decks in Technology

Transcript

  1. Fenix Architecture MYSQL Application Container (Tomcat, Jetty) Fenix Framework (STM)

    Domain Model JSPs renderers Struts Faces Jersey (REST API)
  2. Today MYSQL Application Container (Tomcat, Jetty) Fenix Framework (STM) Domain

    Model JSPs renderers Struts Faces Jersey (REST API)
  3. Struts Control Layer • open-source web application framework • uses

    and extends the Java Servlet API • model–view–controller (MVC) architecture • version 1.2.7 • http://struts.apache.org/release/1.2.x/
  4. Struts Dispatching Module Semantic division in modules • struts-publico.xml •

    .do maps to Struts Servlet (JavaServlet API) ◦ src/main/resources/web.xml fenix.ist.utl.pt/publico/executionCourse.do?method=marks&executionCourseID=1610612925705
  5. Struts Dispatching Mapping Mapping between path and action • The

    path is a string ◦ “/executionCourse” • Where is the mapping ? ◦ Mapping with annotations (what you should use) @Mapping(module ="publico" path="/executionCourse" ) ◦ struts-publico.xml (read-only, don’t create things here) <action type="n.s.f.p.A.p.ExecutionCourseDA" parameter="method" path="/executionCourse"> fenix.ist.utl.pt/publico/executionCourse.do?method=marks&executionCourseID=1610612925705
  6. Struts Dispatching Mapping Mapping between path and action • Action

    Class ( ExecutionCourseDA.java) • each action is module aware • usually extends FenixDispatchAction (check outline on eclipse) ◦ helper methods ▪ getFromRequest ▪ redirect ▪ getLoggedPerson ▪ getDomainObject(request,parameter) • method execute runs always DEMO fenix.ist.utl.pt/publico/executionCourse.do?method=marks&executionCourseID=1610612925705
  7. ExecutionCourseDA.java public ActionForward marks(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse

    response) { final String executionCourseOID = request.getParameter("executionCourseID"); final ExecutionCourse executionCourse = FenixFramework.getDomainObject(executionCourseOID); Map<> attendsMap = getAttendsMap(executionCourse); request.setAttribute("executionCourse", executionCourse); request.setAttribute("attendsMap", attendsMap); request.setAttribute("dont-cache-pages-in-search-engines", Boolean.TRUE); return mapping.findForward("execution-course-marks"); } • Parameters ◦ get values on query string • Attributes ◦ get or set state on request Struts @ Fenix Action fenix.ist.utl.pt/publico/executionCourse.do?method=marks&executionCourseID=1610612925705
  8. Struts Presentation Layer • Tiles ◦ templating system ◦ create

    a common look and feel for a web application ◦ create reusable view components ◦ bridge to JSPs ◦ module aware • tiles-<module>-definitions.xml ◦ template definitions • tiles-<module>-pages-definitions.xml ◦ fill in the template
  9. ExecutionCourseDA.java public ActionForward marks(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse

    response) { final String executionCourseOID = request.getParameter("executionCourseID" ); final ExecutionCourse executionCourse = FenixFramework. getDomainObject(executionCourseOID); Map<> attendsMap = getAttendsMap(executionCourse); request .setAttribute("executionCourse" , executionCourse); request .setAttribute("attendsMap", attendsMap); request .setAttribute("dont-cache-pages-in-search-engines" , Boolean.TRUE); return mapping.findForward("execution-course-marks" ); } Struts @ Fenix Forwards
  10. ExecutionCourseDA.java public ActionForward marks(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse

    response) { final String executionCourseOID = request.getParameter("executionCourseID "); final ExecutionCourse executionCourse = FenixFramework. getDomainObject(executionCourseOID); Map<> attendsMap = getAttendsMap(executionCourse); request .setAttribute("executionCourse" , executionCourse); request .setAttribute("attendsMap", attendsMap); request .setAttribute("dont-cache-pages-in-search-engines" , Boolean.TRUE); return mapping.findForward("execution-course-marks"); } • What is mapping.findForward(..) ? Struts @ Fenix Forwards
  11. ExecutionCourseDA.java public ActionForward marks(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse

    response) { final String executionCourseOID = request.getParameter("executionCourseID "); final ExecutionCourse executionCourse = FenixFramework. getDomainObject(executionCourseOID); Map<> attendsMap = getAttendsMap(executionCourse); request .setAttribute("executionCourse" , executionCourse); request .setAttribute("attendsMap", attendsMap); request .setAttribute("dont-cache-pages-in-search-engines" , Boolean.TRUE); return mapping.findForward("execution-course-marks"); } • Forwards annotation (what you should use) @Forwards({ @Forward(name = "execution-course-marks", path = "/publico/executionCourse/marks.jsp") }) public class ExecutionCourseDA extends FenixDispatchAction { … } • name - forward name • path - logic name for tiles Struts @ Fenix Forwards
  12. ExecutionCourseDA.java public ActionForward marks(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse

    response) { final String executionCourseOID = request.getParameter("executionCourseID "); final ExecutionCourse executionCourse = FenixFramework. getDomainObject(executionCourseOID); Map<> attendsMap = getAttendsMap(executionCourse); request .setAttribute("executionCourse" , executionCourse); request .setAttribute("attendsMap", attendsMap); request .setAttribute("dont-cache-pages-in-search-engines" , Boolean.TRUE); return mapping.findForward("execution-course-marks"); } • struts-publico.xml <action type="n.s.f.p.A.p.ExecutionCourseDA" parameter="method" path="/executionCourse" > <forward path= "execution-course-marks" name="execution-course-marks"></forward> ………………………………………………… </action> • name - forward name • path - logic name for tiles Struts @ Fenix Forwards (Deprecated)
  13. • tiles-public-definitions.xml <definition name= "execution-course-marks" extends="definition.public.executionCourse"> <put name="body" value="/publico/executionCourse/marks.jsp" />

    </definition> • tiles-public-pages-definitions.xml <definition name= "definition.public.executionCourse" page="/layout/istLayout.jsp"> <put name="title" value="/commons/functionalities/courseTitle.jsp" /> <put name="hideLanguage" value="true"/> <put name="symbols_row" value="/publico/degreeSite/symbolsRow.jsp" /> <put name="profile_navigation" value="/publico/degreeSite/profileNavigation.jsp" /> <put name="main_navigation" value="/publico/executionCourse/mainNavigation.jsp" /> <put name="body_header" value="/publico/executionCourse/executionCourseHeader.jsp" /> <put name="body" value="/commons/blank.jsp" /> <put name="footer" value="/publico/degreeSite/footer.jsp" /> <put name="rss" value="/messaging/announcements/rssHeader.jsp" /> <put name="keywords" value="/messaging/announcements/keywordsHeader.jsp" /> </definition> • istLayout.jsp <tiles:insert attribute= "body" ignore="true"/> <tiles:insert attribute= "footer" ignore="true"/> Struts @ Fenix Forwards (Deprecated)
  14. JSPs • JavaServer Pages (JSP) • create dynamically generated web

    pages based on HTML • HTML with behaviour DEMO publico/executionCourse/marks.jsp
  15. • publico/executionCourse/marks.jsp <logic:iterate id="evaluation" name="executionCourse " property="orderedAssociatedEvaluations "> • ExecutionCourseDA.java

    public ActionForward marks(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) { final String executionCourseOID = request.getParameter("executionCourseID" ); final ExecutionCourse executionCourse = FenixFramework. getDomainObject(executionCourseOID); Map<Attends, Map<Evaluation, Mark>> attendsMap = getAttendsMap(executionCourse); request .setAttribute("executionCourse" , executionCourse); request .setAttribute("attendsMap", attendsMap); request .setAttribute("dont-cache-pages-in-search-engines" , Boolean.TRUE); return mapping.findForward("execution-course-marks" ); } JSPs without renderers
  16. • publico/executionCourse/marks.jsp <logic:iterate id="evaluation" name="executionCourse" property="orderedAssociatedEvaluations"> • ExecutionCourseDA.java public ActionForward

    marks(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) { final String executionCourseOID = request.getParameter("executionCourseID" ); final ExecutionCourse executionCourse = FenixFramework. getDomainObject(executionCourseOID); Map<Attends, Map<Evaluation, Mark>> attendsMap = getAttendsMap(executionCourse); request .setAttribute("executionCourse", executionCourse); request .setAttribute("attendsMap", attendsMap); request .setAttribute("dont-cache-pages-in-search-engines" , Boolean.TRUE); return mapping.findForward("execution-course-marks" ); } • name - get from request attribute or parameter with that name • property - get property from object ◦ executionCourse .getOrderedAssociatedEvaluations () • uses Java Bean conventions • id - defines bean in jsp scope JSPs without renderers
  17. • simple bean example <h3><bean:write name= "executionCourse" property="name"></h3> • executionCourse.getName()

    • Tag libs ◦ <bean:*> ◦ <logic:*> ◦ <html:*> ◦ http://struts.apache.org/release/1.2.x/userGuide/ JSPs without renderers
  18. • integration with domain model and fenix- framework • our

    taglib <fr:*> ◦ fr:view - display domain objects ◦ fr:create - create domain objects ◦ fr:edit - edit domain objects • renderers-config.xml ◦ All renderers definitions JSPs Renderers
  19. • What is a renderer ? ◦ java class used

    to produce HTML ◦ Properties ▪ layout • logical name for renderer definition ▪ mode • input • output ▪ class • rendered type ◦ String ◦ ExecutionCourse ◦ int ▪ properties • render specific properties JSPs Renderers
  20. • output renderer <renderer type= "java.util.Collection" layout="contact-list" class="n.s.f.p.r.ContactListRenderer" > <property

    name= "bundle" value="APPLICATION_RESOURCES" /> <property name= "defaultLabel" value="label.partyContacts.defaultContact" /> </renderer> • input renderer <renderer mode= "input" type="j.u.Collection" layout="option-select" class="p.i.fr.InputCheckBoxListRenderer" > <property name= "eachClasses" value="dinline" /> </renderer> JSPs renderers-config.xml
  21. • manageApplications.jsp <fr:view name="appsOwned" schema="oauthapps.view.apps" > <fr:layout name="tabular"> <fr:property name="classes"

    value="tstyle4 thcenter thcenter" /> <fr:property name="columnClasses" value="tdcenter, tdcenter, ..." /> </fr:layout> </fr:view> • renderers-config.xml <renderer type="java.util.Collection" layout="tabular" class="p.i.f.r.CollectionRenderer" > <property name="groupLinks" value="true"/> <property name="linkGroupSeparator" value=", "/> </renderer> JSPs Renderers
  22. • manageApplications.jsp <fr:view name="appsOwned" schema="oauthapps.view.apps" > <fr:layout name="tabular"> <fr:property name="classes"

    value="tstyle4 thcenter thcenter" /> <fr:property name="columnClasses" value="tdcenter, tdcenter, ..." /> </fr:layout> </fr:view> • renderers-config.xml <renderer type="java.util.Collection" layout="tabular" class="p.i.f.r.CollectionRenderer" > <property name="groupLinks" value="true"/> <property name="linkGroupSeparator" value=", "/> </renderer> JSPs Renderers
  23. • manageApplications.jsp <fr:view name="appsOwned" schema="oauthapps.view.apps" > <fr:layout name="tabular"> <fr:property name="classes"

    value="tstyle4 thcenter thcenter" /> <fr:property name="columnClasses" value="tdcenter, tdcenter, ..." /> </fr:layout> </fr:view> Renderers (reusable) Schemas
  24. • manageApplications.jsp <fr:view name="appsOwned" schema="oauthapps.view.apps"> <fr:layout name="tabular"> <fr:property name="classes" value="tstyle4

    thcenter thcenter" /> <fr:property name="columnClasses" value="tdcenter, tdcenter, ..." /> </fr:layout> </fr:view> Renderers (reusable) Schemas
  25. • Schemas <fr:view name="appsOwned" schema="oauthapps.view.apps"> <fr:layout name="tabular"> <fr:property name="classes" value="tstyle4

    thcenter thcenter" /> <fr:property name="columnClasses" value="tdcenter, tdcenter, ..." /> </fr:layout> </fr:view> • specify how object’s slots are rendered • schemas-config.xml • *-schemas.xml ◦ logical separation Renderers (reusable) Schemas
  26. • personnelSection-schemas.xml <schema name="oauthapps.view.apps" type="net.sourceforge.fenixedu.domain.ExternalApplication" bundle="APPLICATION_RESOURCES" > <slot name="name" key="oauthapps.label.app.name"

    /> <slot name="description" layout="longText" key="oauthapps.label.app.description" /> <slot name="scopes" layout="flowLayout"> <property name= "eachLayout" value="values"></property> <property name= "eachSchema" value="oauthapps.view.scope.name" ></property> <property name= "htmlSeparator" value=", "></property> </slot> <slot name="siteUrl" key="oauthapps.label.app.site.url" /> </schema> • name ◦ unique identifier • type ◦ schema target type • slot ◦ object slot to render Renderers (reusable) Schemas
  27. <fr:view name="appsOwned" schema="oauthapps.view.apps" > <fr:layout name="tabular"> <fr:property name="classes" value="tstyle4 thcenter

    thcenter" /> <fr:property name="columnClasses" value="tdcenter, tdcenter, ..." /> </fr:layout> </fr:view> Renderers (inline) Schemas
  28. <fr:view name="appsOwned"> <fr:schema type="net.sourceforge.fenixedu.domain.ExternalApplication" bundle="APPLICATION_RESOURCES" > <fr:slot name="name" key="oauthapps.label.app.name" />

    <fr:slot name="description" layout="longText" key="oauthapps.label.app.description" /> <fr:slot name="scopes" layout="flowLayout"> <fr:property name="eachLayout" value="values"></property> <fr:property name="eachSchema" value="oauthapps.view.scope.name" ></property> <fr:property name="htmlSeparator" value=", "></property> </fr:slot> <fr:slot name="siteUrl" key="oauthapps.label.app.site.url" /> </fr:schema> <fr:layout name="tabular"> <fr:property name="classes" value="tstyle4 thcenter thcenter" /> <fr:property name="columnClasses" value="tdcenter, tdcenter, ..." /> </fr:layout> </fr:view> Renderers (inline) Schemas
  29. Resource Bundles <fr:view name="appsOwned"> <fr:schema type="net.sourceforge.fenixedu.domain.ExternalApplication" bundle="APPLICATION_RESOURCES"> <fr:slot name="name" key="oauthapps.label.app.name"

    /> <fr:slot name="description" layout="longText" key="oauthapps.label.app.description" /> <fr:slot name="scopes" layout="flowLayout"> <fr:property name="eachLayout" value="values"></property> <fr:property name="eachSchema" value="oauthapps.view.scope.name" ></property> <fr:property name="htmlSeparator" value=", "></property> </fr:slot> <fr:slot name="siteUrl" key="oauthapps.label.app.site.url" /> </fr:schema> <fr:layout name="tabular"> <fr:property name="classes" value="tstyle4 thcenter thcenter" /> <fr:property name="columnClasses" value="tdcenter, tdcenter, ..." /> </fr:layout> </fr:view> • src/main/resources/resources/ApplicationResources_pt.properties ◦ oauthapps.label.app.name ="Nome Aplicação" • src/main/resources/resources/ApplicationResources_en.properties ◦ oauthapps.label.app.name ="Application Name"
  30. JavaServer Faces • JavaServer Faces ◦ version 1.1 • component-based

    user interfaces for web apps • servlet mapping *.faces • faces-config.xml
  31. • publico/degreeSite/viewCurricularCourse.jsp <h:outputFormat value="<h1>#{CurricularCourseManagement.degreePresentationName}</h1>" escape="false"/> • Backing Bean ◦ name

    - CurricularCourseManagement • faces-config.xml <managed-bean> <description>ManagerCurricularCourseManagementBackingBean</ description> <managed-bean-name>ManagerCurricularCourseManagement</ managed-bean-name> <managed-bean-class>n.s.f.p.b.m.c.ManagerCurricularCourseManagementBackingBean</ managed-bean-class> <managed-bean-scope>request</managed-bean-scope> </managed-bean> DEMO https://fenix.ist.utl.pt/publico/degreeSite/viewCurricularCourse.faces?degreeID=2761663971474 JavaServer Faces
  32. Golden Rules • don’t create stuff in struts-*.xml ◦ use

    annotations ▪ @Mapping ▪ @Forwards • @Forward • renderers-config.xml ◦ read-only (unless you are going to create a new renderer) • read renderers docs ◦ Administrador > Frameworks > Renderers > Exemplos Renderers • install resource bundle editor ◦ https://fenix-ashes.ist.utl.pt/fenixWiki/I18NConventions