SlideShare une entreprise Scribd logo
1  sur  42
Télécharger pour lire hors ligne
Presentation Layer

Sérgio Silva

October 2013
Fenix Architecture
Application Container (Tomcat, Jetty)

JSPs
renderers

Faces
Jersey
(REST API)
Domain
Model

Struts

Fenix Framework
(STM)

MYSQL
Today
Application Container (Tomcat, Jetty)

JSPs
renderers

Faces
Jersey
(REST API)
Domain
Model

Struts

Fenix Framework
(STM)

MYSQL
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/
Struts
Control Layer
Struts
Control Layer
Struts Dispatching
fenix.ist.utl.pt/publico/executionCourse.do?method=marks&executionCourseID=1610612925705
Struts Dispatching
Module
fenix.ist.utl.pt/publico/executionCourse.do?method=marks&executionCourseID=1610612925705

Semantic division in modules
● struts-publico.xml
● .do maps to Struts Servlet (JavaServlet API)
○ src/main/resources/web.xml
Struts Dispatching
Mapping
fenix.ist.utl.pt/publico/executionCourse.do?method=marks&executionCourseID=1610612925705

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">
Struts Dispatching
Mapping
fenix.ist.utl.pt/publico/executionCourse.do?method=marks&executionCourseID=1610612925705

Mapping between path and action
● Action Class ( ExecutionCourseDA.java)
●

each action is module aware

●

usually extends FenixDispatchAction (check outline on eclipse)
○

helper methods
■
■

redirect

■

getLoggedPerson

■

●

getFromRequest

getDomainObject(request,parameter)

method execute runs always
DEMO
Struts @ Fenix
Action
fenix.ist.utl.pt/publico/executionCourse.do?method=marks&executionCourseID=1610612925705

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
Wrapping Up
JSPs
Presentation Layer
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
Struts @ Fenix
Forwards
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
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
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 (Deprecated)
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)
● 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"/>
JSPs
● JavaServer Pages (JSP)
● create dynamically generated web pages
based on HTML
● HTML with behaviour
DEMO
publico/executionCourse/marks.jsp
JSPs
without renderers
● 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
● 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
● 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
Renderers
● integration with domain model and fenixframework
● 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
● 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-config.xml

● 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
● 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
● 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
JSPs
Renderers
Renderers
(reusable) Schemas
● 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
● 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
● 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
●

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
(inline) 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>
Renderers
(inline) Schemas
<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>
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"
JavaServer Faces
● JavaServer Faces
○ version 1.1

● component-based user interfaces for web
apps
● servlet mapping *.faces
● faces-config.xml
JavaServer Faces
https://fenix.ist.utl.pt/publico/degreeSite/viewCurricularCourse.faces?degreeID=2761663971474
JavaServer Faces
https://fenix.ist.utl.pt/publico/degreeSite/viewCurricularCourse.faces?degreeID=2761663971474

●

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</ anaged-bean-name>
m
<managed-bean-class>n.s.f.p.b.m.c.ManagerCurricularCourseManagementBackingBean</
managed-bean-class>
<managed-bean-scope>request</managed-bean-scope>
</managed-bean>

DEMO
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
Q&A?

Contenu connexe

Tendances

Spring MVC Annotations
Spring MVC AnnotationsSpring MVC Annotations
Spring MVC AnnotationsJordan Silva
 
Drupal8Day: Demystifying Drupal 8 Ajax Callback commands
Drupal8Day: Demystifying Drupal 8 Ajax Callback commandsDrupal8Day: Demystifying Drupal 8 Ajax Callback commands
Drupal8Day: Demystifying Drupal 8 Ajax Callback commandsMichael Miles
 
Reactive state management with Jetpack Components
Reactive state management with Jetpack ComponentsReactive state management with Jetpack Components
Reactive state management with Jetpack ComponentsGabor Varadi
 
Spring 3.x - Spring MVC
Spring 3.x - Spring MVCSpring 3.x - Spring MVC
Spring 3.x - Spring MVCGuy Nir
 
Hastening React SSR - Web Performance San Diego
Hastening React SSR - Web Performance San DiegoHastening React SSR - Web Performance San Diego
Hastening React SSR - Web Performance San DiegoMaxime Najim
 
Demystifying AJAX Callback Commands in Drupal 8
Demystifying AJAX Callback Commands in Drupal 8Demystifying AJAX Callback Commands in Drupal 8
Demystifying AJAX Callback Commands in Drupal 8Michael Miles
 
