getting started with struts2

Upload: minh-tien

Post on 04-Jun-2018

230 views

Category:

Documents


0 download

TRANSCRIPT

  • 8/13/2019 Getting Started With Struts2

    1/37

  • 8/13/2019 Getting Started With Struts2

    2/37

    WEB-INF/classes/example/Login-!alidation.xmlWEB-INF/classes/example/Login.classWEB-INF/classes/example/pac"age.propertiesWEB-INF/classes/example/pac"age#es.propertiesWEB-INF/classes/example.xml

    WEB-INF/classes/LI$ENE.txtWEB-INF/classes/N%&I$E.txtWEB-INF/classes/struts.xmlWEB-INF/li'WEB-INF/li'/commons-logging-(.(.jarWEB-INF/li'/)reemar"er-*.+.,.jarWEB-INF/li'/ognl-*..((.jarWEB-INF/li'/struts*-core-*...jarWEB-INF/li'/xor"-*..(.jarWEB-INF/srcWEB-INF/src/ja!a

    WEB-INF/src/ja!a/exampleWEB-INF/src/ja!a/example/'uild.'atWEB-INF/src/ja!a/example/Exampleupport.ja!aWEB-INF/src/ja!a/example/HelloWorld.ja!aWEB-INF/src/ja!a/example/Login-!alidation.xmlWEB-INF/src/ja!a/example/Login.ja!aWEB-INF/src/ja!a/example/pac"age.propertiesWEB-INF/src/ja!a/example/pac"age#es.propertiesWEB-INF/src/ja!a/example.xmlWEB-INF/src/ja!a/LI$ENE.txtWEB-INF/src/ja!a/N%&I$E.txt

    WEB-INF/src/ja!a/struts.xmlWEB-INF/e'.xml

    To ma+e a Struts2-based web application, the first step is

    configuring the Struts2 ser$let filter" %re$ious $ersions of Strutswere in$o+ed as a Ser$let that would pic+ the appropriate action

    based on the configuration" The ilter7ispatcher filter will be

    co$ered in another entry, but for now, it is important to note

    that the url-pattern is mapped to !8" Ser$let filters areconfigured in the application*s web"6ml file" .ere are the

    contents of the struts2-blan+ web"6ml -web.xml ->

    01xml !ersion34(.4 encoding345&F-,4160e'-app id34We'7pp#84 !ersion34*.94 xmlns34http://ja!a.sun.com/xml/ns/j*ee4 xmlns:xsi34http://.+.org/*(/;MLchema-instance4 xsi:schemaLocation34http://ja!a.sun.com/xml/ns/j*eehttp://ja!a.sun.com/xml/ns/j*ee/e'app#*#9.xsd46

    0displa

  • 8/13/2019 Getting Started With Struts2

    3/37

  • 8/13/2019 Getting Started With Struts2

    4/37

    default"6ml and will be located in the struts2-core-2"6"jar file"

    This configuration file although editable, is best left untouched"

    1ften & will refer to it to find out what interceptor stac+ will bee6ecuted by default, or to see which interceptor stac+s can be

    chosen, we will del$e a little further into interceptors andinterceptor stac+s later" After the struts-default"6ml is read and

    parsed, the web application will loo+ for a *struts"6ml* file inW'9-&3!classes"

    The e6ample struts"6ml file included with struts2-blan+ -struts.xml ->

    01xml !ersion34(.4 encoding345&F-,4 160?=%$&@AE struts A5BLI$ 4-//7pache o)tare Foundation//=&=truts $on)iguration *.//EN4

    4http://struts.apache.org/dtds/struts-*..dtd460struts6 0constant name34struts.ena'le.=ed and lends to good design,

    managing a large project is often problematic which leads

    architects to want to brea+ projects into multiple web

    applications" Although this can be done, indi$idual webapplications can not easily communicate with other web

    applications" 9rea+ing the web application up within Struts2 is

    easy and allows components to communicate easily and e$en

    hide information if necessary" 1ne recent project & wor+ed oncontained *shopping cart,* )registration,* and )chec+ out* modules

    that were easily separated in the codebase, but was capable of

    using a single A%& for business object interaction and

    persistence to the database"

  • 8/13/2019 Getting Started With Struts2

    5/37

  • 8/13/2019 Getting Started With Struts2

    6/37

    type"B The result*s name matches the String returned from the

    method e6ecuted in the action" The default name is success"B &f

    you are configuring the successB result for an action, you cans+ip the )nameD* attribute since successB is the default" The

    result*s typeB indicates how the application ser$er shouldgenerate the response" 9y default, the result is dispatched, so

    the )typeD* attribute is only needed when a result needs to begenerated by redirecting (such as if you are trying to

    implement the redirect-after-post pattern to eliminate browser

    9ac+B button problems#" When you combine these defaults with

    the Wildcard feature, you can easily and 5uic+ly configure abasic action such as is done here E

    0action name34>4 class34example.Exampleupport46 0result6/example/(C.jsp0/result6

    0/action6

    This is the )catch-all* action in the e6ampleB pac+age" 9y

    specifying a 8 as the action name, but using a bac+reference in

    the result, when a re5uest comes in that does not match anyother configured actions, the response should be dispatched to a

    S% matching the re5uest if such a S% e6ists" or instance,

    following the e6ample pre$iously, if a re5uest comes in to -

    http!!yourhost!struts2-blan+!e6ample!oo"action , the

    filesystem will be searched for a file called !e6ample!oo"jsp andthe result of e6ecuting !e6ample!oo"jsp will be dispatched as

    the result"

    1ne 5uestion that de$elopers as+ when first adopting Struts is

    whether or not it is necessary to ha$e all re5uests processed bya Struts action" The answer to this 5uestion is most definitely

    yes" This seems li+e e6tra wor+, but there are a few benefits"

    1ne benefit is that for Struts2 tags to wor+ appropriately, the

    S% must ha$e the Struts2 filter in$o+ed" There are a few usefulStruts2 tags that are helpful to adopt whether the page

    performs a typical RC7 operation or not" 1ne such tag is the

    )FsurlG* tag" FsurlG helps create CR0s that can be placed in

    lin+s without hardcoding assumptions li+e the name of the web-

    app into your S% code" An e6ample of using FsurlG -

  • 8/13/2019 Getting Started With Struts2

    7/37

    0s:url id34add*cart4 action347ddIn!oice&o$art4namespace34/customer/ajax460s:param name34in!oiceId460s:propert

    hre)34Dadd*cartC4 targets34shop$art=i!4executecripts34true4 6

    This particular snippet generates a lin+ which in$o+es an AA4

    re5uest to mo$e an item into the user*s shopping cart" Although

    the page was not a typical Struts2 $iew or result, by in$o+ing

    the S% $ia a wildcard-mapped action, & was able to ta+ead$antage of 130 and Struts2 tags to simplify what wouldotherwise be a comple6 combination of .T/0 and a$aScript"

    Wildcard mappings allow de$elopers to easily le$erage the

    Struts2 framewor+ for their C& code with minimal configuration

    and a$a code"

    The ne6t set of files to note in struts2-blan+ are

    pac+age"properties and pac+ageHes"properties" These files

    pro$ide an easy route to e6ternali>e the Strings in your C& and

    Struts2 can automatically present the proper translation to theweb application*s $isitors" pac+age"properties is the default

    resource bundleB for the struts2-blan+ web application, but if

    the web application is configured to do so, the locale will be

    pushed into the conte6t so that when resources are retrie$ed

    from the bundle, Struts2 will find the resource in theappropriate bundle for the browser*s locale and present the

    appropriate translation" So, internationali>ing a web application

    is as simple as e6ternali>ing your Strings into resource bundles

    and adding appropriate translations as necessary"

    The rest of the files in struts2-blan+ are code e6amples" The

    concepts behind the code e6amples in struts2-blan+ will each be

    co$ered in subse5uent entries" To start building a Struts2-based

    web application a de$eloper can import the struts2-blan+ WAR

    file or create the following directory structure -

    WEB-INF/li'/commons-logging-(.(.jarWEB-INF/li'/)reemar"er-*.+.,.jar

  • 8/13/2019 Getting Started With Struts2

    8/37

    WEB-INF/li'/ognl-*..((.jarWEB-INF/li'/struts*-core-*...jarWEB-INF/li'/xor"-*..(.jarWEB-INF/classes/struts.xmlWEB-INF/classes/e" &n

    case you ha$e not figured it out yet, Struts2 is a comple6framewor+" 1n the Strut2 mailing list, & constantly here people

    as+ing, Where do & startJB /y hope is that this series will gi$e

    people an answer to that 5uestion" 9ut, getting started is

    tougher than it sounds"

    9efore we get to the coding, let*s tal+ about the Struts2architecture" At this point, if you are unfamiliar with /odel 2

    and /K, then chec+ out this post" Struts2 handles re5uests in

    a way that is different than other framewor+s" Although the

    re5uest processing in Struts2 may seem proprietary, it is alsoone of Struts2*s biggest ad$antages" The first and most

    important feature of Struts2 is that it is designed to incorporate

    %lain 1l* a$a 1bjects (%11s# into it*s processing" This seems

    aw+ward to e6perienced a$a!S% de$elopers because they areused to ha$ing access to the objects defined in the S% and

    http://www.wantii.com/wordpress/?p=10http://www.wantii.com/wordpress/?p=8http://www.wantii.com/wordpress/?p=10http://www.wantii.com/wordpress/?p=8
  • 8/13/2019 Getting Started With Struts2

    9/37

  • 8/13/2019 Getting Started With Struts2

    10/37

    script#" The action should be in charge only with ta+ing the

    parameters sent from the user and passing them off to your

    business objects"

    This all sounds fine and dandy, but why would you go throughthe e6tra wor+ of creating so many objectsJ This separation will

    create an application that is easier to maintain" When we

    (finally# start to loo+ at some code, you will see just how well

    suited actions are at pro$iding this middle layer"B Actions wor+closely with the KiewsB (S%, freemar+er templates, $elocity

    templates, etc"# that are displayed to the web browser" The

    actions can be configured to $alidate the data passed to them as

    well" 1nce the action has completed it*s wor+, it will return a$alue that the Struts2 filter will read and based on that return

    $alue, a $iew will be pic+ed to be displayed" This concept isfamiliar to Struts: de$elopers, but as you will see later, the

    code and configuration is much simpler in Struts2 than it is inStruts:"

    At this point, the last step in the re5uest processing is the

    presentation of the Kiew"B To +eep things simple, let*s assume

    for a bit that our $iews are going to be S%s" Although there are

    many different technologies a$ailable to present $iews, most of

    the time you will use a S%" The $iews are similar to normalS%s, but there are a few added features" 1ne big feature is that

    the action being re5uested is placed onto the Kalue Stac+"B

    This allows you to use Struts2 tags to access data from theaction $ery easily" Another feature is the a$ailability of the

    Struts2 tags" There are tags for conditional processing, looping,

    AA4 and form $alidation" As you will see when we are coding

    actions and $iews, these tags are the perfect blend offunctionality and $ersatility"

    So, to sum up the Struts2 architecture, the Struts2 filter callsthe interceptor stac+, then hands the re5uest to an action which

    will process the parameters and pic+ a $iew to present" &n the

    ne6t part of the series, we will compare Struts2 code with rawS%!Ser$let code"

    Getting Started with Struts2 (Part 3)

    http://www.wantii.com/wordpress/?p=12http://www.wantii.com/wordpress/?p=12
  • 8/13/2019 Getting Started With Struts2

    11/37

    So & ha$e tal+ed and tal+ed in the pre$ious entries without

    showing any code e6amples" inally, it is time to start loo+ing at

    code" & apologi>e for waiting this long, but in my defense, theStruts 2"6 framewor+ is comple6 and without thorough

    co$erage, & would not be doing it justice"

    Example #1 - Hit Counter

    0et*s get our feet wet by comparing framewor+ code with

    standard S%!Ser$let code" &t was a popular practice in the early

    days of the web to display what often loo+ed li+e an odometer

    to tell the user how many other people had $iewed the pagethat was currently loaded" A good .it ounter re5uires many

    considerations, including most importantly storage and

    concurrency" or this e6ample, the .it ounter will e6ist in the

    ser$er memory only" The goal of this .it ounter is that it befunctional, but not necessarily production worthy"

    &n the S% and Ser$let platform there are many options on how

    to approach this project" To ma6imi>e reusability, & will create a

    custom tag that displays and updates the count for the page

    that is calling the tag" 'ach time the tag is used to display thecount, the count will be incremented" i$en the reusable nature

    of a custom tag, it is a re5uirement that this tag can be used by

    more than one page on the site, so the count $ariable should be

    an object that will hold an indi$idual count for each page thatcalls the tag" or this project, there are also potential

    concurrency issues" 1n real world projects, the biggest

    concurrency issues are usually data consistency and possible

    deadloc+s" &n this case, & can sol$e these issues by ma+ing sure

    to only use thread-safe objects to store the counts and alsoretrie$e then manipulate in a thread safe manner"

    To get more specific, & will create a custom tag that instantiates

    a static ja$a"util".ashtable in a static initiali>er bloc+" &f you are

    unfamiliar with custom tags, go right now and do a google

    searchfor custom tagB and ta+e a minute to learn how to

    create and use custom tags" When the tag is called, it will

    retrie$e the current count for the page that is calling the tag,

    then the count will be incremented" The retrie$al and increment

    will happen in a synchroni>ed method to maintain integrity" Thecount will then be written to the page"

    http://www.google.com/search?q=custom+taghttp://www.google.com/search?q=custom+taghttp://www.google.com/search?q=custom+taghttp://www.google.com/search?q=custom+tag
  • 8/13/2019 Getting Started With Struts2

    12/37

    HitCounter.java ->

    pac"age com.antii.examples.tagsimport ja!a.io.I%Exceptionimport ja!a.util.Hashta'le

    import ja!ax.ser!let.http.Httper!letReuestimport ja!ax.ser!let.jsp.JspExceptionimport ja!ax.ser!let.jsp.JspWriterimport ja!ax.ser!let.jsp.tagext.&agupport

    pu'lic class Hit$ounter extends &agupport pri!ate static )inal Hashta'le counts

    static counts 3 ne Hashta'leG C

    pri!ate static s

  • 8/13/2019 Getting Started With Struts2

    13/37

    go#" To ma+e this tag usable, you will ha$e to ha$e a T07 file"

    .ere is a sample T07 -

    wantiitags.tld ->

    01xml !ersion34(.4 encoding34I%-,,P8-(4 160?=%$&@AE tagli' A5BLI$ 4-//un Micros

  • 8/13/2019 Getting Started With Struts2

    14/37

    9efore & del$e into the details of this e6ample, & would li+e to

    co$er the Struts2 e6ample" Since & am going to sol$e this

    problem with Struts2, & could try to retro-fit the code into theStruts2 en$ironment" Cnfortunately, retro-fitting a pre$ious

    solution will only create e6tra wor+" or a simple project such asthis, it is best to re-thin+ the solution from the ground up"

    Applying the Model 2approach, & am going to start by creating

    a business object" When creating business objects, there issome temptation to spend too much time coming up with the

    most elegant solutions and highly reusable objects that are

    beautifully well-designed" .owe$er, & ha$e found that the best

    solution is usually the simplest solution" or this businessobject, & will create a )ounter* that will pro$ide a count of the

    times that a count has been re5uested for a gi$en +ey"

    Counter.java ->

    pac"age com.antii.'iKimport ja!a.util.Hashta'lepu'lic class $ounter pri!ate static Hashta'le counts

    static counts 3 ne Hashta'leG C pri!ate static s

  • 8/13/2019 Getting Started With Struts2

    15/37

    C

    The ounter class abo$e will act as the /odel"B &t represents

    the business case" Although the custom tag & wrote abo$e canbe considered reusable, someone could ma+e a case that this

    class is e$en more reusableB because it has no dependencies

    (other than basic classes li+e .ashtable and &nteger and

    primiti$es#" Another +ey feature of this business object is that ithas a getter"B Although this is not a traditional a$a9ean, the

    )getount* method will be found through introspection and

    treated in a special way when it comes to the Struts2 coding

    later"

    3ow that & ha$e a business object that acts as my /odel,B &ha$e to create the KiewB and ontroller"B To proceed, & will

    need an Action class and a S%" A Struts2 Action class is a a$a

    object that implements the Action interface" To implement the

    Action interface, & only need to create one method callede6ecuteB which ta+es no parameters and returns a String"

    Although the )public String e6ecute(#* method is the only

    re5uirement, there are many more features that can be

    e6ploited while coding action classes" Lou can use a defaultimplementation called )ActionSupport"* '$ery action & ha$e

    written to date has e6tended ActionSupport" ActionSupport*s

    implementation of the )e6ecute* method simply returns the

    String success"B This will be significant when & configure theaction"

    Another nifty feature of Action classes in Struts2 is that all

    getterB methods are e6posed to the S% files that are rendered"

    or the sample action that & will create, & will use this

    functionality to create an Action that trac+s it*s own hit count"

    CountableAction.java ->

    pac"age com.antii.strutsimport com.opens

  • 8/13/2019 Getting Started With Struts2

    16/37

    return count.get$ountG C

    C

    To use this action we must configure this class in the strutsconfiguration file"

    struts.xml ->

    01xml !ersion34(.4 encoding345&F-,4 160?=%$&@AE struts A5BLI$ 4-//7pache o)tare Foundation//=&= truts$on)iguration *.//EN4 4http://struts.apache.org/dtds/struts-*..dtd46

    0struts6 0constant name34struts.ena'le.=

  • 8/13/2019 Getting Started With Struts2

    17/37

    0DO tagli' uri34/struts-tags4 pre)ix34s4 D60html60head60title67 imple $ounted Aage0/title60/head6

    0'odimport org.junit.7)terimport org.junit.Be)oreimport org.junit.&estimport com.antii.'iK.$ounterpu'lic class $ounter&est O&est pu'lic )inal !oid testQet$ountG $ounter counter 3 ne$ounter45nit&est$ount4G int )irst 3 counter.get$ountG

    $ounter another$ounter 3 ne$ounter45nit&est$ount4G int next 3 another$ounter.get$ountG int di))erence 3 next - )irst assert&ruedi))erence 33(G C

    C

    CountableActionest.java ->

    pac"age test.antii.strutsimport static org.junit.7ssert.>

  • 8/13/2019 Getting Started With Struts2

    18/37

    import org.junit.7)terimport org.junit.Be)oreimport org.junit.&estimport com.antii.struts.$ounta'le7ctionpu'lic class $ounta'le7ction&est O&est

    pu'lic )inal !oid testQet$ountG $ounta'le7ction )irst 3 ne $ounta'le7ctionG $ounta'le7ction next 3 ne $ounta'le7ctionG int )irst$ount 3 )irst.get$ountG int next$ount 3 next.get$ountG int di))erence 3 next$ount - )irst$ount assert&ruedi))erence 33(G tr< assert&rue)irst.executeG.euals4success4GG assert&ruenext.executeG.euals4success4GG C catchException eG )aile.getMessageGG

    C C

    C

    There are ways to create unit tests for the first e6ample" To

    write a unit test for the custom tag written in the Ser$let!S%e6ample, you would need to add 5uite a bit of house+eeping

    code that simply creates all of the necessary objects to fill all of

    the dependencies re5uired" Cnit tests are not the only

    ad$antage of the Struts e6ample, but the unit tests representthe ad$antages you gain" .a$ing simple objects and unit tests

    allow me to de$elop with a design by contractB type of

    paradigm" & can continue to ma+e changes or enhance the

    objects and the unit tests will +eep me from introducing bugs"This is not a full proof method for +eeping bugs out of the

    system, but it is a highly effecti$e method" Another ad$antage

    of using simple objects is that & can reuse my components on

    platforms other than Struts2 and S%"

    There are also a few disad$antages that & should point out" irstoff, using Struts2 is not particularly intuiti$e at first" There are

    many topics that & glossed o$er that would re5uire e6planation

    before wor+ing on your first Struts2 project (struts"6ml and

    Fsproperty !G tag for e6ample#" This is easily o$ercomethough once you start" About two wee+s into my first Struts2

    project, & felt that & was up to speed" The ne6t disad$antage is

    that the custom tag in the Ser$let!S% e6ample is usable in any

    S% within the web-app, whereas the ounted action is only one

    page" This disad$antage is also easily dealt with in a number ofdifferent ways" 1ne possible solution is to ha$e other actions

  • 8/13/2019 Getting Started With Struts2

    19/37

    e6tend ountableAction" Since a$a does not support multiple

    inheritance, this may not be a great solution" A better solution is

    to use the Struts built-in AA4 support to call the ounted actionfrom the pages that need a count"

    Example #2 - Send a essage Page

    3ow that we ha$e one Struts2 action under our belts, it is time

    to get a little more comple6" 1ur ne6t e6ample is one that e$enthe most basic websites ha$e, a Send Cs A /essageB page"

    These pages started to become common for plenty of ob$ious

    reasons" The purpose of a page li+e this is to pro$ide a web

    $isitor with a method for contacting the site owners without

    displaying email addresses for spammers to har$est with webcrawlers" 3ot only does a page li+e this protect site owners from

    potential spam, but it also allows the incoming messages to be

    recorded" 1n many sites, the messages are pushed right into aR/ system as a lead"

    As with the last e6ample, & will start off by ma+ing a solution

    based on Ser$lets and S% alone" or this project, & am going to

    ta+e what the web $isitor types and email it" '$en if you ha$e

    not written much Ser$let and S% code, you probably +now that

    ha$ing a$a code in your S% is considered bad design" &n fact,it is considered a best practiceB to write your form in a S% and

    ha$e the form post to a Ser$let which performs the hea$y-lifting

    then passes control on to another S%" As an added bonus,control can be passed bac+ to the original form if there is an

    error and ha$e the original form notify the user of the error and

    ma+e suggestions to fi6 the condition"

    Lou may be tempted to start out by creating a S%, but & am

    going to start with the ser$let" 9y tac+ling the ser$let first, & will+now all of the error conditions that may send the user bac+ to

    the S%" When & wor+ on the S%, all of the e6tra code for

    handling the errors will be a bit more intuiti$e"

    !endMessage.java ->

    pac"age com.antii.examples.ser!lets

    import ja!a.io.I%Exceptionimport ja!a.util.Aroperties

  • 8/13/2019 Getting Started With Struts2

    20/37

    import ja!ax.mail.Messageimport ja!ax.mail.MessagingExceptionimport ja!ax.mail.essionimport ja!ax.mail.&ransportimport ja!ax.mail.internet.7ddressException

    import ja!ax.mail.internet.Internet7ddressimport ja!ax.mail.internet.MimeMessageimport ja!ax.ser!let.er!let$on)igimport ja!ax.ser!let.er!letExceptionimport ja!ax.ser!let.http.Httper!letimport ja!ax.ser!let.http.Httper!letReuestimport ja!ax.ser!let.http.Httper!letResponsepu'lic class endMessage extends Httper!let tring email&o 3 null tring mailer!er 3 null Internet7ddress email&o7ddr 3 null

    pu'lic !oid initG thros er!letException

    super.initG er!let$on)ig con)ig 3 geter!let$on)igG mailer!er 3con)ig.getInitAarameter4mailer!er4G email&o 3con)ig.getInitAarameter4email&o4G Internet7ddressS addr7rra< 3 null tr< addr7rra< 3

    Internet7ddress.parseemail&o )alseG C catch 7ddressException aG thro ne RuntimeException4'ademail address chec" the ser!let init params in / tring msgRepl

  • 8/13/2019 Getting Started With Struts2

    21/37

    tring msg$ontents 3reuest.getAarameter4message$ontent4G tring su'ject 3reuest.getAarameter4su'ject4G /> ma"e sure there is an email address to

    repl< to later >/ i)msgRepl

  • 8/13/2019 Getting Started With Struts2

    22/37

    response.sendRedirectresponse.encodeRedirect5RLreuest.get$ontextAathG 4/contact5s.jsp1msgFailed3+4GG return C

    /> Lastl

  • 8/13/2019 Getting Started With Struts2

    23/37

    o$er it briefly and +now that it sends an email" When reading

    the do%ost method, there are four things that happen"

    :" the parameters are read2" the parameters read pre$iously are $alidated

  • 8/13/2019 Getting Started With Struts2

    24/37

    0tr6 0td align34right46@our Email 7ddress:0/td6 0td align34le)t460input name34senderEmail4 /60/td6 0/tr6 0tr6 0td align34right46u'ject:0/td6

    0td align34le)t460input name34su'ject4 /60/td6 0/tr6 0tr6 0td align34right46@our Message:0/td6 0td align34le)t46 0textarea name34message$ontent4 cols349P4 ros34(P46&

  • 8/13/2019 Getting Started With Struts2

    25/37

    place to loo+ would be the ST0" The ST0 pro$ides tags that

    can perform logic tests which would clean up this S% 5uite a

    bit, and there are many other features of the ST0 that could beuseful on any project li+e looping tags, date and currency

    formatting tags, etc"

    & am not going to paste the contents of messageSent"jsp" This

    page contains only .T/0 code but is a S% in case we add some

    programmatic elements such as custom tags in the future"

    9efore & co$er a Struts 2 solution, & would li+e to say that since

    this is a larger e6ample, right away the disad$antages of using

    only S% and Ser$let technology start to surface" & do not want

    to gi$e the impression that S% and Ser$lets are bad technology,

    but just that there are inherent disad$antages that can beo$ercome using a framewor+ (namely the Struts 2 framewor+#"

    /any of the problems & mentioned abo$e are compounded e$en

    further on other platforms (such as perl & code#" As with any

    platform, as your codebase grows, organi>ation and good designbecome important" 1ne of the teams & wor+ed on in the past

    used S% and Ser$let technology 5uite e6tensi$ely" We were not

    using any framewor+s" 'ach time enhancements were

    re5uested, the project would usually be nearly re-written from

    scratch" Kery little of the code was considered reusable becausee$en if changes were not necessary, an engineer would ha$e to

    spend time reading code just to $erify that the changes were

    not necessary" This had less to do with the lac+ of framewor+and more to do with a lac+ of unit testing and no modern design

    patterns being incorporated" Although this article (and other

    future articles# may read as though there is a hea$y Struts 2

    bias, the point that & would li+e to ma+e is that discipliningyourself to using a design pattern and stic+ing to it will ma+e

    your life easier as your projects grow"

    or the Struts 2 solution & will start with the business objects" &n

    this case, & need an object to represent the message submitted

    from the website" & will call this class WebSite/essage" Thebusiness object will follow a$a9eans con$entions much better

    than our first Struts e6ample" & will ma+e getters and setters for

    all of the members and & will ma+e a *send* method that sends

    the message"

    #eb!iteMessage.java ->

  • 8/13/2019 Getting Started With Struts2

    26/37

    pac"age com.antii.'iKimport org.apache.commons.mail.EmailExceptionimport org.apache.commons.mail.impleEmailimport static com.antii.'iK.$on)ig.con)igpu'lic class We'iteMessage

    pri!ate tring msgRepl

  • 8/13/2019 Getting Started With Struts2

    27/37

    Lou will notice a few important items" irst, this time around, &

    decided to use the commons-email pac+age from the Apache

    a+arta project" 1$erall, the code is only shortened slightly, butthis is a bit easier to read" There is also a onfig object

    referenced" & am not going to insert the code, it really is awrapper around the commons-configuration pac+age from the

    Apache a+arta project" Struts does not ha$e a mechanism forpro$iding general purpose configuration elements" &n the first

    half of this e6ample, & used the ser$let*s init-params" or a large

    scale project, neither method would be preferred" 1n a large

    scale project, & would suggest in$esting time learning a7ependency &njection framewor+ li+e Spring which will be

    co$ered in a future article" At first, it may not seem that Spring

    can sol$e simple configuration issues, but li+e Struts, if you

    in$est some time learning the Spring framewor+ as it isintended to be used, then you will find that your code willbecome easier to maintain and many mundane tas+s can be

    handled within the framewor+"

    To create a unit test for this a$a9ean is tri$ial" Although the

    object now has e6ternal dependencies, they are in$isible to thecalling code" The action for this project will be more comple6

    than the last one & wrote" &n the last action, & e6ploited a getter

    method from a result S%" &n this action, & am going to usesetters to recei$e the form fields from the input form" & will alsowrite an e6ecute method since the ActionSupport

    implementation will not suffice" & am also going to use Struts*

    $alidation facilities" As you will see the input $alidation will not

    happen within the action code" irst & will create the action

    class, then & will co$er the $alidation techni5ue"

    !endMessageAction.java ->

    pac"age com.antii.strutsimport com.opens

  • 8/13/2019 Getting Started With Struts2

    28/37

    msg.setMsg$ontentsmsg$ontentsG msg.setMsgRepl

  • 8/13/2019 Getting Started With Struts2

    29/37

    4-//%pen

  • 8/13/2019 Getting Started With Struts2

    30/37

    !endMessage-input.jsp ->

    0DO tagli' uri34/struts-tags4 pre)ix34s4

    D60html60head60title6end 5s 7 Message0/title60script language34Ja!acript460?--!ar taelected 3 //--60/script60s:head theme34ajax4 /60/head60'od

  • 8/13/2019 Getting Started With Struts2

    31/37

    of a$aScript inserted manually to select the te6t in the

    Fte6tareaG when the Fte6tareaG recei$es focus for the first

    time" The a$aScript is inserted to demonstrate how easy it is tointegrate your own a$aScript despite all of the a$aScript

    generated by the Struts elements" '$en if a theme is chosenthat does not ma+e use of a$aScript such as the simpleB

    theme, the a$aScript you add will e6ecute and wor+ as normal"

    0et us compare the $iew generated by each techni5ue" .ere wecan see the output of the contactCs"jsp page-

  • 8/13/2019 Getting Started With Struts2

    32/37

    .ere is the same page if the $alidation fails -

  • 8/13/2019 Getting Started With Struts2

    33/37

    3ow, let us ta+e a loo+ at the Struts2 pages" .ere isthe input page -

  • 8/13/2019 Getting Started With Struts2

    34/37

    0et us also ta+e a loo+ at how the page loo+s when$alidation fails"

    What you can not see in the screenshot was the smoothness

    with which the error was displayed" &n the first half of this

    e6ample, & used some $alidation at the ser$er so that for the

    error message to reach the user, the page would ha$e to besubmitted then reloaded with the error" &n the second half of

    this e6ample, the error message is inserted into the page

    without reloading the entire page"

    There are many ad$antages to discuss just at this point"1b$iously, each of the Struts components can be unit tested

  • 8/13/2019 Getting Started With Struts2

    35/37

    easily because they ha$e few dependencies" Also, you can tell

    right away that the $alidation facilities in Struts are $ery useful

    and what you ha$e not seen at this point is just how e6tensiblethey can be" & will discuss $alidation further in a future article"

    Also, you can probably already sense just how easy it would beto ma+e changes to your business logic while minimi>ing

    changes to your C&" Another big ad$antage at this point is thatthe a$a code is contained within only two simple elements" &f

    you ta+e a second loo+ bac+ through the e6isting code, there is

    no direct dependence on any part of the Ser$let A%&" & ha$e also

    mo$ed input $alidation out of the code and treat it as aconfiguration which will allow me to concentrate on the business

    logic" Another ad$antage of Struts2*s $alidation facility is that

    $alues are retained with no e6tra effort" So if a user is wor+ing

    on a form and fails $alidation, none of what was input will belost"

    & did not co$er the messageSent"jsp file because there was

    nothing worth discussing, but in Send/essage-success"jsp, &

    ha$e access to all of the action class*s getter methods" So, & can

    easily echo bac+ to the user what was sent"

    !endMessage-success.jsp ->

    0DO tagli' uri34/struts-tags4 pre)ix34s4D60html60head60title6Message ent uccess)ull

  • 8/13/2019 Getting Started With Struts2

    36/37

    0/ta'le60/'od

    01xml !ersion34(.4 encoding345&F-,4 160?=%$&@AE struts A5BLI$ 4-//7pache o)tare Foundation//=&= truts$on)iguration *.//EN4 4http://struts.apache.org/dtds/struts-*..dtd460struts6 0constant name34struts.ena'le.=

  • 8/13/2019 Getting Started With Struts2

    37/37

    0/struts6

    This action is configured slightly differently than the first" & am

    using a wildcard this time around that allows me to specifywhich of the action*s methods to call by specifying it in the CR0"

    This way, by specifying Send/essageHinput"action, the input

    method is run which bypasses $alidation and presents the input

    form" The .T/0 form on the input page will post toSend/essage"action, which will default to running the e6ecute

    method" Struts +nows to treat the H8B in a special way, so it is

    not necessary to post to Send/essageHe6ecute"action" When

    the input form posts to the action, if $alidation fails, the inputpage is redisplayed with appropriate error messages"

    .opefully the two e6amples gi$e you a feel for the ways that

    Struts2 can help you" 9efore & am finished, & will create a few

    more articles that gi$e more detailed information on writing

    actions or using the Struts2 tags" At this point, you should startto feel that you understand more about the architecture and

    ha$e a better general idea how writing code for the Struts2

    framewor+ differs from traditional S%!Ser$let programming"