Top Banner
For Struts Developers
69

Struts2

May 06, 2015

Download

Technology

Scott Stanlick

This is a presentation I gave recently at the Apache conference
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: Struts2

For Struts Developers

Page 2: Struts2

Me• Scott Stanlick

– Drummer– Techie– Instructor– Connoisseur of cereal malt beverages

2

Page 3: Struts2

Agenda• Hello Struts 2• Action/Interceptor/Result• Configuration• OGNL/Value Stack• Tag Libraries• Business Validation• Plug-ins• Wrap up

3

Page 4: Struts2

Hello Struts 2

The History

4

Page 5: Struts2

What is Struts 2?

• Not Struts 1.x!

• EE5 Web Framework

• Originally OpenSymphony WebWork

• WebWork + Struts + Apache Incubator– Struts 2 was hatched in ‘07

5

Page 6: Struts2

Built Specifically For…• Developer Productivity

– Simple HTTP-free code– Easy Spring integration– Reusable UI templates– Plug-in architecture– Crazy cool type conversions– Rich validation– Easy to test– And so much more!

6

Page 7: Struts2

Configuration Styles

• Packaged actions (namespace)

• Package inheritance

• Wildcard mappings

• Generic actions

• Annotations

• Ruby-On-Rails Rest-style mappings– Convention over configuration

7

Page 8: Struts2

Plug-in Architecture

• Similar to Firefox and Eclipse• Add features by dropping in a jar• Several bundled plug-ins

– Tiles– JFreeChart– JasperReports– REST-Style URI mappings

• Plug-in registry growing steadily

8

Page 9: Struts2

The Core Components

• Actions

• Interceptors

• Results

9

Page 10: Struts2

Differences from Struts Classic

• No form beans• Actions are no longer singletons• HTTP-free• Intelligent defaults• Easy to extend with

– Interceptors– Results– Plug-ins

10

Page 11: Struts2

Action/Interceptor/Result

The Request Pipeline

11

Page 12: Struts2

12

ActionContext(ThreadLocal)

Page 13: Struts2

MVC2

• Where C=Cool!• Request

– FilterDispatcher• Dispatcher

– StrutsActionProxy» ActionInvocation [ThreadLocal]

13

Page 14: Struts2

Action• Packaged according to like kind

– Sort of like Java packages• ThreadLocal (safe)• Typically extend ActionSupport• Contain your domain model

– Can be model driven• May contain multiple methods• Not tangled up with Servlet/API• Easy to test!

14

Page 15: Struts2

Action Mapping

15

<package name="hr" namespace="/hr" extends="starter"><action

name=“uri“ class=“class“ method=“method"> <result>destination</result>

</action><package>

Page 16: Struts2

Wildcard Action Mapping

16

<package name="hr" namespace="/hr" extends="starter"><action

name=“employeeAction_*" class=“HREmployeeManager" method=“{1} ">

<result>/employee/{1}.jsp</result></action>

<package>

Page 17: Struts2

HREmployeeManager Actionclass HREmployeeManager {

private Employee model;

private EmployeeService service;

public List getList(){…}

}

17

Page 18: Struts2

Interceptor• Intercepts request

– Think AOP

• Called before/after your action

• Useful for cross-cutting concerns

• Built-ins cover 98+% of all use cases

• Configured at package or action level

• Is central to the framework itself– Eat your own dog food!

18

Page 19: Struts2

Interceptor Stack• An interceptor has a specific role

– Parameter interception– Validation– Workflow

• Named “stacks” provide pluggable lists pre-assembled for goal specific cases– defaultStack– fileUploadStack– modelDrivenStack– paramsPrepareParamsStack

19

Page 20: Struts2

Interceptor Configuration

• Easy to configure wrong!

• config-browser plug-in provides a glimpse into the runtime– More about this later

20

Page 21: Struts2

Timer Interceptor

• Stopwatch feature for action execution– “starts” before your action – “stops” afterward

• Writes performance timings to log

• Order of interceptors is interesting– See next slide

21

Page 22: Struts2

Timer Interceptor (cont.)

<interceptors>

<interceptor-stack name="stackWithTimer">

<interceptor-ref name="timer"/>

<interceptor-ref name="defaultStack"/>

</interceptor-stack>

</interceptors>

records action's execution with interceptors

22

Page 23: Struts2

Timer Interceptor (cont.)

<interceptors>

<interceptor-stack name="stackWithTimer">

<interceptor-ref name="defaultStack"/>

<interceptor-ref name="timer"/>

</interceptor-stack>

</interceptors>

records only the action's execution time

23

Page 24: Struts2