State management in android applications
State management in android applicationsState management in android applications
State management in android applicationsGabor Varadi
 
Heroku pop-behind-the-sense
Heroku pop-behind-the-senseHeroku pop-behind-the-sense
Heroku pop-behind-the-senseBen Lin
 
Simplified Android Development with Simple-Stack
Simplified Android Development with Simple-StackSimplified Android Development with Simple-Stack
Simplified Android Development with Simple-StackGabor Varadi
 
Architecting Single Activity Applications (With or Without Fragments)
Architecting Single Activity Applications (With or Without Fragments)Architecting Single Activity Applications (With or Without Fragments)
Architecting Single Activity Applications (With or Without Fragments)Gabor Varadi
 
[22]Efficient and Testable MVVM pattern
[22]Efficient and Testable MVVM pattern[22]Efficient and Testable MVVM pattern
[22]Efficient and Testable MVVM patternNAVER Engineering
 
"Angular.js Concepts in Depth" by Aleksandar Simović
"Angular.js Concepts in Depth" by Aleksandar Simović"Angular.js Concepts in Depth" by Aleksandar Simović
"Angular.js Concepts in Depth" by Aleksandar SimovićJS Belgrade
 
Demystifying Drupal AJAX Callback Commands
Demystifying Drupal AJAX Callback CommandsDemystifying Drupal AJAX Callback Commands
Demystifying Drupal AJAX Callback CommandsMichael Miles
 
Workshop 26: React Native - The Native Side
Workshop 26: React Native - The Native SideWorkshop 26: React Native - The Native Side
Workshop 26: React Native - The Native SideVisual Engineering
 
Java Spring MVC Framework with AngularJS by Google and HTML5
Java Spring MVC Framework with AngularJS by Google and HTML5Java Spring MVC Framework with AngularJS by Google and HTML5
Java Spring MVC Framework with AngularJS by Google and HTML5Tuna Tore
 

Tendances (17)

Paging Like A Pro
Paging Like A ProPaging Like A Pro
Paging Like A Pro
 
Spring MVC Annotations
Spring MVC AnnotationsSpring MVC Annotations
Spring MVC Annotations
 
Drupal8Day: Demystifying Drupal 8 Ajax Callback commands
Drupal8Day: Demystifying Drupal 8 Ajax Callback commandsDrupal8Day: Demystifying Drupal 8 Ajax Callback commands
Drupal8Day: Demystifying Drupal 8 Ajax Callback commands
 
Reactive state management with Jetpack Components
Reactive state management with Jetpack ComponentsReactive state management with Jetpack Components
Reactive state management with Jetpack Components
 
Spring 3.x - Spring MVC
Spring 3.x - Spring MVCSpring 3.x - Spring MVC
Spring 3.x - Spring MVC
 
Hastening React SSR - Web Performance San Diego
Hastening React SSR - Web Performance San DiegoHastening React SSR - Web Performance San Diego
Hastening React SSR - Web Performance San Diego
 
Demystifying AJAX Callback Commands in Drupal 8
Demystifying AJAX Callback Commands in Drupal 8Demystifying AJAX Callback Commands in Drupal 8
Demystifying AJAX Callback Commands in Drupal 8
 
State management in android applications
State management in android applicationsState management in android applications
State management in android applications
 
Backbone Basics with Examples
Backbone Basics with ExamplesBackbone Basics with Examples
Backbone Basics with Examples
 
Heroku pop-behind-the-sense
Heroku pop-behind-the-senseHeroku pop-behind-the-sense
Heroku pop-behind-the-sense
 
Simplified Android Development with Simple-Stack
Simplified Android Development with Simple-StackSimplified Android Development with Simple-Stack
Simplified Android Development with Simple-Stack
 
Architecting Single Activity Applications (With or Without Fragments)
Architecting Single Activity Applications (With or Without Fragments)Architecting Single Activity Applications (With or Without Fragments)
Architecting Single Activity Applications (With or Without Fragments)
 
[22]Efficient and Testable MVVM pattern
[22]Efficient and Testable MVVM pattern[22]Efficient and Testable MVVM pattern
[22]Efficient and Testable MVVM pattern
 