Default Stack <interceptor-stack name="defaultStack"> <interceptor-ref name="exception"/> <interceptor-ref name="alias"/> <interceptor-ref name="servletConfig"/> <interceptor-ref name="prepare"/> <interceptor-ref name="i18n"/> <interceptor-ref name="chain"/> <interceptor-ref name="debugging"/> <interceptor-ref name="profiling"/> <interceptor-ref name="scopedModelDriven"/> <interceptor-ref name="modelDriven"/> <interceptor-ref name="fileUpload"/> <interceptor-ref name="checkbox"/> <interceptor-ref name="staticParams"/> <interceptor-ref name="params"> <param name="excludeParams">dojo\..*</param> </interceptor-ref> <interceptor-ref name="conversionError"/> <interceptor-ref name="validation"> <param name="excludeMethods">input,back,cancel,browse</param> </interceptor-ref> <interceptor-ref name="workflow"> <param name="excludeMethods">input,back,cancel,browse</param> </interceptor-ref> </interceptor-stack>

24

Page 25: Struts2

Result• What should be returned to requester?

• Many provided out of the box

• It’s easy to write your own– Graphics– JSON– PDF

• It’s another configurable object

25

Page 26: Struts2

Result Types<result-types> <result-type name="chain" class=“…"/> <result-type name="dispatcher" class=“…" default="true"/> <result-type name="freemarker" class=“…"/> <result-type name="httpheader" class=“…"/> <result-type name="redirect" class=“…"/> <result-type name="redirectAction" class=“…"/> <result-type name="stream" class=“…"/> <result-type name="velocity" class=“…"/> <result-type name="xslt" class=“…"/> <result-type name="plainText" class=“…" />

<result-type name="plaintext" class=“…" /></result-types>

26

Page 27: Struts2

Result Example<action …>

<result name="success" type="dispatcher">/employee/list.jsp

</result></action>

• name and type are optional– name defaults to success– type default can be set by package

27

Page 28: Struts2

Connecting the Wildcard Dots

28

<action name=“employeeAction_*“ class=“HREmployeeManager“ method=“{1} ">

<result>/employee/{1}.jsp</result>

</action>

• www.foo.com/employeeAction_list

• list()

• list.jsp

Page 29: Struts2

Configuration

Declaring the Web Site Capabilities

29

Page 30: Struts2

struts.xml• Core configuration file for framework • Can contain multiple packages<struts>

<package name=“base" extends="struts-default"> <action...>

</package> <include file=“hr.xml"/> <include file=“logon.xml"/> <include file=“preferences.xml"/>

</struts>

30

Page 31: Struts2

struts-default.xml• Most of your packages will extend this

– Directly/Indirectly

• Contains about everything you need

• Packages form inheritance hierarchies

• The key sections are– package– result-types– interceptors/stacks

31

Page 32: Struts2

Package Inheritance

<package name=“hr" extends=“base“ namespace="/hr">

<action name=“…”/>

</package>

32

• struts-default• base

• hr

Page 33: Struts2

Intelligent Configuration

• Declarative architecture

• Configurable defaults

• Extendable– Framework extension points– Sub-packages

• Shipped in the struts2-core-2.m.n.jar– struts-default.xml

33

Page 34: Struts2

Sample Declaration

<package name=“hr“ extends=“base“ namespace="/hr">

<action name="list“

method=“preload” class=“HREmployeeManager”>

<result>/pages/hr/employee/list.jsp</result>

</action>

</package>

34

Page 35: Struts2

Constant Configuration• Modify framework and plug-in behavior • Can be declared at multiple levels• Searched in the following order

– struts-default.xml– struts-plugin.xml– struts.xml– struts.properties– web.xml

• Subsequent files override previous ones

35

Page 36: Struts2

struts.properties

struts.devMode=truestruts.objectFactory=springstruts.configuration.xml.reload=truestruts.freemarker.templatesCache=truestruts.ui.theme=simplestruts.enable.DynamicMethodInvocation=falsestruts.custom.i18n.resources=resources.Messages…

36

Page 37: Struts2

OGNL/ValueStack

Dynamic Data/Object Graph

37

Page 38: Struts2

Dynamic Data

38

• Where is dynamic data stored?– Data to generate pages– User input from pages

• Form beans are gone

• Dependence on Servlet/API is bad

• Welcome to the ValueStack

Page 39: Struts2

ValueStack• Leverages the OGNL framework

– Object Graph Navigation Language• Extends OGNL to support searching stack

– Top down to locate object/property• Where Interceptors put/get object data• Thread Safe• ActionContext.getContext().getValueStack()

39

Page 40: Struts2

Struts 2 and OGNL

40

OG

NL

OG

NL

Con

text

(A

ctio

nC

on

text

)Value Stack (OGNL root) |___Action |___other objects…

#parameters#request#session#application#attr (searches p, r, s, then a)

Page 41: Struts2

ValueStack

• Request “Object Stack”

• OGNL expressions search it top down

• Can specify object level

• Common operations

– peek

– pop

– push

41

Page 42: Struts2

Type Conversions

• OGNL uses reflection to convert types

• JavaBeans convention provides “hint”

• Custom converters can be added– Scope

• Bean/Model• Action• Application

42

Page 43: Struts2

Tag Libraries

The UI

43

Page 44: Struts2

Struts 2 Tags

• Tags are divided into 2 sets– UI

• Form/Non-Form• Ajax

– Leverages dojo