"Angular.js Concepts in Depth" by Aleksandar Simović
"Angular.js Concepts in Depth" by Aleksandar Simović"Angular.js Concepts in Depth" by Aleksandar Simović
"Angular.js Concepts in Depth" by Aleksandar Simović
 
Demystifying Drupal AJAX Callback Commands
Demystifying Drupal AJAX Callback CommandsDemystifying Drupal AJAX Callback Commands
Demystifying Drupal AJAX Callback Commands
 
Workshop 26: React Native - The Native Side
Workshop 26: React Native - The Native SideWorkshop 26: React Native - The Native Side
Workshop 26: React Native - The Native Side
 
Java Spring MVC Framework with AngularJS by Google and HTML5
Java Spring MVC Framework with AngularJS by Google and HTML5Java Spring MVC Framework with AngularJS by Google and HTML5
Java Spring MVC Framework with AngularJS by Google and HTML5
 

Similaire à Training: Day Four - Struts, Tiles, Renders and Faces

Rich Portlet Development in uPortal
Rich Portlet Development in uPortalRich Portlet Development in uPortal
Rich Portlet Development in uPortalJennifer Bourey
 
Building Web Apps with Express
Building Web Apps with ExpressBuilding Web Apps with Express
Building Web Apps with ExpressAaron Stannard
 
Bonnes pratiques de développement avec Node js
Bonnes pratiques de développement avec Node jsBonnes pratiques de développement avec Node js
Bonnes pratiques de développement avec Node jsFrancois Zaninotto
 
Backbone.js — Introduction to client-side JavaScript MVC
Backbone.js — Introduction to client-side JavaScript MVCBackbone.js — Introduction to client-side JavaScript MVC
Backbone.js — Introduction to client-side JavaScript MVCpootsbook
 
PUC SE Day 2019 - SpringBoot
PUC SE Day 2019 - SpringBootPUC SE Day 2019 - SpringBoot
PUC SE Day 2019 - SpringBootJosué Neis
 
比XML更好用的Java Annotation
比XML更好用的Java Annotation比XML更好用的Java Annotation
比XML更好用的Java Annotationjavatwo2011
 
Xitrum Web Framework Live Coding Demos / Xitrum Web Framework ライブコーディング
Xitrum Web Framework Live Coding Demos / Xitrum Web Framework ライブコーディングXitrum Web Framework Live Coding Demos / Xitrum Web Framework ライブコーディング
Xitrum Web Framework Live Coding Demos / Xitrum Web Framework ライブコーディングscalaconfjp
 
Xitrum @ Scala Matsuri Tokyo 2014
Xitrum @ Scala Matsuri Tokyo 2014Xitrum @ Scala Matsuri Tokyo 2014
Xitrum @ Scala Matsuri Tokyo 2014Ngoc Dao
 
Primefaces Nextgen Lju
Primefaces Nextgen LjuPrimefaces Nextgen Lju
Primefaces Nextgen LjuSkills Matter
 
Primefaces Nextgen Lju
Primefaces Nextgen LjuPrimefaces Nextgen Lju
Primefaces Nextgen LjuSkills Matter
 
Introduction to Struts
Introduction to StrutsIntroduction to Struts
Introduction to Strutselliando dias
 
Василевский Илья (Fun-box): "автоматизация браузера при помощи PhantomJS"
Василевский Илья (Fun-box): "автоматизация браузера при помощи PhantomJS"Василевский Илья (Fun-box): "автоматизация браузера при помощи PhantomJS"
Василевский Илья (Fun-box): "автоматизация браузера при помощи PhantomJS"Provectus
 
Writing HTML5 Web Apps using Backbone.js and GAE
Writing HTML5 Web Apps using Backbone.js and GAEWriting HTML5 Web Apps using Backbone.js and GAE
Writing HTML5 Web Apps using Backbone.js and GAERon Reiter
 
Stepbystepguideforbuidlingsimplestrutsapp 090702025438-phpapp02
Stepbystepguideforbuidlingsimplestrutsapp 090702025438-phpapp02Stepbystepguideforbuidlingsimplestrutsapp 090702025438-phpapp02
Stepbystepguideforbuidlingsimplestrutsapp 090702025438-phpapp02Rati Manandhar
 
We sport architecture_implementation
We sport architecture_implementationWe sport architecture_implementation
We sport architecture_implementationaurelianaur
 

Similaire à Training: Day Four - Struts, Tiles, Renders and Faces (20)

Rich Portlet Development in uPortal
Rich Portlet Development in uPortalRich Portlet Development in uPortal
Rich Portlet Development in uPortal
 
Unit 07: Design Patterns and Frameworks (3/3)
Unit 07: Design Patterns and Frameworks (3/3)Unit 07: Design Patterns and Frameworks (3/3)
Unit 07: Design Patterns and Frameworks (3/3)
 
Building Web Apps with Express
Building Web Apps with ExpressBuilding Web Apps with Express
Building Web Apps with Express
 
Bonnes pratiques de développement avec Node js
Bonnes pratiques de développement avec Node jsBonnes pratiques de développement avec Node js
Bonnes pratiques de développement avec Node js
 
Backbone.js — Introduction to client-side JavaScript MVC
Backbone.js — Introduction to client-side JavaScript MVCBackbone.js — Introduction to client-side JavaScript MVC
Backbone.js — Introduction to client-side JavaScript MVC
 
PUC SE Day 2019 - SpringBoot
PUC SE Day 2019 - SpringBootPUC SE Day 2019 - SpringBoot
PUC SE Day 2019 - SpringBoot
 
比XML更好用的Java Annotation
比XML更好用的Java Annotation比XML更好用的Java Annotation
比XML更好用的Java Annotation
 
How to React Native
How to React NativeHow to React Native
How to React Native
 
Xitrum Web Framework Live Coding Demos / Xitrum Web Framework ライブコーディング
Xitrum Web Framework Live Coding Demos / Xitrum Web Framework ライブコーディングXitrum Web Framework Live Coding Demos / Xitrum Web Framework ライブコーディング
Xitrum Web Framework Live Coding Demos / Xitrum Web Framework ライブコーディング
 
Xitrum @ Scala Matsuri Tokyo 2014
Xitrum @ Scala Matsuri Tokyo 2014Xitrum @ Scala Matsuri Tokyo 2014
Xitrum @ Scala Matsuri Tokyo 2014
 
Android best practices
Android best practicesAndroid best practices
Android best practices
 
Struts Intro
Struts IntroStruts Intro
Struts Intro
 
Primefaces Nextgen Lju
Primefaces Nextgen LjuPrimefaces Nextgen Lju
Primefaces Nextgen Lju
 
Primefaces Nextgen Lju
Primefaces Nextgen LjuPrimefaces Nextgen Lju
Primefaces Nextgen Lju
 
Introduction to Struts
Introduction to StrutsIntroduction to Struts
Introduction to Struts
 
Василевский Илья (Fun-box): "автоматизация браузера при помощи PhantomJS"
Василевский Илья (Fun-box): "автоматизация браузера при помощи PhantomJS"Василевский Илья (Fun-box): "автоматизация браузера при помощи PhantomJS"
Василевский Илья (Fun-box): "автоматизация браузера при помощи PhantomJS"
 
Writing HTML5 Web Apps using Backbone.js and GAE
Writing HTML5 Web Apps using Backbone.js and GAEWriting HTML5 Web Apps using Backbone.js and GAE
Writing HTML5 Web Apps using Backbone.js and GAE
 
Stepbystepguideforbuidlingsimplestrutsapp 090702025438-phpapp02
Stepbystepguideforbuidlingsimplestrutsapp 090702025438-phpapp02Stepbystepguideforbuidlingsimplestrutsapp 090702025438-phpapp02
Stepbystepguideforbuidlingsimplestrutsapp 090702025438-phpapp02
 
We sport architecture_implementation
We sport architecture_implementationWe sport architecture_implementation
We sport architecture_implementation
 
Spine.js
Spine.jsSpine.js
Spine.js
 

Dernier

Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUnderstanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUK Journal
 
How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonetsnaman860154
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processorsdebabhi2
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfsudhanshuwaghmare1
 
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxFactors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxKatpro Technologies
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking MenDelhi Call girls
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Scriptwesley chun
 
Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)wesley chun
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerThousandEyes
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationSafe Software
 
What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?Antenna Manufacturer Coco
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)Gabriella Davis
 
Advantages of Hiring UIUX Design Service Providers for Your Business
Advantages of Hiring UIUX Design Service Providers for Your BusinessAdvantages of Hiring UIUX Design Service Providers for Your Business
Advantages of Hiring UIUX Design Service Providers for Your BusinessPixlogix Infotech
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...apidays
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsMaria Levchenko
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking MenDelhi Call girls
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc
 