– Generic• Control

– if, else, iterator

• Data– bean, text, url

44

Page 45: Struts2

Struts 2 Tags

• Decoupled from underlying view technology– JSP– Velocity– FreeMarker

• Markup via Freemarker templates

45

Page 46: Struts2

S2 Tag Syntax

• The value attribute is not a string– It’s an OBJECT

• What you pass is evaluated as an expression!

• <s:sometag … value=“foo”/>– Looks for getFoo()

• <s:sometag … value=“{‘foo’}”/>– String literal is passed

46

Page 47: Struts2

Tag Templates

• The markup generated is your choice– HTML– XML– JSON– WML– …

47

Page 48: Struts2

UI Tag Templates

• Template technology is FreeMarker

• CSS classes can be used to control L&F

• You may tweak provided templates

• Tight affinity with ValueStack

48

Page 49: Struts2

Base select Component• View technology agnostic• org.apache.struts2.components.Select• Generates markup via TemplateEngine• S2 provides FreeMarkerTemplateEngine

– Unites ValueStack & FreeMarker

49

Page 50: Struts2

<s:select/> JSP Custom Tag

• org.apache.struts2.views.jsp.ui.SelectTag• Renders a select widget

50

Page 51: Struts2

<@s.select/> FreeMarker Tag• org.apache.struts2.views.freemarker.tags.SelectModel

• Renders a select widget

51

Page 52: Struts2

StrutsRequestWrapper

• JSTL does not know OGNL

• This class wraps the Struts request

• Delegates to the Value Stack

• ${customer.address.city}– Resolves to stack.find under the covers

52

Page 53: Struts2

S2 and JSTL• OGNL values are exposed to JSP/JSTL• Expression syntax is a little different

– JSTL: ${a.b.c}– OGNL: %{a.b.c}

• Beware of JSP 2.1 Unified EL JSR 245– EL has been expanded to interpret #{}– Clashes with OGNL usage for Maps

• #{ "foo" : "foo value", "bar" : "bar value" }

53

Page 54: Struts2

Themes

• S2 UI tags grouped into themes– simple - minimal with no "bells and whistles" – xhtml - uses common HTML practices – css_xhtml - xhtml theme re-implemented

using strictly CSS for layout – Ajax - based on the xhtml theme that

provides advanced AJAX features

• Specified globally or at the tag level

54

Page 55: Struts2

Simple Theme

55

<H2>Employee Save</H2><s:form> <s:textfield key="employee.name“ required="true"/> <s:textfield key="employee.department“ required="true"/></s:form>

Page 56: Struts2

XHTML Theme

56

<H2>Employee Save</H2><s:form> <s:textfield key="employee.name“ required="true"/> <s:textfield key="employee.department“ required="true"/></s:form>

Page 57: Struts2

Business Validation

Rules and Regulations

57

Page 58: Struts2

Validation Styles

• Annotations

• XML

• Java

58

Page 59: Struts2

Simple Field Example• Form

– <s:textfield key="age"/> • Action

– private int age; get/set• Validator <ActionClassName>-validation.xml

<field name="age"> <field-validator type="int">

<param name="min">13</param>

<param name="max">19</param>

<message>Only people ages 13 to 19 allowed</message>

</field-validator>

</field>

59

Page 60: Struts2

Validator Types• conversion• date• email• short – int – long - double• regex <takes a regular expression>• required• requiredstring• stringlength• url• visitor - conditionalvisitor• fieldexpression <resolves an OGNL expression>• expression <resolves an OGNL expression>

60

Page 61: Struts2

Another Field Example<field name=“password">

<field-validator type="expression">

<param name="expression">

password.equals(password2)

</param>

<message>

Password 2 must equal ${password}

</message>

</field-validator>

</field>

61

Page 62: Struts2

Non-Field Validation

62

<validators> <validator type="expression"> <param name="expression“> ( (a==b) && (b==c) )</param> <message>all three fields must be the same></message> </validator>

</validators>

Page 63: Struts2

Plug-ins

Extensions Simplified

63

Page 64: Struts2

Benefits of plug-ins

• Strategic points in the framework where you can – Provide you own implementations– Add new features

• Add functionality without modifying code– Open-Closed Principle

64

Page 65: Struts2

Configuration Browser

• Exposes the runtime configuration

• Accessed via a browser– http://.../config-browser/index.action

65

Page 66: Struts2

OGNL Viewer• Provides debugging screens to provide

insight into the data behind the page• Accessed via a browser

– http://..?debug={flag}

• Flag values– xml, console, command, browser

• Make sure – DebuggingInterceptor is included– struts.devMode=true

66

Page 67: Struts2

Wrap up

Odds & Ends

67

Page 68: Struts2

My Web Site

68

• www.struts2inaction.com

• The cobbler’s children have no shoes

• Too many paying gigs to lace up my own site!

• Vacation time coming• It will rock!

Page 69: Struts2

Resources

• Manning

• Nabble

• Google

• Also watch for – Struts 2 in Practice (Wes Wannemacher)

69