Real Time Object Detection Using Open CV
Real Time Object Detection Using Open CVReal Time Object Detection Using Open CV
Real Time Object Detection Using Open CVKhem
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024Rafal Los
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreternaman860154
 

Dernier (20)

Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUnderstanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
 
How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonets
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processors
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdf
 
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxFactors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Script
 
Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
 
What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)
 
Advantages of Hiring UIUX Design Service Providers for Your Business
Advantages of Hiring UIUX Design Service Providers for Your BusinessAdvantages of Hiring UIUX Design Service Providers for Your Business
Advantages of Hiring UIUX Design Service Providers for Your Business
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed texts
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
 
Real Time Object Detection Using Open CV
Real Time Object Detection Using Open CVReal Time Object Detection Using Open CV
Real Time Object Detection Using Open CV
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreter
 

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

  • 2. Fenix Architecture Application Container (Tomcat, Jetty) JSPs renderers Faces Jersey (REST API) Domain Model Struts Fenix Framework (STM) MYSQL
  • 3. Today Application Container (Tomcat, Jetty) JSPs renderers Faces Jersey (REST API) Domain Model Struts Fenix Framework (STM) MYSQL
  • 4. 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/
  • 8. Struts Dispatching Module fenix.ist.utl.pt/publico/executionCourse.do?method=marks&executionCourseID=1610612925705 Semantic division in modules ● struts-publico.xml ● .do maps to Struts Servlet (JavaServlet API) ○ src/main/resources/web.xml
  • 9. Struts Dispatching Mapping fenix.ist.utl.pt/publico/executionCourse.do?method=marks&executionCourseID=1610612925705 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">
  • 10. Struts Dispatching Mapping fenix.ist.utl.pt/publico/executionCourse.do?method=marks&executionCourseID=1610612925705 Mapping between path and action ● Action Class ( ExecutionCourseDA.java) ● each action is module aware ● usually extends FenixDispatchAction (check outline on eclipse) ○ helper methods ■ ■ redirect ■ getLoggedPerson ■ ● getFromRequest getDomainObject(request,parameter) method execute runs always DEMO
  • 11. Struts @ Fenix Action fenix.ist.utl.pt/publico/executionCourse.do?method=marks&executionCourseID=1610612925705 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
  • 14. 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
  • 15. Struts @ Fenix Forwards 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" ); }
  • 16. Struts @ Fenix Forwards 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(..) ?
  • 17. Struts @ Fenix Forwards 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
  • 18. Struts @ Fenix Forwards (Deprecated) 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
  • 19. Struts @ Fenix Forwards (Deprecated) ● 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"/>
  • 20. JSPs ● JavaServer Pages (JSP) ● create dynamically generated web pages based on HTML ● HTML with behaviour DEMO publico/executionCourse/marks.jsp
  • 21. JSPs without renderers ● 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" ); }
  • 22. JSPs without renderers ● 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
  • 23. JSPs without renderers ● 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/
  • 24. JSPs Renderers ● integration with domain model and fenixframework ● our taglib <fr:*> ○ fr:view - display domain objects ○ fr:create - create domain objects ○ fr:edit - edit domain objects ● renderers-config.xml ○ All renderers definitions
  • 25. JSPs Renderers ● 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
  • 26. JSPs renderers-config.xml ● 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>
  • 27. JSPs Renderers ● 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>
  • 28. JSPs Renderers ● 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>
  • 31. Renderers (reusable) Schemas ● 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>
  • 32. Renderers (reusable) Schemas ● 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>
  • 33. Renderers (reusable) Schemas ● 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
  • 34. Renderers (reusable) Schemas ● 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
  • 35. Renderers (inline) 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>
  • 36. Renderers (inline) Schemas <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>
  • 37. 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"
  • 38. JavaServer Faces ● JavaServer Faces ○ version 1.1 ● component-based user interfaces for web apps ● servlet mapping *.faces ● faces-config.xml
  • 40. JavaServer Faces https://fenix.ist.utl.pt/publico/degreeSite/viewCurricularCourse.faces?degreeID=2761663971474 ● 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</ anaged-bean-name> m <managed-bean-class>n.s.f.p.b.m.c.ManagerCurricularCourseManagementBackingBean</ managed-bean-class> <managed-bean-scope>request</managed-bean-scope> </managed-bean> DEMO
  • 41. 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
  • 42. Q&A?