You are on page 1of 132

What is Struts?

Struts is a popular open source framework from Apache Software Foundation to build web applications that integrate with standard technologies such as Servlets, Java Beans and Java Server pages.

Struts offers many benefits to the web application developer,including the Model-ViewController (MVC) design patterns (best practice) in web applications.

he Model-View-Controller paradigm applied to web applications lets you separately display code (for e!ample, " M# and tag libraries) from flow control logic (action classes) from the data model to be displayed and updated by the application.

Struts offers a set of tag libraries to support the faster development of the different layers of the web application.

he basic idea of the MVC architecture is to divide the application into three layers$ Model that represents the data layer, a view layer that represents the data processed by the model component% and a Controller component that is responsible for interaction between the model and the controller.

So when we say Struts is an MVC framewor& for web based applications, we actually mean that it facilitates the rapid development of applications by providing a Controller that helps interaction between the model and the view so that an application developer has not to worry about how to ma&e view and the model independent of each other and yet e!ist in coordination.

Struts is basically a Controller. It depends on other things for the model and the view. It can communicate with Hibernate, Enterprise Java Beans or any other ava components for the model. JS!"Servlets are used for the view which use html front end internally. Struts provides several tag libraries to support the rapid development for the view layer. Why do we need Struts? #lthough a dynamic web application can be developed using JS! and Servlet technology, there are many problems.

$ %ightly coupled classes & one change affects other classes $ Business logic resides in both presentation and data access layer. So if there is a change in a business rule, needs multiple places to find the business rules. #lso promotes duplicate business rules. $ 'ata sources are difficult to change as data access methods may be used in the presentation layer. $ (ogic to determine what to do ne)t is across the application,no centrali*ed decision.

%o solve these problems,we need a mechanism that can separate the

presentation layer of a web application from business logic. (uc+ily we have ,-C and we have Struts. ,-C is a design pattern .best practice method/ that separates the application design into there main parts0

,odel, -iew and Controller

$ ,odel & data and logic .business logic methods/. $ -iew & output displayed to the user $ Controller & ta+es the input from the user and passes it to the relevant model. %he model returns and based on the result, the controller decides which view .page/ to show the user. Advantages of Struts Struts offers many advantages to the application programmer while reducing the development time and ma&ing the manageability of the application easier. "ere are few &ey advantages of using Struts instead of managing the every layer of the web application yourself.

Centralized File-Based Configuration

'ather than hard coding information into (ava programs,many Struts values are represented in )M# or property files. his loose coupling means that many changes can be made without modifying or recompiling *ava code,and that wholesale changes can be made by editing a single file. his approach also lets *ava and +eb developers focus on their specific tas&s (implementing business logic,presenting certain values to clients,etc.) without needing to &now about the overall system layout.

Form Beans

,n *S-,you can use property./0/ with (sp$set-roperty to automatically populate a *ava1ean component based on incoming re2uest parameters. 3nfortunately,however,in the standard 4-, this capability is unavailable to servlets,even though with MVC it is really servlets,not *Spages,that should usually be the target of form submissions. 4pache Struts e!tends this capability to *ava code and adds in several useful utilities,all of which serve to greatly simplify the processing of re2uest parameters.

Bean Tags

4pache Struts provides a set of custom *S- tags (bean$write,in particular) that let you easily output the properties of *ava1eans components. 1asically,these are concise and powerful variations of the standard (sp$use1ean and (sp$get-roperty tags.

HTML tags

4pache Struts provides a set of custom *S- tags to create " M# forms that are associated with *ava1eans components. his bean5form association serves two useful purposes$

,t lets you get initial form-field values from *ava ob(ects.

,t lets you redisplay forms with some or all previously entered values intact.

Form Field Validation

4pache Struts has built-in capabilities for chec&ing that form values are in the re2uired format. ,f values are missing or in an improper format,the form can be automatically redisplayed with error messages and with the previously entered values maintained.

his validation can be performed on the server (in *ava),or both on the server and on the client (in *avaScript).

Struts 6.7 is currently in beta phase and contains the e!isting Struts features plus all the features of +eb+or&s framewor&. Setting up Eclipse for Web Development 1. Eclipse does not come with a bundled Java 'evelopment 2it. 'ownload and install J'2 1.3 .Sun or IB,/ http0"" ava.sun.com" 4se"downloads"inde).html

4. 'ownload and install Eclipse 5.4.1 from0

http0""www.eclipse.org"downloads"download.php6 file7"eclipse"downloads"drops"8&5.4.1&499:9;419;3<"eclipse&S'2&5.4.1& win54.*ip

5. By default,Eclipse supports only basic Java 'evelopment. ,ost of the advanced features are available in the form of pluggins which may be downloaded and installed from there respective repositories. ,yEclipse is a mini&I'E which is installed as an add&on to the Eclipse. 'ownload and install ,yEclipse <.1 from0

http0""www.myeclipseide.com"'ownloads=4Binde)&re>&viewsdownload&sid& 1<.html

3. %o deploy the web applications,we need a Servlet container li+e tomcat or JBoss. 'ownload and install %omcat <.9.) .or other compliant Servlet"EJB container/ from http0""www.a)int.net"apache" a+arta"tomcat& <"v<.9.4?"bin" a+arta&tomcat&<.9.4?.e)e

If your Eclipse version is other than 5.4.1,please download an appropriate ,yEclipse plug&in from http0""www.myeclipseide.com"

5. 'ownload the source code used in this tutorial http$55www.visualbuilder.com5tutorials5(sp5struts5sourcecode5eclipse-pro(ect.8ip :. Registration Case Study Let us consider an example a web based user registration application !suall" e#er" web based application re$uires secure login to access its critical resources t%erefore a user management is part of e#er" web application

&ur first 'truts application is a web based user registration application T%e application is capable of displa"ing t%e list of registered users and allowing t%e user to add a new user to t%e database (e)ll use a single table *users) to store t%e user information 'elect an" database of "our c%oice+and create a table ,!'-.', wit% following fields/

Column Name

Data Type

Constraints

US !"#$

% &%

'!#(A!) * )

F#!S%"+A( -AS%"+A( A. (A#'ASS/,!$

% &% % &% +U(B ! % &% % &%

+,+ +,+ +,+ +,+ +,+

@eAll use ,icrosoft #ccess database for this purpose. Bse the following SC( to create table in ,icrosoft #ccess.

CREATE TABLE USERS(

user_id text primary key,

first_name text,

last_name text,

age number,

email text,

pass !rd text

"#

Struts Configuration Now that we have configured our pro ect for struts!let"s have a loo# at the configurations $yEclipse has made for us%

Web.xml /eb.0ml resides in application1s / B2#+F director3 and contains the essential configuration for the web application like the Servlet mappings,Authentications mechanisms,%ag libraries etc. -et1s see what is in web.0ml right now.

450ml version678.97 encoding67U%F2:75; 4web2app 0mlns67http<==>ava.sun.com=0ml=ns=>?ee7 a0mlns<0si67http<==www.w@.org=?998=&(-Schema2 instance7 version67?.A7 0si<schema-ocation67http<==>ava.sun.com=0ml=ns=>?ee BBhttp<==>ava.sun.com=0ml=ns=>?ee=web2 app"?"A.0sd7; 4servlet; 4servlet2name;action4=servlet2name; 4servlet2class;org.apache.struts.action.ActionServlet4=servlet2class; 4init2param; 4param2name;config4=param2name; 4param2value;=/ B2#+F=struts2config.0ml4=param2value; 4=init2param; 4init2param; 4param2name;debug4=param2name; 4param2value;@4=param2value; 4=init2param; 4init2param; 4param2name;detail4=param2name; 4param2value;@4=param2value; 4=init2param; 4load2on2startup;94=load2on2startup; 4=servlet; 4servlet2mapping; 4servlet2name;action4=servlet2name; 4url2pattern;C.do4=url2pattern; 4=servlet2mapping; 4=web2app;

As we can see,there is one Servlet configured and is mapped with U!- pattern C.do. /hat is this DActionServlet1 for5 %his is the simple wa3 how the Struts E,+%!,- ! is plugged into the web application.

%he basic reason of defining a servlet mapping for a web application is that whenever someone access a page that matches the U!- pattern defined in servlet mapping,Application Server will redirect the reBuest to this servlet. %hat means,we have configure Struts Action Servlet to receive all the reBuest that end with a .do ke3word. /e can even configure it for .html or .>sp or .abc,.do is the generall3 accepted token.

Struts-config.xml 450ml version678.97 encoding67U%F2:75; 4F$,E%)' struts2config 'UB-#E 72==Apache Software Foundation==$%$ Struts Eonfiguration 8.?== +7 7http<==struts.apache.org=dtds=struts2config"8"?.dtd7; 4struts2config; 4data2sources =; 4form2beans =; 4global2e0ceptions =; 4global2forwards =; 4action2mappings =; 4message2resources parameter67com.visualbuilder.struts.Application!esources7 =; 4=struts2config;

/e don1t have an3thing special in this file configured,but as 3ou can see,we have the basic tags. /e1ll add the appropriate struts components to these tags as we develop them. ,ne important thing in this file is the message2resources. %his is a resource bundle that will contain all the errors,labels or other messages that we want to displa3 on the view G>sp pagesH. %he separation of the String messages from the >sp pages helps internationaliIation. Writing the &ser class 'et"s start with our first ava class% Remember we have a table (users) in the database% 'et"s write a simple bean that represents this table%

package com.visualbuilder.struts.beansJ

public class User K private String user#d 6 77J private String first+ame 6 77J private String last+ame 6 77J private int age 6 9J private String email 6 77J

private String password 6 77J

public UserGString user#dH K superGHJ this.user#d 6 user#dJ L public int getAgeGH K return ageJ L public void setAgeGint ageH K this.age 6 ageJ L public String get mailGH K return emailJ L public void set mailGString emailH K this.email 6 emailJ L public String getFirst+ameGH K return first+ameJ L public void setFirst+ameGString first+ameH K this.first+ame 6 first+ameJ L public String get-ast+ameGH K return last+ameJ L public void set-ast+ameGString last+ameH K this.last+ame 6 last+ameJ L public String getUser#dGH K return user#dJ L public void setUser#dGString user#dH K this.user#d 6 user#dJ L public String get'asswordGH K return passwordJ L public void set'asswordGString passwordH K this.password 6 passwordJ L L

Resource$anager As we have already discussed!one of the main concerns of the struts framewor# is to separate the string resources from the view% *or this purpose!we have already defined a message+resources property n struts+ config%,ml% $ost of the struts components will e,pect a property #ey where a string literal will be needed% -o be consistent with the struts framewor#!we will try to separate the string resources from our normal ava classes where we are not using struts components% -o do this!we can use ava%util%Resource.undle class to pic# the values from properties file against the specified #eys% -o ease the manipulation of string resources where we are not using the struts components!we"ll write a separate class%

package com.visualbuilder.strutsJ import >ava.util.!esourceBundleJ public class !esource(anager K private static !esourceBundle bundle6!esourceBundle.getBundleG7com.visualbuilder.struts.Application!esources7HJ public static String getStringGString ke3HK return bundle.getStringGke3H L L Writing the Struts .usiness Component Now let us write our business class that has the ability to perform several actions on the user li#e adding a new user to the database!updating an e,isting user!deleting a user or fetching a user from the database% 'et us call this class a &ser$anager%

package com.visualbuilder.struts.dbJ public class User(anager K private static User(anager mgr 6 nullJ private User(anagerGH K L

public static User(anager get#nstanceGH K ifGmgr 66 nullH K mgr 6 new User(anagerGHJ L return mgrJ L L Because for one application,there can e0ist onl3 a single User(anager,we have made the User(anager a singleton. /e will use User(anager.get#nstanceGH whenever we need an instance of User(anager.

Connecting to a database %he purpose of the User(anager is to provide an interface between the database and the client applications that need access to the database. -et1s connect to the database and add the following code in the constructor.

String driverElass 6 ResourceManager.getStringG7database.driver7HJ

String dbUrl 6 ResourceManager.getStringG7database.url7HJ

String dbUser 6 ResourceManager.getStringG7database.user7HJ

String db'assword 6 ResourceManager.getStringG7database.password7HJ tr3K Elass.for+ameGdriverElassHJ con 6 $river(anager.getEonnectionGdbUrl,dbUser,db'asswordHJ LcatchG 0ception e0pHK S3stem.err.printlnG7Eould not connect to dtabase.Mn7 e0p.get(essageGHHJ L

/here con is a global variable of t3pe >ava.sBl.Eonnection. +ow that we have connected to the database,let us add the necessar3 methods to manipulate the users.

After adding these methods,User(anager

package com.visualbuilder.struts.dbJ

import >ava.sBl.!esultSetJ import >ava.sBl.StatementJ import >ava.sBl.EonnectionJ import >ava.sBl.$river(anagerJ import >ava.sBl.SN- 0ceptionJ import >ava.sBl.'reparedStatementJ import >ava.util.Arra3-istJ import >ava.util.-istJ

import com.visualbuilder.struts.!esource(anagerJ import com.visualbuilder.struts.beans.UserJ

public class User(anager K private static User(anager mgr 6 nullJ private Eonnection con 6 nullJ private User anagerGH K String driverElass 6 !esource(anager.getStringG7database.driver7HJ String dbUrl 6 !esource(anager.getStringG7database.url7HJ String dbUser 6 !esource(anager.getStringG7database.user7HJ String db'assword 6 !esource(anager.getStringG7database.password7HJ tryK Elass.forNameGdriverElassHJ con 6 $river(anager.getConnectionGdbUrl,dbUser,db'asswordHJ LcatchG 0ception e0pHK S3stem.err.printlnG7Eould not connect to dtabase.Mn7 e0p.get essageGHHJ L L public void sa!eUserGUser userH throws SN- 0ception K ifGuser 66 nullH throw new S"#$xceptionG!esource(anager.getStringG7save.user.null7HHJ Eonnection connection 6 getConnectionGHJ 'reparedStatement pstmt 6 connection.prepareStatementG7insert into

usersGuser"id,first"name,last"name,age,emailH valuesG5,5,5,5,5H7HJ pstmt.setStringG8,user.getUser%dGHHJ pstmt.setStringG?,user.get&irstNameGHHJ pstmt.setStringG@,user.get#astNameGHHJ pstmt.set%ntGA,user.get'geGHHJ pstmt.setStringG5,user.get mailGHHJ pstmt.executeUpdateGHJ pstmt.closeGHJ L public User getUserGString user#dH thro(s SN- 0ception K ifGuser#d 66 null OO user#d.lengthGH 66 9H thro( ne( S"#$xceptionG!esource(anager.getStringG7retrieve.user.null7HHJ Eonnection connection 6 getConnectionGHJ Statement stmt 6 connection.createStatementGHJ !esultSet rs 6 stmt.execute"ueryG7select C from users where user"id6PaposJ7 user#d 7PaposJ7HJ User user 6 nullJ ifGrs.nextGHH K user 6 ne( UserGuser#dHJ user.set&irstNameGrs.getStringG7first"name7HHJ user.set#astNameGrs.getStringG7last"name7HHJ user.set'geGrs.get%ntG7age7HHJ user.set$mailGrs.getStringG7email7HHJ L rs.closeGHJ stmt.closeGHJ return userJ L public -ist listGH thro(s SN- 0ception K Eonnection connection 6 getConnectionGHJ Statement stmt 6 connection.createStatementGHJ !esultSet rs 6 stmt.execute"ueryG7select C from users7HJ User user 6 nullJ -ist list 6 ne( 'rray#istGHJ (hileGrs.nextGHH K user 6 ne( UserGrs.getStringG7user"id7HHJ user.set&irstNameGrs.getStringG7first"name7HHJ user.set#astNameGrs.getStringG7last"name7HHJ user.set'geGrs.get%ntG7age7HHJ user.set$mailGrs.getStringG7email7HHJ list.addGuserHJ L rs.closeGHJ

stmt.closeGHJ return listJ L pri!ate Eonnection getConnectionGH thro(s SN- 0ception K ifGcon 66 nullH thro( ne( S"#$xceptionG!esource(anager.getStringG7database.notEonnected7HHJ return conJ L public static User(anager get%nstanceGH K ifGmgr 66 nullH K mgr 6 ne( User anagerGHJ L return mgrJ L public !oid finali)eGH K tryK con.closeGHJ LcatchG 0ception e0pHKL L L

/e have used several properties in this class. Add these properties in the Application!esources.properties file.

#database connection properties database.driver 6 sun.>dbc.odbc.Jdbc,dbc$river database.url 6 >dbc<odbc<users database.user 6 77 database.password 6 77 #User operations messages save.user.null 6 User is null retrieve.user.null 6 User is null user.notFound 6 User not found database.notEonnected 6 +ot connected to a database +ow we have all the business functions available,we are read3 to move to the formal development of the struts based application.

Creating the Action Class -he basic component of a struts based application is the Action class% #dding #ctionDorward %he EforwardE element in struts&config.)ml describes an #ctionDorward that is to be made available to an #ction as a return value. #n #ctionDorward is referenced by a logical name and encapsulates a B8I. # EforwardE element may be used to describe both global and local #ctionDorwards. Flobal forwards are available to all the #ction ob ects in the module. (ocal forwards can be nested within an GactionH element and only available to an #ction ob ect when it is invo+ed through that #ction,apping. (et us add two forwards for (ogin#ction IsuccessJ and IfailJ. #fter adding the two forwards,the GactionH tag loo+s li+e this0

4action path67=login7 t3pe67com.visualbuilder.struts.action.-oginAction7 validate67false7; 4forward name67success7 path67=manageusers.>sp7 =; 4forward name67failure7 path67=inde0.>sp7 =; 4=action;

+ote the two forwards success and the failure. %he path attribute in each forward tag is the resource to which the reBuest will be redirected when forwarded to a particular forward. -et us now program our action to return to QsuccessR if the entered user id and password is admin=admin. !ight now we don1t have an3 action form associated with this action,let1s get the parameters from reBuest as we do in servlets. String user 6 reBuest.get'arameterG7user#d7HJ String password 6 reBuest.get'arameterG7password7HJ ifGuserF6null PP passwordF6null PP user.eBualsG7admin7H PP password.eBualsG7admin7HH return mapping.findForwardG7success7HJ return mapping.findForwardG7failure7HJ

+ow create inde0.>sp so that we have a form to submit values to this form. Add the following form in the bod3 section of the >sp.

4form action67=login.do7 method67post7;

4table border6797; 4tr; 4td;-ogin<4=td; 4td;4input t3pe67te0t7 name67user#d7 =;4=td; 4=tr; 4tr; 4td;'assword<4=td; 4td;4input t3pe67te0t7 name67password7 =;4=td; 4=tr; 4tr; 4td colspan67?7 align67center7;4input t3pe67submit7 value67-ogin7=;4=td; 4=tr; 4=table; 4=form; /e are almost read3 to run the pro>ect. But let1s create a file manageusers.>sp so that if we enter a valid user id = password,we can see the success page. Add a simple success message Q)ou are logged into this pageR.

Adding the *orm bean


In our (ogin#ction,we retrieved the form values using the conventional methods in HttpServlet8e>uest. Struts provides an easy way to retrieve these values with the help of form beans. # form bean is a simple JavaBean that e)tends from org.apache.struts.action.#ctionDorm. @e already have a JavaBean IBserJ but that does not e)tend from #ctionDorm. @e can reuse this JavaBean for this purpose. (etAs add the e)tends clause to the Bser class so that the signature of the class becomes public class Bser e)tends #ctionDorm #lso we need to add a no&argument constructor to the Bser class to enable the struts framewor+ to instantiate the bean. public Bser./K super./L

Configuring *orm .ean in struts+ config%,ml


#dding a form bean is a two step process. Dirst of all we need to declare the form bean in the Gform&beansH tag. %hen we can associate this form bean to as many actions as we want. %o declare the form bean,add the following line in the Gform& beansH tag.

4form2bean name67loginForm7 t3pe67com.visualbuilder.struts.beans.User7 =;

+ow we will associate this form bean with the -oginAction. Update the action tag in action2mappings so that it becomes like this.

4action

name67loginForm7

path67=login7

scope67reBuest7

t3pe67com.visualbuilder.struts.action.-oginAction7

validate67false7;

4forward name67failure7 path67=inde0.>sp7 =;

4forward name67success7 path67=manageusers.>sp7 =;

4=action;

+ow update the -oginAction to retrieve form values from form bean instead of reBuest ob>ect though the3 are still available in the reBuest ob>ect s well. 0ecute method should look like this now.

public ActionForward executeGAction(apping mapping,ActionForm form,SttpServlet!eBuest reBuest,SttpServlet!esponse responseH K User userForm 6 GUserHformJ String user 6 userForm.getUser%dGHJ String password 6 userForm.get*ass(ordGHJ ifGuserF6null PP passwordF6null PP user.e+ualsG7admin7H PP password.e+ualsG7admin7HH return mapping.find&or(ardG7success7HJ return mapping.find&or(ardG7failure7HJ L

Again deplo3 and run the pro>ect. )ou should get the same behavior as 3ou got earlier.

&sing Struts -ag 'ibraries


%he Struts framewor+ provides a set of built&in %ag libraries that allow you to build the view part of the ,-C without embedding Java code directly within your application JS!s. Some commonly used struts tag libraries are described below.

The ,ean Tags %he %ags within the Bean -ibrar3 are used for creating and accessing JavaBeans and a few other general purpose uses. Although these tags work with an3 standard JavaBean,the3 are often used with ,b>ects that e0tend the Struts ActionForm class.

The -T # Tags %he %ags within the Struts S%(- %ag -ibrar3 are used to create input forms for 3our application. %here are also a few other useful %ags used in the creation and rendering of S%(-2based user

interfaces.

The #ogic Tags %he -ogic %ag -ibrar3 contains tags that are helpful with iterating through collections,conditional generation of output,and application flow.

/e have alread3 used the ActionForm,but we actuall3 have not en>o3ed the blessings of struts. -et1s program our action to return an appropriate error message called DAction rror1 when the user fails to login successfull3. Also re2arrange our view Gthe inde0.>spH to use the struts tag libraries to manipulate the ActionForm values,and displa3 the appropriate error message on error.

After adding the mentioned code,the e0ecute method of -oginAction becomes<

public ActionForward executeGAction(apping mapping,ActionForm form, SttpServlet!eBuest reBuest,SttpServlet!esponse responseH K User userForm 6 GUserHformJ String user 6 userForm.getUser%dGHJ String password 6 userForm.get*ass(ordGHJ ifGuser.e+ualsG7admin7H PP password.eBualsG7admin7HH return mapping.find&or(ardG7success7HJ Action(essages errors 6 ne( 'ction essagesGHJ Action(essage error 6 ne( 'ction essageG7login.failed7HJ errors.addG7error7,errorHJ sa!e$rrorsGreBuest,errorsHJ return mapping.find&or(ardG7failure7HJ L

+ote that we have created a new Action(essage with a ke3 Qlogin.failedR. %his ke3 must e0ist in the Application!esources.properties file. Add the following line in the resource file.

login.failed 6 %he supplied user name = password does not match

And the inde0.>sp becomes< 4TU page language67>ava7 page ncoding67#S,2::5V287T;

4TUtaglib prefi067html7 uri67=/ B2#+F=struts2html.tld7 T; 4F$,E%)' S%(- 'UB-#E 72==/@E==$%$ S%(- A.98 %ransitional== +7; 4html; 4head; 4title;/elcome to the registration case stud34=title; 4F22 4link rel67st3lesheet7 t3pe67te0t=css7 href67st3les.css7; 22; 4=head; 4bod3; 4html<errors=; 4html<form action67=login7; 4table border6797; 4tr; 4td;-ogin<4=td; 4td;4html<te0t propert367user#d7 =;4=td; 4=tr; 4tr; 4td;'assword<4=td; 4td;4html<te0t propert367password7 =;4=td; 4=tr; 4tr; 4td colspan67?7 align67center7;4html<submit value67-ogin7=;4=td; 4=tr; 4=table; 4=html<form; 4=bod3; 4=html;

As 3ou can see,we have declared a tag librar3 Dstruts2html.tld1. %his is the Stml tag librar3 we talked about a while ago. %he tag 4html<errors=; is responsible for displa3ing the message that we ma3 have saved in the reBuest or the session. /e can specif3 the scope as an attribute to this tag. +ow re2deplo3 the application and see 3ourself the difference. $id 3ou notice the field values after submitting the invalid values5 )esF %he values again appear in the field when the error message is displa3ed. %his is particularl3 important when submitting huge forms. And we have achieved all this without an3 e0tra programming.

'isting all &sers + Struts /terator 'ooping


(et us write a simple action and a view that displays the user list on our manageusers. sp. Dirst of all,create an #ction class named M(ist#ctionA and add the e)ecute method as following. public class $anage&sersAction e,tends Action 0 public #ctionDorward e)ecute.#ction,apping mapping,#ctionDorm form, HttpServlet8e>uest re>uest,HttpServlet8esponse response/ K ""Fet a list of users and save to the re>uest tryK (ist list 7 Bser,anager.getInstance./.list./L re>uest.set#ttribute.ElistE,list/L Ncatch.SC(E)ception s>le/ K #ction,essages errors 7 new #ction,essages./L

Action(essage error 6 ne( Action(essageG7error.generic7,sBle.get(essageGHHJ errors.addG7error7,errorHJ save rrorsGreBuest,errorsHJ L return mapping.findForwardG7success7HJ L L Add the following line in Application!esources.properties file. error.generic 6 An error prevented the operation. rror detail is<4br;./0

Add the following code in manageusers.>sp

4TU page language67>ava7 page ncoding67#S,2::5V287T; 4TUtaglib uri67=/ B2#+F=struts2html.tld7 prefi067html7 T; 4TUtaglib uri67=/ B2#+F=struts2logic.tld7 prefi067logic7 T; 4TUtaglib uri67=/ B2#+F=struts2bean.tld7 prefi067bean7 T;

4F$,E%)' S%(- 'UB-#E 72==/@E==$%$ S%(- A.98 %ransitional== +7; 4html; 4head; 4title;-isting all users4=title; 4=head; 4bod3; 4center;4h@;User -ist4=h@;4=center; 4html<errors=; 4logic<present name67list7; 4table border6797 cellspacing6797 cellpadding6797 align67center7 width67W9T7 st3le67border2 collapse<collapseJ7; 4tr bgcolor67XV:AFEE7; 4th;User #$4=th; 4th;First +ame4=th; 4th;-ast +ame4=th; 4th; mail4=th; 4=tr; 4Tboolean even 6 falseJ T; 4logic<iterate id67user7 name67list7; 4T even 6 FevenJ T; 4tr bgcolor674T6even57XBW$@F57<7X$Y 9F57 T;7; 4td; 4bean<write name67user7 propert367user#d7 =; 4=td; 4td; 4bean<write name67user7 propert367first+ame7 =; 4=td; 4td; 4bean<write name67user7 propert367last+ame7 =; 4=td; 4td; 4bean<write name67user7 propert367email7 =; 4=td; 4=tr; 4=logic<iterate; 4tr; 4td colspan67Y7 align67center7; 4a href67adduser.>sp7;Add +ew User4=a; 4=td; 4=tr; 4=table; 4=logic<present; 4=bod3; 4=html;

+ote that in this >sp,we have not performed an3 loop and still we are iterating over the list. Also note the separation of view from the model GdataH.

+ow /e need to update the Dsuccess1 forward in struts2config.0ml to forward to manageusers.do instead of manageusers.>sp. Also we need to add the manageusers action entr3 in the struts2config.0ml. +ow the 4action2mappings; looks like this. 4action2mappings ; 4action name67loginForm7 path67=login7 scope67reBuest7 t3pe67com.visualbuilder.struts.action.-oginAction7 validate67false7; 4forward name67failure7 path67=inde0.>sp7 =; 4forward name67success7 path67=manageusers.do7 =; 4=action; 4action path67=manageusers7 t3pe67com.visualbuilder.struts.action.(anageUsersAction7 ; 4forward name67success7 path67=manageusers.>sp7 =; 4=action; 4=action2mappings; ,n redeplo3ing and running the application,3ou should be able to see a list of users on successful login. )ou don1t have an3 data in the database right now,so 3ou might be viewing a page with onl3 one link QAdd +ew UserR but if 3ou add few records manuall3,3ou will see the list of users. %he variable even is used to indicate if the current row is even or odd to change the row background.

Add &ser Action + New Struts Action Class


Oow itAs time to add a new user to the database. (etAs write an action first that can save a user in the database. Create a new #ction class M#ddBser#ctionA and add the following code in its e)ecute method.

User user 6 GUserH formJ tryK User(anager.get%nstanceGH.sa!eUserGuserHJ LcatchGSN- 0ception sBleH K Action(essages errors 6 ne( 'ction essagesGHJ Action(essage error 6 ne( 'ction essageG7error.generic7,sBle.get essageGHHJ errors.addG7error7,errorHJ sa!e$rrorsGreBuest,errorsHJ L return mapping.find&or(ardG7success7HJ Eonfigure this action in the struts2config.0ml as given below.

4action attribute67loginForm7 name67loginForm7 path67=adduser7 scope67reBuest7 t3pe67com.visualbuilder.struts.action.AddUserAction7 validate67false7 ; 4forward name67success7 path67=manageusers.do7 =; 4=action;

+ote that we have associated the same form bean that we did when writing the -oginAction.

Add &ser 1iew


Oow it is the time to write a view component for our #ddBser#ction. Create a sp page Madduser. spA with the following code.

<%@ page language="java" pageEncoding="ISO-8859-1"%> <%@ taglib u i="!"E#-I$%!St ut&-'t(l)tld" p e*i+="'t(l" %>

<,-O./01E 2/34 15#4I. "-!!"6.!!-/- 2/34 7)81 / an&itional!!E$"> <'t(l9't(l lang="t ue"> <'ead> <'t(l9ba&e !> <title>:dd ne; u&e <!title> <!'ead> <bod<> <cente ><'6>:dd $e; 5&e <!'6><!cente > <.E$/E=><'t(l9e o &!><!.E$/E=>

<'t(l9*o ( action="!addu&e " (et'od="po&t"> <table bo de ="8" align="cente "> <t > <td>5&e I-9<!td>

<td><'t(l9te+t p ope t<="u&e Id" !><!td> <!t > <t > <td>%i &t $a(e9<!td> <td><'t(l9te+t p ope t<="*i &t$a(e" !><!td> <!t > <t > <td>4a&t $a(e9<!td> <td><'t(l9te+t p ope t<="la&t$a(e" !><!td> <!t > <t >

<td>:ge9<!td> <td><'t(l9te+t p ope t<="age" !><!td> <!t > <t > <td>E(ail9<!td> <td><'t(l9te+t p ope t<="e(ail" !><!td> <!t > <t > <td col&pan=">" align="cente "><'t(l9&ub(it !><!td> <!t > <!table> <!'t(l9*o (> <!bod<> <!'t(l9't(l>

8un the application,login as admin"admin and clic+ on #dd Oew Bser lin+ at the bottom of the page. Pou will find a form. Enter the appropriate values,and clic+ on submit button. Pou will again be redirected to the page showing the list of users and notice that the new user has been added to the list.

1alidating Struts *orm .ean


%ry to create a user with invalid values. Dor e)ample an invalid email address that does not follow email addresses rules. Pou will see that the system does not chec+ the validity of the data and the user still gets inserted into the database.

%o solve this issue,we need to validate the data before inserting into the database or perform an3 operation on the data. /e have two options to do this.

8. 'erform the validation in action class and return to failure if the validation fails.

?. 'erform validation in form bean.

%he first option is not feasible because one form bean ma3 be used in man3 actions. So we will need to perform validation in all actions where this form bean is used. %he better choice is to perform validation in form bean.

Struts framework provides validation facilit3 for form beans. #f we need to perform validation on a form bean,we need to override validate method in our ActionForm class. %he validate method returns an instance of Action rrors. /e can return Action rrors instance with appropriate Action rror ob>ect if the validation fails,or simpl3 return empt3 Action rrors instance to indicate that the validation has passed and the struts frame ma3 forward the reBuest to action class. -et1s add the validation to our User class.

public Action rrors validateG Action(apping mapping,SttpServlet!eBuest reBuest H K Action rrors errors 6 ne( Action rrorsGHJ ifG getUser#dGH.lengthGH48 H K errors.addG7name7,ne( Action(essageG7null.check7,7User #$7HHJ L

ifGget mailGH.lengthGH;9H KK ==)esF user entered email address. validate it ifGFget mailGH.matchesG7Z[a2IA2\][MMwMM.2]C[a2IA2\92V]U[a2IA2\92V][MMwMM.2]C[a2IA2\92V]MM. [a2IA2\][a2IA2\MM.]C[a2IA2\]^7HHK errors.addG7name7,ne( Action(essageG7email.invalid7HHJ L L return errorsJ L

Also we need to enable the validate6RtrueR and provide an input attribute in the action configuration in struts2config.0ml

4action attribute67loginForm7 name67loginForm7 path67=adduser7 scope67reBuest7 validate67true7 input67=adduser.>sp7 t3pe67com.visualbuilder.struts.action.AddUserAction7; 4forward name67success7 path67=manageusers.do7 =; 4=action;

Also we have used two error messages if the validation fails. Add these two ke3s in the

Application!esources.properties.

null.check 6 ./0 cannot be null or empt3 email.invalid 6 mail address does not pass the validation rules

+ow run the application and tr3 to create a user with empt3 User #$ or invalid email address. )ou will see the s3stem does not insert the user into the database.

Review of the Struts -utorial


'et2s review what you have learnt

#fter reading this tutorial you should have a good idea of how to write a Struts based web application using Eclipse and ,yEclipse platform.

In addition,we also covered a lot more concepts of what actually the ,yEclipse did and how to do them manually even if we donQt have a sophisticated I'E.

#fter completing this tutorial,with ust a few re>uired libraries,a Standard Java 'evelopment 2it and an appropriate installation of %omcat,you should be able to develop and deploy a struts based application.

%he approach used in this tutorial was using a QregistrationQ application as a case study. Oow it is the time to write a view component for our #ddBser#ction. Create a sp page Madduser. spA with the following code.

'DD US$1 2%$W


<%@ page language="java" pageEncoding="ISO-8859-1"%> <%@ taglib u i="!"E#-I$%!St ut&-'t(l)tld" p e*i+="'t(l" %>

<,-O./01E 2/34 15#4I. "-!!"6.!!-/- 2/34 7)81 / an&itional!!E$"> <'t(l9't(l lang="t ue"> <'ead> <'t(l9ba&e !> <title>:dd ne; u&e <!title> <!'ead> <bod<> <cente ><'6>:dd $e; 5&e <!'6><!cente > <.E$/E=><'t(l9e o &!><!.E$/E=>

<'t(l9*o ( action="!addu&e " (et'od="po&t"> <table bo de ="8" align="cente "> <t > <td>5&e I-9<!td>

<td><'t(l9te+t p ope t<="u&e Id" !><!td> <!t > <t > <td>%i &t $a(e9<!td> <td><'t(l9te+t p ope t<="*i &t$a(e" !><!td> <!t > <t >

<td>4a&t $a(e9<!td> <td><'t(l9te+t p ope t<="la&t$a(e" !><!td> <!t > <t > <td>:ge9<!td> <td><'t(l9te+t p ope t<="age" !><!td> <!t > <t > <td>E(ail9<!td> <td><'t(l9te+t p ope t<="e(ail" !><!td> <!t > <t > <td col&pan=">" align="cente "><'t(l9&ub(it !><!td> <!t > <!table> <!'t(l9*o (> <!bod<> <!'t(l9't(l>

8un the application,login as admin"admin and clic+ on #dd Oew Bser lin+ at the bottom of the page. Pou will find a form. Enter the appropriate values,and clic+ on submit button. Pou will again be redirected to the page showing the list of users and notice that the new user has been added to the list.

1alidating Struts *orm .ean -ry to create a user with invalid values% *or e,ample an invalid email address that does not follow email addresses rules% 3ou will see that the system does not chec# the validity of the data and the user still gets inserted into the database%

%o solve this issue,we need to validate the data before inserting into the database or perform an3 operation on the data. /e have two options to do this.

8. 'erform the validation in action class and return to failure if the validation fails.

?. 'erform validation in form bean.

%he first option is not feasible because one form bean ma3 be used in man3 actions. So we will need to perform validation in all actions where this form bean is used. %he better choice is to perform validation in form bean.

Struts framework provides validation facilit3 for form beans. #f we need to perform validation on a form bean,we need to override validate method in our ActionForm class. %he validate method returns an instance of Action rrors. /e can return Action rrors instance with appropriate Action rror ob>ect if the validation fails,or simpl3 return empt3 Action rrors instance to indicate that the validation has passed and the struts frame ma3 forward the reBuest to action class. -et1s add the validation to our User class.

public Action rrors validateG Action(apping mapping,SttpServlet!eBuest reBuest H K

Action rrors errors 6 ne( Action rrorsGHJ ifG getUser#dGH.lengthGH48 H K errors.addG7name7,ne( Action(essageG7null.check7,7User #$7HHJ L ifGget mailGH.lengthGH;9H KK ==)esF user entered email address. validate it ifGFget mailGH.matchesG7Z[a2IA2\][MMwMM.2]C[a2IA2\92V]U[a2IA2\92V][MMwMM.2]C[a2IA2\92V]MM. [a2IA2\][a2IA2\MM.]C[a2IA2\]^7HHK errors.addG7name7,ne( Action(essageG7email.invalid7HHJ L L return errorsJ L

Also we need to enable the validate6RtrueR and provide an input attribute in the action configuration in struts2config.0ml

4action attribute67loginForm7 name67loginForm7 path67=adduser7 scope67reBuest7 validate67true7 input67=adduser.>sp7

t3pe67com.visualbuilder.struts.action.AddUserAction7; 4forward name67success7 path67=manageusers.do7 =; 4=action;

Also we have used two error messages if the validation fails. Add these two ke3s in the Application!esources.properties.

null.check 6 ./0 cannot be null or empt3 email.invalid 6 mail address does not pass the validation rules

+ow run the application and tr3 to create a user with empt3 User #$ or invalid email address. )ou will see the s3stem does not insert the user into the database. Why do we need Struts? 0lt%oug% a d"namic web application can be de#eloped using 1'2 and 'er#let tec%nolog"+ t%ere are man" problems

3 Tig%tl" coupled classes - one c%ange affects ot%er classes 3 Business logic resides in bot% presentation and data access la"er 'o if t%ere is a c%ange in a business rule+ needs multiple places to find t%e business rules 0lso promotes duplicate business rules 3 4ata sources are difficult to c%ange as data access met%ods ma" be used in t%e presentation la"er 3 Logic to determine w%at to do next is across t%e application+no centralized decision

To sol#e t%ese problems+we need a mec%anism t%at can separate t%e presentation

la"er of a web application from business logic Luc5il" we %a#e MVC and we %a#e 'truts MVC is a design pattern 6best practice met%od7 t%at separates t%e application design into t%ere main parts/

Model+ View and Controller

3 Model - data and logic 6business logic met%ods7 3 View - output displa"ed to t%e user 3 Controller - ta5es t%e input from t%e user and passes it to t%e rele#ant model T%e model returns and based on t%e result+ t%e controller decides w%ic% #iew 6page7 to s%ow t%e user 0dvantages of Struts 'truts offers man" ad#antages to t%e application programmer w%ile reducing t%e de#elopment time and ma5ing t%e manageabilit" of t%e application easier Here are few 5e" ad#antages of using 'truts instead of managing t%e e#er" la"er of t%e web application "ourself

Centralized File-Based Configuration

.at%er t%an %ard coding information into 8a#a programs+man" 'truts #alues are represented in 9ML or propert" files T%is loose coupling means t%at man" c%anges can be made wit%out modif"ing or recompiling 1a#a code+and t%at w%olesale c%anges can be made b" editing a single file T%is approac% also lets 1a#a and (eb de#elopers focus on t%eir specific tas5s 6implementing business logic+presenting certain #alues to clients+etc 7 wit%out needing to 5now about t%e o#erall s"stem la"out

Form Beans

:n 1'2+"ou can use propert";,3, wit% 8sp/set2ropert" to automaticall" populate a

1a#aBean component based on incoming re$uest parameters !nfortunatel"+%owe#er+in t%e standard 02: t%is capabilit" is una#ailable to ser#lets+e#en t%oug% wit% MVC it is reall" ser#lets+not 1'2 pages+t%at s%ould usuall" be t%e target of form submissions 0pac%e 'truts extends t%is capabilit" to 1a#a code and adds in se#eral useful utilities+all of w%ic% ser#e to greatl" simplif" t%e processing of re$uest parameters

Bean Tags

0pac%e 'truts pro#ides a set of custom 1'2 tags 6bean/write+in particular7 t%at let "ou easil" output t%e properties of 1a#aBeans components Basicall"+t%ese are concise and powerful #ariations of t%e standard 8sp/useBean and 8sp/get2ropert" tags

HTML tags

0pac%e 'truts pro#ides a set of custom 1'2 tags to create HTML forms t%at are associated wit% 1a#aBeans components T%is bean<form association ser#es two useful purposes/

:t lets "ou get initial form-field #alues from 1a#a ob8ects

:t lets "ou redispla" forms wit% some or all pre#iousl" entered #alues intact

Form Field Validation

0pac%e 'truts %as built-in capabilities for c%ec5ing t%at form #alues are in t%e re$uired format :f #alues are missing or in an improper format+t%e form can be automaticall"

redispla"ed wit% error messages and wit% t%e pre#iousl" entered #alues maintained T%is #alidation can be performed on t%e ser#er 6in 1a#a7+or bot% on t%e ser#er and on t%e client 6in 1a#a'cript7

'truts = > is currentl" in beta p%ase and contains t%e existing 'truts features plus all t%e features of (eb(or5s framewor5 DispatchAction -he ma or component in the Struts based application is the Action class% Action class only defines the ne,t steps and logic processing for the application% -he execute() method is called by the framewor# for the processing% All the business logic and all the flow is derived from the execute() method in the Action class% -here is a special Action class which will permit the user to have more than one method which can be called by the framewor# and not ust the execute() method% -his class is DispatchAction% -he class is helpful to have all the methods related to a single &/ page in one Action class and developers need not to implement the logics in different classes% -he method to be called on Action is decided with the parameter attribute in the 4action5 tag of strutsconfig.xml. -he code for the mapping is given below%

4action path67=dispatchAction 0ample7 t3pe67com.visualbuilder.$ispatchAction 0ample7 parameter34method4 name67inputForm7 input67=inde0.>sp7 =;

Note:-The above mapping will check the method parameter and call the method with the name coming in the parameter. dd the !ollowing ke"s in the messageresources.properties !ile under #$%&N'(classes

error.unspecified6 Unspecified Ealled. error.add6 Add Ealled. error.delete6 delete Ealled. error.view6 _iew Ealled. Example For DispatchAction )*+ Struts-con!ig.,ml !ile

450ml version678.97 encoding67#S,2::5V287 5;

4F$,E%)' struts2config 'UB-#E 72==Apache Software Foundation==$%$ Struts Eonfiguration 8.@== +7 7http<==struts.apache.org=dtds=struts2config"8"@.dtd7; 4struts2config; 4F22 666666666666666666666666666666666666666666666666 Form Bean $efinitions 22; 4form2beans; 4form2bean name67inputForm7 t3pe67com.visualbuilder.#nputForm7 =; 4=form2beans; 4F22 66666666666666666666666666666666666666666 .lobal 0ception $efinitions 22; 4global2e0ceptions;4=global2e0ceptions; 4F22 6666666666666666666666666666666666666666666 .lobal Forward $efinitions 22; 4global2forwards;4=global2forwards; 4F22 6666666666666666666666666666666666666666666 Action (apping $efinitions 22; 4action2mappings; 4action path67=dispatchAction 0ample7 t3pe67com.visualbuilder.$ispatchAction 0ample7 parameter67method7 name67inputForm7 input67=inde0.>sp7 =; 4=action2mappings; 4F22 6666666666666666666666666666666666666666 (essage !esources $efinitions 22; 4message2resources parameter67(essage!esources7 =; 4=struts2config; 678 Action*orm Class

pac5age com.visualbuilderJ

import org.apache.struts.action.ActionFormJ

public class #nputForm e0tends ActionFormK L 678 'ctionClass Note:- Now all the action classes must imherit the org.apache.struts.action.-ispatch ction .lass and not the org.apache.struts.action. ction .lass.

pac5age com.visualbuilderJ

import >ava0.servlet.http.SttpServlet!eBuestJ import >ava0.servlet.http.SttpServlet!esponseJ

import org.apache.struts.action.Action(essagesJ import org.apache.struts.action.ActionFormJ import org.apache.struts.action.ActionForwardJ import org.apache.struts.action.Action(appingJ

import org.apache.struts.action.Action(essageJ import org.apache.struts.action.Action(essagesJ import org.apache.struts.actions.$ispatchActionJ

public class $ispatchAction 0ample extends $ispatchActionK

protected ActionForward unspecifiedGAction(apping mapping, ActionForm form, SttpServlet!eBuest reBuest, SttpServlet!esponse responseH thro(s 0ception K Action(essages message 6 new Action(essagesGHJ message.addG7unspecified7,new Action(essageG7error.unspecified7HHJ save(essagesGreBuest, messageHJ return mapping.get#nputForwardGHJ L

public ActionForward viewGAction(apping mapping, ActionForm form, SttpServlet!eBuest reBuest, SttpServlet!esponse responseH throws 0ceptionK Action(essages message 6 new Action(essagesGHJ message.addG7unspecified7,new Action(essageG7error.view7HHJ save(essagesGreBuest, messageHJ return mapping.get#nputForwardGHJ L public ActionForward addGAction(apping mapping, ActionForm form, SttpServlet!eBuest reBuest, SttpServlet!esponse responseH throws 0ceptionK Action(essages message 6 new Action(essagesGHJ message.addG7unspecified7,new Action(essageG7error.add7HHJ

save(essagesGreBuest, messageHJ return mapping.get#nputForwardGHJ L public ActionForward deleteGAction(apping mapping, ActionForm form, SttpServlet!eBuest reBuest, SttpServlet!esponse responseH throws 0ception K Action(essages message 6 new Action(essagesGHJ message.addG7unspecified7,new Action(essageG7error.delete7HHJ save(essagesGreBuest, messageHJ return mapping.get#nputForwardGHJ L

(4) JSP Page

4TU taglib uri67http<==struts.apache.org=tags2bean7 prefi067bean7 T; 4TU taglib uri67http<==struts.apache.org=tags2html7 prefi067html7 T; 4TU taglib uri67http<==struts.apache.org=tags2logic7 prefi067logic7 T; 4F$,E%)' S%(- 'UB-#E 72==/@E==$%$ S%(- A.98 %ransitional== +7; 4html<html; 4logic<messages'resent; 4html<messages id67msg7; 4p;4strong;4font color67red7;4bean<write name67msg7 =;4=font;4=strong;4=p; 4=html<messages; 4=logic<messages'resent;

4logic<messages'resent message67true7; 4html<messages message67true7 id67msg7; 4p;4strong;4bean<write name67msg7 =;4=strong;4=p; 4=html<messages; 4=logic<messages'resent; 4html<form action67=dispatchAction 0ample.do5method6add7 method67post7; 4html<submit;Submit for add4=html<submit; 4=html<form; 4html<form action67=dispatchAction 0ample.do5method6view7 method67post7; 4html<submit;Submit for view4=html<submit; 4=html<form; 4html<form action67=dispatchAction 0ample.do5method6delete7 method67post7; 4html<submit;Submit for delete4=html<submit; 4=html<form; 4html<form action67=dispatchAction 0ample.do7 method67post7; 4html<submit;Submit for unspecified4=html<submit; 4=html<form; 4=html<html; 9utput:-

%he following buttons will be displa3ed and on clicking the buttons the te0t 7delete called7 changes /ntroduction to DynaAction*orm /n struts! every form control need to have one Action*orm class property

and getter9setter method for it% DynaActionForm will replace the Action*orm with the simple ,ml mappings so that the ava form class can be eliminated and thus helps in developing the application more :uic#ly% -he advantages of using the DynaAction*orm are as follows;+

8. +o ActionForm is reBuired. ?. !eplace the propert3 mapping with the simple 0ml file so that if an3 propert3 is to add and remove then there is no need to compile the >ava class again.

%he mapping is to be done in the struts2config.0ml file in the 4form2bean; tag for all the form properties.

4form2bean name67inputForm7 t3pe67org.apache.struts.action.$3naActionForm7 ; 4form2propert3 name67name7 t3pe67>ava.lang.String7=; 4form2propert3 name67email7 t3pe67>ava.lang.String7 =; 4=form2bean;

Data Types <2 %he t3pes supported b3 -"na ction'orm include<

>ava.math.Big$ecimal >ava.math.Big#nteger boolean and >ava.lang.Boolean b3te and >ava.lang.B3te char and >ava.lang.Eharacter >ava.lang.Elass double and >ava.lang.$ouble float and >ava.lang.Float int and >ava.lang.#nteger long and >ava.lang.-ong short and >ava.lang.Short >ava.lang.String >ava.sBl.$ate >ava.sBl.%ime >ava.sBl.%imestamp

Example For DynaActionForm :-

6;8 Struts-config.xml file

450ml version678.97 encoding67#S,2::5V287 5;

4F$,E%)' struts2config 'UB-#E 72==Apache Software Foundation==$%$ Struts Eonfiguration 8.@== +7 7http<==struts.apache.org=dtds=struts2config"8"@.dtd7; 4struts2config; 4F22 666666666666666666666666666666666666666666666666 Form Bean $efinitions 22; 4form2beans; 4form2bean name67inputForm7 t3pe67org.apache.struts.action.$3naActionForm7 ; 4form2propert3 name67name7 t3pe67>ava.lang.String7=; 4form2propert3 name67email7 t3pe67>ava.lang.String7 =; 4=form2bean; 4=form2beans; 4F22 66666666666666666666666666666666666666666 .lobal 0ception $efinitions 22; 4global2e0ceptions;4=global2e0ceptions; 4F22 6666666666666666666666666666666666666666666 .lobal Forward $efinitions 22; 4global2forwards;4=global2forwards; 4F22 6666666666666666666666666666666666666666666 Action (apping $efinitions 22; 4action2mappings; 4action path67=d3naAction 0ample7 t3pe67com.visualbuilder.$3naActionForm 0ample7 name67inputForm7 input67=inde0.>sp7 =; 4=action2mappings; 4F22 6666666666666666666666666666666666666666 (essage !esources $efinitions 22; 4message2resources parameter67(essage!esources7 =; 4=struts2config; 2) ActionClass

pac5age com.visualbuilderJ

import >ava0.servlet.http.SttpServlet!eBuestJ import >ava0.servlet.http.SttpServlet!esponseJ

import org.apache.struts.action.Action(essagesJ import org.apache.struts.action.ActionFormJ import org.apache.struts.action.ActionForwardJ import org.apache.struts.action.Action(appingJ import org.apache.struts.action.Action(essageJ import org.apache.struts.action.Action(essagesJ import org.apache.struts.actions.ActionJ import org.apache.struts.action.$3naActionFormJ

public class $3naActionForm 0ample extends ActionK public ActionForward e0ecuteGAction(apping mapping, ActionForm form, SttpServlet!eBuest reBuest, SttpServlet!esponse responseH throws 0ception K $3naActionForm inputForm 6 G$3naActionFormHformJ

==Ereate ob>ect of Action(esssages Action(essages errors 6 new Action(essagesGHJ ==Eheck and collect errors ifGGGStringHinputForm.getG7name7HH.eBualsG77HH K errors.addG7name7,new Action(essageG7error.name.reBuired7HHJ L ifGGGStringHinputForm.getG7email7HH.eBualsG77HH K errors.addG7email7,new Action(essageG7error.email.reBuired7HHJ L ==Saves the error save rrorsGreBuest,errorsHJ return mapping.get#nputForwardGHJ L

(3) JSP Page

4TU taglib uri67http<==struts.apache.org=tags2bean7 prefi067bean7 T; 4TU taglib uri67http<==struts.apache.org=tags2html7 prefi067html7 T; 4TU taglib uri67http<==struts.apache.org=tags2logic7 prefi067logic7 T; 4F$,E%)' S%(- 'UB-#E 72==/@E==$%$ S%(- A.98 %ransitional== +7; 4html<html; 4logic<messages'resent; 4html<messages id67msg7; 4p;4strong;4font color67red7;4bean<write name67msg7 =;4=font;4=strong;4=p; 4=html<messages; 4=logic<messages'resent; 4logic<messages'resent message67true7; 4html<messages message67true7 id67msg7; 4p;4strong;4bean<write name67msg7 =;4=strong;4=p; 4=html<messages; 4=logic<messages'resent; 4html<form action67=d3naAction 0ample.do7 method67post7; 4table; 4tr;4td; nter the name <2 4=td;4td;4html<te0t propert367name7=; 4=td;4=tr; 4tr;4td; nter the mail<2 4=td;4td;4html<te0t propert367email7=;4=td;4=tr; 4=table; 4html<submit;Submit4=html<submit; 4=html<form; 4=html<html; 9utput:-

%he following will be the output of the application.

Struts solution to Duplicate &orm Submission 6To5en mechanism8


-he problem of duplicate form submission arises when a user clic#s the Submit button more than once before the response is sent bac# or when a client accesses a view by returning to a previously boo# mar#ed page% -he struts provide the save-o#en68 and is-o#en1alid68 to chec# whether the re:uest is already submitted or not%

%he method is_alid%okenGH return true if there is a transaction to&en stored in the user9s current session, and the value submitted as a re2uest parameter with this action matches it. 'eturns false under any of the following circumstances$ +o session associated with this reBuest +o transaction token saved in the session +o transaction token included as a reBuest parameter %he included transaction token value does not match the transaction token in the user`s session

Note:- &! the ction class is changed as per the !ollowing code then it will validate against the duplicate !orm submission.

public ActionForward e0ecuteGAction(apping mapping, ActionForm form, SttpServlet!eBuest reBuest, SttpServlet!esponse responseH thro(s 0ception K Action(essages errors 6 new Action(essagesGHJ if 6<isTo5en2alid6re+uest88 . errors.addG7error.duplicatereBuest7, new Action(essageG7error.duplicatereBuest7HHJ L resetTo5en6re+uest8= if GFerrors.is mpt3GHH K save rrorsGreBuest, errorsHJ save%okenGreBuestHJ

return Gmapping.get#nputForwardGHHJ L return mapping.findForwardG7success7HJ L

Output

Note:- The output changes as !ollows :/ntroduction to 1alidation framewor# We have seen the validate() method in Action*orm is used to validate the form properties! which are entered by the user on the <S= pages% .ut each and every validation has to be implemented using the ava code %/n case the application has similar #ind of the validations for all the forms then the redundancy is increased% Also updating validation routines are very cumbersome% -he 1alidator framewor# was developed by David Winterfeldt as third+party add+on to Struts% -he advantages of the 1alidation *ramewor#;+

8. #t is &(- based framework so it is ver3 eas3 to modif3 the validation routines in the 0ml files as compared to the Java files. ?. All the validations are at the same place so the reusabilit3 of the validations are ver3 eas3. @. )ou can implement the validations in the Elient Side as well as Server side with a little coding effort. A. %he validation framework is browser independent and needs no e0tra effort for the different browser in coding.

The Components of 2alidation &rame(or5.

%he basic components of the _alidation Framework is as follows <2

2alidations.xml :- %his is the basic class consist of all the validation rules applied for a form bean. 2alidator-rules.xml:- %his is the file which contains all the validation rules which can be used to validate the form bean data. A default file is also provided b3 the Struts framework which is in =org=apache=struts=validator= path and contains the commonl3 used rules, *lugin mapping in Struts-Config.xml:- %he mapping of the plugin is to be there in the struts2 config file so that Struts controller class will configure the plugin so that it can be used in the application.

Simple Example For ali!ations <2

Note :- #e are using the de!ault validator-rules.,ml !or this e,ample.

6;8 2alidations.xml file

450ml version678.97 encoding67#S,2::5V287 5; 4F$,E%)' form2validation 'UB-#E 72==Apache Software Foundation==$%$ Eommons _alidator !ules Eonfiguration 8.@.9== +7 7http<==>akarta.apache.org=commons=dtds=validator"8"@"9.dtd7;

4form2validation; 4formset; 4form name67inputForm7; 4field propert367name7 depends67reBuired7; 4arg ke367inputForm.name.reBuired7 =; 4=field; 4field propert367phone7 depends67reBuired,mask7; 4arg ke367inputForm.phone.reBuired7 position6797 =; 4arg ke367inputForm.phone.format7 position6787 =; 4var;

4var2name;mask4=var2name; 4var2value;Z[92V]C^4=var2value; 4=var; 4=field; 4field propert367email7 depends67reBuired,email7; 4arg ke367inputForm.email.reBuired7 position6797 =; 4arg ke367inputForm.email.format7 position6787 =; 4=field; 4=form; 4=formset; 4=form2validation; (") Struts#con$ig%xml $ile

450ml version678.97 encoding67#S,2::5V287 5;

4F$,E%)' struts2config 'UB-#E 72==Apache Software Foundation==$%$ Struts Eonfiguration 8.@== +7 7http<==struts.apache.org=dtds=struts2config"8"@.dtd7; 4struts2config; 4F22 666666666666666666666666666666666666666666666666 Form Bean $efinitions 22; 4form2beans; 4form2bean name67inputForm7 t3pe67com.visualbuilder.#nputForm7 =; 4=form2beans; 4F22 66666666666666666666666666666666666666666 .lobal 0ception $efinitions 22; 4global2e0ceptions;4=global2e0ceptions; 4F22 6666666666666666666666666666666666666666666 .lobal Forward $efinitions 22; 4global2forwards;4=global2forwards; 4F22 6666666666666666666666666666666666666666666 Action (apping $efinitions 22; 4action2mappings; 4action path67=validate7 t3pe67com.visualbuilder._alidateAction7 validate67true7 name67inputForm7 input67=inde0.>sp7 =; 4=action2mappings; 4F22 6666666666666666666666666666666666666666 (essage !esources $efinitions 22; 4message2resources parameter67(essage!esources7 =;

4F22 666666666666666666666666666666666666666666666666666 _alidator plugin 22;

4plug2in class+ame67org.apache.struts.validator._alidator'lug#n7; 4set2propert3 propert367pathnames7 value67=org=apache=struts=validator=validator2rules.0ml, =/ B2#+F=validation.0ml7=; 4=plug2in; 4=struts2config; E,ample Continued 1alidation *ramewor# (3) alidator Form file

pac5age com.visualbuilderJ

import org.apache.struts.validator._alidatorFormJ

public class #nputForm extends _alidatorForm K String nameJ String emailJ String phoneJ public String get mailGH K return emailJ L public void set mailGString emailH K this.email 6 emailJ L public String get+ameGH K return nameJ

L public void set+ameGString nameH K this.name 6 nameJ L public String get'honeGH K return phoneJ L public void set'honeGString phoneH K this.phone 6 phoneJ L L

(3) ali!ator Action $ile

pac5age com.visualbuilderJ import >ava0.servlet.http.SttpServlet!eBuestJ import >ava0.servlet.http.SttpServlet!esponseJ

import org.apache.struts.action.ActionJ import org.apache.struts.action.ActionFormJ import org.apache.struts.action.ActionForwardJ import org.apache.struts.action.Action(appingJ

public class _alidateAction extends Action K public ActionForward e0ecuteGAction(apping mapping, ActionForm form, SttpServlet!eBuest reBuest, SttpServlet!esponse responseHthro(s 0ception K return mapping.get#nputForwardGHJ L

(4) JSP $ile

4TU taglib uri67http<==struts.apache.org=tags2bean7 prefi067bean7T; 4TU taglib uri67http<==struts.apache.org=tags2html7 prefi067html7T; 4TU taglib uri67http<==struts.apache.org=tags2logic7 prefi067logic7T; 4F$,E%)' S%(- 'UB-#E 72==/@E==$%$ S%(- A.98 %ransitional== +7; 4html<html; 4html<form action67=validate.do7 method67post7; 4table; 4tr; 4td colspan67?7; 4logic<messages'resent; 4html<messages id67msg7; 4p; 4strong;4font color67red7;4bean<write name67msg7 =;4=font;4=strong; 4=p; 4=html<messages; 4=logic<messages'resent; 4=td; 4=tr; 4tr; 4td colspan67?7; 4logic<messages'resent message67true7; 4html<messages message67true7 id67msg7; 4p; 4strong;4bean<write name67msg7 =;4=strong; 4=p; 4=html<messages; 4=logic<messages'resent; 4=td; 4=tr; 4tr;4td; nter the name4=td; 4td;4html<te0t propert367name7 =;4=td;4=tr; 4tr;4td; nter the 'hone4=td; 4td; 4html<te0t propert367phone7 =;4=td;4=tr; 4tr;4td; nter the mail4=td; 4td;4html<te0t propert367email7 =;4=td;4=tr; 4=table;4html<submit;Submit 4=html<submit; 4=html<form;

4=html<html; Client Side 1alidation Enabling Client Side 1alidation

%he validation framework also gives the fle0ibilit3 to use it on Elient Side. %he framework automaticall3 generates the browser specific JavaScript and validate the data onl3 at the client side. Although it has some disadvantages as the client side validations can be turn off b3 browser settings and also it is visible to the client. #t also has some advantages like it reduces the network congestion as the form is not submitted with the wrong data again and again and onl3 the validated data is submitted. #t is also advisable if 3ou are using the client side validation scripts then also use the validation at the server side so that two wa3 check will maintain the data integrit3 full3.

%he following code if placed in the >sp file will generate the >ava script at the client side for the specified form based on the validations.0ml file.

4html<>avascript form+ame67inputForm7=;

%o call the validation routines call the onSubmit/validate000)this+ whereas 000 stands for the form name. #n our case it is inputForm. So the code is as follows <2

4html<form action67=validate.do7 method67post7 onSubmit67validate#nputFormGthisHJ7; /ntroduction to Standard 1alidator+Rules%,ml T%e :nbuilt #alidation in t%e Validator-.ules xml

T%e table will describe t%e #alidator rules a#ailable wit% t%e #alidator-rules xml file pro#ided b" t%e 'truts Communit"

1ule b3te

Description Ehecks value contained b3 field can be converted to >ava b3te t3pe Ehecks value contained b3 field can be converted to >ava b3te t3pe using the number formatting convention for the current locale. Ehecks for the valid card number supplied b3 ma>or companies like _#SA, (AS% !EA!$ etc. Ehecks value contained b3 field can be converted to >ava.util.$ate.

b3te-ocale

creditEard

date

double

Ehecks value contained b3 field can be converted to double primitive t3pe. Ehecks value contained b3 field can be fitted into the primitive double range or not. Ehecks value contained b3 field can be properl3 formatted email address or not. Ehecks value contained b3 field can be converted to float primitive t3pe. Ehecks value contained b3 field can be converted to >ava float t3pe using the number formatting convention for the current locale. Ehecks value contained b3 field can be fitted into the primitive float range or not. Ehecks value contained b3 field can be converted to int primitive t3pe. Ehecks value contained b3 field can be converted to >ava int t3pe using the number formatting convention for the current locale. Ehecks value contained b3 field can be fitted into the primitive int range or not. Ehecks value contained b3 field can be converted to long primitive t3pe.

double!ange

email

float

float-ocale

float!ange

integer

integer-ocale

int!ange

long

long-ocale

Ehecks value contained b3 field can be converted to >ava long t3pe using the number formatting convention for the current locale. Ehecks value contained b3 field can be fitted into the primitive long range or not. _alidate the value with the given !egular 0pression. _alidate the ma0imum length should not be e0ceeded of the value with the value given in the propert3. _alidate the minimum length should not be e0ceeded of the value with the value given in the propert3. Ehecks whether the value contain b3 the field is other than the whitespace.

long!ange

mask

ma0-ength

min-ength

reBuired

short

Ehecks value contained b3 field can be converted to >ava short t3pe Ehecks value contained b3 field can be converted to >ava short t3pe using the number formatting convention for the current locale. Ehecks the given value is properl3 formatted U!- or not.

short-ocale

url

validwhen

$etermine the field is validated or not based on the specified test condition.

Stan!ar! &ali!ator#rules%xml $ile

%he following is given the standard validator2rules.0ml file. #n the ne0t section 3ou will learn how to create 3our own validator rules. %ill the time we are using the same validator2rules.0ml which is the standard file comes with standard struts framework. 4F22 -icensed to the Apache Software Foundation GASFH under one or more contributor license agreements.

See the +,%#E file distributed with this work for additional information regarding cop3right ownership. %he ASF licenses this file to )ou under the Apache -icense, _ersion ?.9 Gthe 7-icense7HJ 3ou ma3 not use this file e0cept in compliance with the -icense. )ou ma3 obtain a cop3 of the -icense at http<==www.apache.org=licenses=-#E +S 2?.9

Unless reBuired b3 applicable law or agreed to in writing, software distributed under the -icense is distributed on an 7AS #S7 BAS#S, /#%S,U% /A!!A+%# S ,! E,+$#%#,+S ,F A+) *#+$, either e0press or implied. See the -icense for the specific language governing permissions and limitations under the -icense. 22; 4F$,E%)' form2validation 'UB-#E 72==Apache Software Foundation==$%$ Eommons _alidator !ules Eonfiguration 8.@.9== +7 7http<==>akarta.apache.org=commons=dtds=validator"8"@"9.dtd7; 4F22 ^#d< validator2rules.0ml A:8:@@ ?99Y28?29@ 8W<@?<5?\ niallp ^

%his file contains the default Struts _alidator pluggable validator definitions. #t is contained in struts2 core.>ar, and should be referenced in the struts2config.0ml under the plug2in element for the _alidator'lug#n.

4plug2in class+ame67org.apache.struts.validator._alidator'lug#n7; 4set2propert3 propert367pathnames7 value67=org=apache=struts=validator=validator2rules.0ml, =/ B2 #+F=validation.0ml7=; 4=plug2in;

%hese are the default error messages associated with each validator defined in this file. %he3 should be added to 3our pro>ects Application!esources.properties file or 3ou can associate new ones b3 modif3ing the pluggable validators msg attributes in this file.

X Struts _alidator rror (essages

errors.reBuired6K9L is reBuired. errors.minlength6K9L can not be less than K8L characters. errors.ma0length6K9L can not be greater than K8L characters. errors.invalid6K9L is invalid.

errors.b3te6K9L must be a b3te. errors.short6K9L must be a short. errors.integer6K9L must be an integer. errors.long6K9L must be a long. errors.float6K9L must be a float. errors.double6K9L must be a double.

errors.date6K9L is not a date. errors.range6K9L is not in the range K8L through K?L. errors.creditcard6K9L is an invalid credit card number. errors.email6K9L is an invalid e2mail address.

+ote< Starting in Struts 8.?.9 the default >avascript definitions have been consolidated to commons2 validator. %he default can be overridden b3 suppl3ing a 4>avascript; element with a E$A%A section, >ust as in struts 8.8.

22;

4form2validation;

4global; 4validator name67reBuired7 classname67org.apache.struts.validator.FieldEhecks7 method67validate!eBuired7 method'arams67>ava.lang.,b>ect, org.apache.commons.validator._alidatorAction, org.apache.commons.validator.Field, org.apache.struts.action.Action(essages, org.apache.commons.validator._alidator, >ava0.servlet.http.SttpServlet!eBuest7 msg67errors.reBuired7=;

4validator name67reBuiredif7 classname67org.apache.struts.validator.FieldEhecks7 method67validate!eBuired#f7 method'arams67>ava.lang.,b>ect, org.apache.commons.validator._alidatorAction, org.apache.commons.validator.Field, org.apache.struts.action.Action(essages, org.apache.commons.validator._alidator, >ava0.servlet.http.SttpServlet!eBuest7 msg67errors.reBuired7=;

4validator name67validwhen7 msg67errors.reBuired7 classname67org.apache.struts.validator.validwhen._alid/hen7 method67validate_alid/hen7 method'arams67>ava.lang.,b>ect, org.apache.commons.validator._alidatorAction, org.apache.commons.validator.Field, org.apache.struts.action.Action(essages, org.apache.commons.validator._alidator, >ava0.servlet.http.SttpServlet!eBuest7=; 4validator name67minlength7 classname67org.apache.struts.validator.FieldEhecks7 method67validate(in-ength7 method'arams67>ava.lang.,b>ect, org.apache.commons.validator._alidatorAction, org.apache.commons.validator.Field, org.apache.struts.action.Action(essages, org.apache.commons.validator._alidator, >ava0.servlet.http.SttpServlet!eBuest7 depends677 msg67errors.minlength7 >sFunction67org.apache.commons.validator.>avascript.validate(in-ength7=;

4validator name67ma0length7 classname67org.apache.struts.validator.FieldEhecks7 method67validate(a0-ength7 method'arams67>ava.lang.,b>ect, org.apache.commons.validator._alidatorAction, org.apache.commons.validator.Field, org.apache.struts.action.Action(essages, org.apache.commons.validator._alidator, >ava0.servlet.http.SttpServlet!eBuest7 depends677 msg67errors.ma0length7 >sFunction67org.apache.commons.validator.>avascript.validate(a0-ength7=; 4validator name67mask7 classname67org.apache.struts.validator.FieldEhecks7 method67validate(ask7 method'arams67>ava.lang.,b>ect, org.apache.commons.validator._alidatorAction, org.apache.commons.validator.Field, org.apache.struts.action.Action(essages, org.apache.commons.validator._alidator, >ava0.servlet.http.SttpServlet!eBuest7 depends677 msg67errors.invalid7=; 4validator name67b3te7

classname67org.apache.struts.validator.FieldEhecks7 method67validateB3te7 method'arams67>ava.lang.,b>ect, org.apache.commons.validator._alidatorAction, org.apache.commons.validator.Field, org.apache.struts.action.Action(essages, org.apache.commons.validator._alidator, >ava0.servlet.http.SttpServlet!eBuest7 depends677 msg67errors.b3te7 >sFunction+ame67B3te_alidations7=; 4validator name67short7 classname67org.apache.struts.validator.FieldEhecks7 method67validateShort7 method'arams67>ava.lang.,b>ect, org.apache.commons.validator._alidatorAction, org.apache.commons.validator.Field, org.apache.struts.action.Action(essages, org.apache.commons.validator._alidator, >ava0.servlet.http.SttpServlet!eBuest7 depends677 msg67errors.short7 >sFunction+ame67Short_alidations7=;

4validator name67integer7 classname67org.apache.struts.validator.FieldEhecks7 method67validate#nteger7 method'arams67>ava.lang.,b>ect, org.apache.commons.validator._alidatorAction, org.apache.commons.validator.Field, org.apache.struts.action.Action(essages, org.apache.commons.validator._alidator, >ava0.servlet.http.SttpServlet!eBuest7 depends677 msg67errors.integer7 >sFunction+ame67#nteger_alidations7=; 4validator name67long7 classname67org.apache.struts.validator.FieldEhecks7 method67validate-ong7 method'arams67>ava.lang.,b>ect, org.apache.commons.validator._alidatorAction, org.apache.commons.validator.Field, org.apache.struts.action.Action(essages, org.apache.commons.validator._alidator, >ava0.servlet.http.SttpServlet!eBuest7 depends677 msg67errors.long7=; 4validator name67float7

classname67org.apache.struts.validator.FieldEhecks7 method67validateFloat7 method'arams67>ava.lang.,b>ect, org.apache.commons.validator._alidatorAction, org.apache.commons.validator.Field, org.apache.struts.action.Action(essages, org.apache.commons.validator._alidator, >ava0.servlet.http.SttpServlet!eBuest7 depends677 msg67errors.float7 >sFunction+ame67Float_alidations7=;

4validator name67double7 classname67org.apache.struts.validator.FieldEhecks7 method67validate$ouble7 method'arams67>ava.lang.,b>ect, org.apache.commons.validator._alidatorAction, org.apache.commons.validator.Field, org.apache.struts.action.Action(essages, org.apache.commons.validator._alidator, >ava0.servlet.http.SttpServlet!eBuest7 depends677 msg67errors.double7=;

4validator name67b3te-ocale7 classname67org.apache.struts.validator.FieldEhecks7 method67validateB3te-ocale7 method'arams67>ava.lang.,b>ect, org.apache.commons.validator._alidatorAction, org.apache.commons.validator.Field, org.apache.struts.action.Action(essages, org.apache.commons.validator._alidator, >ava0.servlet.http.SttpServlet!eBuest7 depends677 msg67errors.b3te7=; 4validator name67short-ocale7 classname67org.apache.struts.validator.FieldEhecks7 method67validateShort-ocale7 method'arams67>ava.lang.,b>ect, org.apache.commons.validator._alidatorAction, org.apache.commons.validator.Field, org.apache.struts.action.Action(essages, org.apache.commons.validator._alidator, >ava0.servlet.http.SttpServlet!eBuest7 depends677 msg67errors.short7=; 4validator name67integer-ocale7 classname67org.apache.struts.validator.FieldEhecks7

method67validate#nteger-ocale7 method'arams67>ava.lang.,b>ect, org.apache.commons.validator._alidatorAction, org.apache.commons.validator.Field, org.apache.struts.action.Action(essages, org.apache.commons.validator._alidator, >ava0.servlet.http.SttpServlet!eBuest7 depends677 msg67errors.integer7=; 4validator name67long-ocale7 classname67org.apache.struts.validator.FieldEhecks7 method67validate-ong-ocale7 method'arams67>ava.lang.,b>ect, org.apache.commons.validator._alidatorAction, org.apache.commons.validator.Field, org.apache.struts.action.Action(essages, org.apache.commons.validator._alidator, >ava0.servlet.http.SttpServlet!eBuest7 depends677 msg67errors.long7=; 4validator name67float-ocale7 classname67org.apache.struts.validator.FieldEhecks7 method67validateFloat-ocale7

method'arams67>ava.lang.,b>ect, org.apache.commons.validator._alidatorAction, org.apache.commons.validator.Field, org.apache.struts.action.Action(essages, org.apache.commons.validator._alidator, >ava0.servlet.http.SttpServlet!eBuest7 depends677 msg67errors.float7=;

4validator name67double-ocale7 classname67org.apache.struts.validator.FieldEhecks7 method67validate$ouble-ocale7 method'arams67>ava.lang.,b>ect, org.apache.commons.validator._alidatorAction, org.apache.commons.validator.Field, org.apache.struts.action.Action(essages, org.apache.commons.validator._alidator, >ava0.servlet.http.SttpServlet!eBuest7 depends677 msg67errors.double7=; 4validator name67date7 classname67org.apache.struts.validator.FieldEhecks7 method67validate$ate7

method'arams67>ava.lang.,b>ect, org.apache.commons.validator._alidatorAction, org.apache.commons.validator.Field, org.apache.struts.action.Action(essages, org.apache.commons.validator._alidator, >ava0.servlet.http.SttpServlet!eBuest7 depends677 msg67errors.date7 >sFunction+ame67$ate_alidations7=; 4validator name67int!ange7 classname67org.apache.struts.validator.FieldEhecks7 method67validate#nt!ange7 method'arams67>ava.lang.,b>ect, org.apache.commons.validator._alidatorAction, org.apache.commons.validator.Field, org.apache.struts.action.Action(essages, org.apache.commons.validator._alidator, >ava0.servlet.http.SttpServlet!eBuest7 depends67integer7 msg67errors.range7=;

4validator name67long!ange7 classname67org.apache.struts.validator.FieldEhecks7

method67validate-ong!ange7 method'arams67>ava.lang.,b>ect, org.apache.commons.validator._alidatorAction, org.apache.commons.validator.Field, org.apache.struts.action.Action(essages, org.apache.commons.validator._alidator, >ava0.servlet.http.SttpServlet!eBuest7 depends67long7 msg67errors.range7=; 4validator name67float!ange7 classname67org.apache.struts.validator.FieldEhecks7 method67validateFloat!ange7 method'arams67>ava.lang.,b>ect, org.apache.commons.validator._alidatorAction, org.apache.commons.validator.Field, org.apache.struts.action.Action(essages, org.apache.commons.validator._alidator, >ava0.servlet.http.SttpServlet!eBuest7 depends67float7 msg67errors.range7=;

4validator name67double!ange7 classname67org.apache.struts.validator.FieldEhecks7

method67validate$ouble!ange7 method'arams67>ava.lang.,b>ect, org.apache.commons.validator._alidatorAction, org.apache.commons.validator.Field, org.apache.struts.action.Action(essages, org.apache.commons.validator._alidator, >ava0.servlet.http.SttpServlet!eBuest7 depends67double7 msg67errors.range7=; 4validator name67creditEard7 classname67org.apache.struts.validator.FieldEhecks7 method67validateEreditEard7 method'arams67>ava.lang.,b>ect, org.apache.commons.validator._alidatorAction, org.apache.commons.validator.Field, org.apache.struts.action.Action(essages, org.apache.commons.validator._alidator, >ava0.servlet.http.SttpServlet!eBuest7 depends677 msg67errors.creditcard7=; 4validator name67email7 classname67org.apache.struts.validator.FieldEhecks7 method67validate mail7 method'arams67>ava.lang.,b>ect,

org.apache.commons.validator._alidatorAction, org.apache.commons.validator.Field, org.apache.struts.action.Action(essages, org.apache.commons.validator._alidator, >ava0.servlet.http.SttpServlet!eBuest7 depends677 msg67errors.email7=;

4validator name67url7 classname67org.apache.struts.validator.FieldEhecks7 method67validateUrl7 method'arams67>ava.lang.,b>ect, org.apache.commons.validator._alidatorAction, org.apache.commons.validator.Field, org.apache.struts.action.Action(essages, org.apache.commons.validator._alidator, >ava0.servlet.http.SttpServlet!eBuest7 depends677 msg67errors.url7=; 4F22 %his simpl3 allows struts to include the validateUtilities into a page, it should not be used as a validation rule. 22;

4validator name67includeJavaScriptUtilities7 Creating custom 1aldator rules &sing validation framewor# in our application not only provide the basic routines for the validations but also gives the user fle,ibility to create their own specific validator rules for the application% -his is the powerful e,tensible feature as this saves a lot more development and validation time during the application development% .elow is given the complete set of changes which should be performed while creating the custom validator rules for the application%

Steps to create the 2alidator rules :-

8. ?. @. A.

Ereate a class and add the static method for the validation. Add the entr3 in the validator2rules.0ml file. Associate the rule with the form field. Add the propert3 in the (essage!esources.properties for the error message.

$xample Note:- The e,ample is merged with the 1$,tending the 2alidation Rules with the inherited Sub'orm classes1. 3ou can see the marks !ield which can onl" take values !rom * to *44. The below is the validation class !or the e,ample.

pac5age com.visualbuilder.validatorJ import >ava.io.SerialiIableJ import >ava0.servlet.http.SttpServlet!eBuestJ import org.apache.commons.validator.FieldJ import org.apache.commons.validator._alidatorJ import org.apache.commons.validator._alidatorActionJ

import org.apache.commons.validator.util._alidatorUtilsJ import org.apache.struts.action.Action(essagesJ import org.apache.struts.validator.!esourcesJ =CC C %his class is a custom validator which when appl3 to the framework checks %he C field should contain onl3 alphabets C C= public class Eustom_alidator implements SerialiIable K public static boolean checkFor!angeG,b>ect bean, _alidatorAction va, Field field, Action(essages errors, _alidator validator, SttpServlet!eBuest reBuestH K boolean result 6 falseJ String value 6 evaluateBeanGbean, fieldHJ try K if G#nteger.parse#ntGvalueH ; 9 >> #nteger.parse#ntGvalueH 4 899H K result 6 trueJ L L catch G 0ception eH K L if GFresultH K errors.addGfield.get*e3GH, !esources.getAction(essageGvalidator, reBuest, va, fieldHHJ L return resultJ L pri!ate static String evaluateBeanG,b>ect bean, Field fieldH K String value 6 nullJ if Gbean instanceof StringH K value 6 GStringH beanJ L else K value 6 _alidatorUtils.get_alueAsStringGbean, field.get'ropert3GHHJ L return valueJ L L -xtending t%e Validator .ules wit% t%e in%erited 'ubForm Classes -= 6?7 0ctionForm Classes

'nputForm%(a&a pac5age com.visualbuilderJ

import org.apache.struts.validator._alidatorFormJ

public class #nputForm extends _alidatorForm K

String nameJ String emailJ String phoneJ

public String get mailGH K return emailJ L public void set mailGString emailH K this.email 6 emailJ L public String get+ameGH K return nameJ L

public void set+ameGString nameH K this.name 6 nameJ L public String get'honeGH K return phoneJ L public void set'honeGString phoneH K this.phone 6 phoneJ L L )egistrationForm%(a&a pac5age com.visualbuilderJ

public class !egistrationForm extends #nputForm K pri!ate String AddressJ pri!ate String marksJ

public String get(arksGH K return marksJ L public void set(arksGString marksH K this.marks 6 marksJ L public String getAddressGH K

return AddressJ L public void setAddressGString addressH K this.Address 6 addressJ L L (*) Action +lasses

2alidate'ction.?a!a pac5age com.visualbuilderJ

import >ava0.servlet.http.SttpServlet!eBuestJ import >ava0.servlet.http.SttpServlet!esponseJ import org.apache.struts.action.ActionJ import org.apache.struts.action.ActionFormJ import org.apache.struts.action.ActionForwardJ import org.apache.struts.action.Action(appingJ

public class _alidateAction extends Action K

public ActionForward e0ecuteGAction(apping mapping, ActionForm form, SttpServlet!eBuest reBuest, SttpServlet!esponse responseHthro(s 0ception K return mapping.get#nputForwardGHJ L

)egisterAction%(a&a pac5age com.visualbuilderJ

import >ava0.servlet.http.SttpServlet!eBuestJ import >ava0.servlet.http.SttpServlet!esponseJ import org.apache.struts.action.ActionJ import org.apache.struts.action.ActionFormJ import org.apache.struts.action.ActionForwardJ import org.apache.struts.action.Action(appingJ

public class !egisterAction e0tends Action K public ActionForward e0ecuteGAction(apping mapping, ActionForm form, SttpServlet!eBuest reBuest, SttpServlet!esponse responseHthro(s 0ception K return mapping.get#nputForwardGHJ L L

(,) Output

:nternationalization in struts application Few "ears bac5+ t%e sites are onl" de#eloped using a single language and t%e de#eloper onl" create t%e sites to t%eir specific languages 0s t%e globalization occurs+ man" framewor5s are de#eloped to support t%e multiple languages at a time T%is can be ac%ie#ed b" %a#ing t%e multi language text in 5e"<#alue pair 0nd at runtime t%e text is read from t%e 5e" as per t%e language re$uired T%is multilingual support is 5nown as :nternationalization 'o :nternationalization is defined as t%e process of designing an application so t%at it can be adapted to #arious languages and regions wit%out engineering c%anges

%he following classes are used to implement #nternationaliIation to an3 site.

#ocale 2 %he fundamental Java class that supports internationaliIation is -ocale . ach -ocale represents a particular choice of countr3 and language, and also a set of formatting assumptions for things like numbers and dates. 1esource,undle 2 %he >ava.util.!esourceBundle class provides the fundamental tools for supporting messages in multiple languages. *roperty1esource,undle 2 ,ne of the standard implementations of !esource Bundle allows 3ou to define resources using the same 7name6value7 s3nta0 used to initialiIe properties files. %his is ver3 convenient for preparing resource bundles with messages that are used in a web application, because these messages are generall3 te0t oriented. essage&ormat 2 %he >ava.te0t.(essageFormat class allows 3ou to replace portions of a message string with arguments specified at run time. %his is useful in cases where 3ou are creating a sentence, but the words would appear in a different order in different languages. %he placeholder string K9L in the message is replaced b3 the first runtime argument, K8L is replaced b3 the second argument, and so on. essage1esources 2 %he framework class org.apache.struts.util.(essage!esources lets 3ou treat a set of resource bundles like a database, and allows 3ou to reBuest a particular message string for a particular -ocale instead of for the default -ocale the server itself is running in.

The below e,ample will show the use o! &nternationali5ation in Struts.

Note :- The e,ample onl" displa"s the te,t coming !rom the di!!erent properties !iles. The properties !ile MessageResource.properties is created with di!!erent locale su!!i, e,ample !r is !or 'rance6 de !or 7erman" etc.. So the e,ample is onl" having the MessagesResources.properties and not the whole program. "ou can download the complete source !rom the !ile. 3ou can change the locale in the &$ b" tools8internet options87eneral---9anguages and check the program.

(-).essage)esources%properties

This is the de!ault properties !ile. &! the locale speci!ic !ile is not present then struts calls the de!ault properties !ile.

welcome.te0t6default /elcome %e0t

(") .essage)esources/en%properties

welcome.te,t/$nglish #elcome Te,t

(3) .essage)esources/$r%properties

welcome.te,t/'rench #elcome Te,t

(4) .essage)esources/!e%properties

welcome.te,t/7erman #elcome Te,t -xception Handling in 'truts 'truts @ A pro#ides a small+ but effecti#e exception-%andling framewor5 for t%e applications T%ere are two approac%es a#ailable for t%e exception %andling in struts

8. Declarati&e<2 #n this approach the e0ceptions are defined in the struts2config file and in case of the e0ception occurs the control is automaticall3 passed to the appropriate error page. %he 4e0ception; tag is used to define the e0ception in the struts2config.0ml file. %he following are the attributes of the 4e0ception; tag. 8. 0ey<2 %he ke3 defines the ke3 present in (essage!esources.properties file to describe the e0ception occurred. ?. Type<2 %he class of the e0ception occurred. @. Path<2 %he page where the control is to be followed in case e0ception occurred. A. 1an!ler<2 %he e0ception handler which will be called before passing the control to the file specified in path attribute

There are !ollowing two sections in struts-con!ig.,ml where "ou can de!ine the e,ceptions.

8. 2ith Any Action mapping<2 #n this approach the action class is identified which ma3 throw the e0ception like password failure, resource access etc. For e0ample<2 4action path67=e0ception7 t3pe67com.visualbuilder. 0ampleAction7 parameter67method7 input67=inde0.>sp7 ; 4e0ception ke367error.s3stem7 t3pe67>ava.lang.!untime 0ception7 path67=inde0.>sp7 =; 4=action; ?. De$ining the Exceptions 3lo4ally $or the struts#con$ig%xml <2 #f the application control is to pass on a single page for all similar t3pe of e0ception then the e0ception can be defined globall3. So if in an3 circumstance the e0ception occurs the control is passed globall3 to the e0ception and control is passed to the error page. For 0ample<2 4global2e0ceptions;

4e0ception ke367error.s3stem7 t3pe67>ava.lang.!untime 0ception7 path67=inde0.>sp7 =; 4=global2e0ceptions;

?. Programmatic< 2 #n this approach the e0ceptions are caught using normal >ava language tr3=catch block and instead of showing the e0ception some meaningful messages are displa3ed. #n this approach the flow of control is also maintained b3 the programs. %he main drawback of the approach is the developer has to write the code for the flow of the application. Creating Custom -xception Handlers in 'truts-@ T%e struts not onl" introduced t%e exception %andling mec%anism and pass t%e flow to t%e appropriate page automaticall"+ it also gi#es t%e flexibilit" to t%e programmers to create t%eir own -xception Handlers T%e struts pro#ides org.apache.struts.action.ExceptionHandler class for creating t%e custom exception %andlers 0ll t%e custom -xception Handlers s%ould extend t%e ExceptionHandler class and o#erride t%e execute67 met%od

%he below e0ample will demonstrate custom 0ceptionSandler for the user program.

Note:- The below e,ample will trans!er the control to the inde,.:sp a!ter calling the e,ception handler. &n the struts-con!ig.,ml we are adding the global e,ception !or Runtime$,ception. 3ou can add an" e,ception like the previous e,ample to some actions onl". The code !or adding it as !ollows :;e,ception ke"/1error.s"stem1 t"pe/1:ava.lang.Runtime$,ception1 handler/1com.visualbuilder.handler..ustom$,ception<andler1 path/1(inde,.:sp1 (8

Example For Exception1an!ler <2

)*+ .reating the $,ception <andler .lass

pac5age com.visualbuilder.handlerJ import >ava0.servlet.Servlet 0ceptionJ import >ava0.servlet.http.SttpServlet!eBuestJ import >ava0.servlet.http.SttpServlet!esponseJ import org.apache.struts.action.ActionFormJ import org.apache.struts.action.ActionForwardJ import org.apache.struts.action.Action(appingJ import org.apache.struts.action. 0ceptionSandlerJ import org.apache.struts.config. 0ceptionEonfigJ

public class Eustom 0ceptionSandler extends 0ceptionSandler K public ActionForward e0ecuteG 0ception e0ception, 0ceptionEonfig config, Action(apping mapping, ActionForm form#nstance, SttpServlet!eBuest reBuest, SttpServlet!esponse responseH thro(s Servlet 0ception K

try K == %,$, EustomeEode S3stem.out.printlnG7 0ception Sandler for the specific error7HJ 0catch G 0ception eH K

L return Gsuper.e0ecuteGe0ception, config, mapping, form#nstance, reBuest, responseHHJ L L

6@8 Struts-config.xml file

450ml version678.97 encoding67#S,2::5V287 5;

4F$,E%)' struts2config 'UB-#E 72==Apache Software Foundation==$%$ Struts Eonfiguration 8.@== +7 7http<==struts.apache.org=dtds=struts2config"8"@.dtd7; 4struts2config; 4F22 666666666666666666666666666666666666666666666666 Form Bean $efinitions 22; 4form2beans; 4=form2beans; 4F22 66666666666666666666666666666666666666666 .lobal 0ception $efinitions 22; 4global2e0ceptions; 4e0ception ke367error.s3stem7 t3pe67>ava.lang.!untime 0ception7 handler67com.visualbuilder.handler.Eustom 0ceptionSandler7 path67=inde0.>sp7 =; 4=global2e0ceptions; 4F22 6666666666666666666666666666666666666666666 .lobal Forward $efinitions 22; 4global2forwards;4=global2forwards; 4F22 6666666666666666666666666666666666666666666 Action (apping $efinitions 22; 4action2mappings; 4action path67=e0ception7 t3pe67com.visualbuilder. 0ampleAction7 input67=inde0.>sp7 =; 4=action2mappings; 4F22 6666666666666666666666666666666666666666 (essage !esources $efinitions 22; 4message2resources parameter67(essage!esources7 =; 4=struts2config; (3) Creating the Action Class

%he Action class is same as we have learned >ust with a small change. /e are throwing an error from

the Action Elass. so the code for the e0ecute method is as follows<2

public ActionForward e0ecuteGAction(apping mapping, ActionForm form, SttpServlet!eBuest reBuest, SttpServlet!esponse responseHthro(s 0ception K ifGtrueHK (( Throwing e,ception to call the $,ception <andler thro( ne( !untime 0ceptionG7+o Action7HJ L return mapping.get#nputForwardGHJ L

(4) JSP Page5# in!ex%(sp

Note :- The below :sp will onl" call the $,ception.do and then e,ception handler will pass the control again to this page.

4TU page language67>ava7 content%3pe67te0t=htmlJ charset6#S,2::5V287 page ncoding67#S,2::5V287T; 4F$,E%)' S%(- 'UB-#E 72==/@E==$%$ S%(- A.98 %ransitional== +7; 4html; 4head; 4meta http2eBuiv67Eontent2%3pe7 content67te0t=htmlJ charset6#S,2::5V287; 4title;#nsert title here4=title; 4=head; 4bod3; 4form action67e0ception.do7; 4input t3pe67submit7 value67Elick7; 4=form; 4=bod3; 4=html;

6A8 9utput:The program will print $,ception <andler !or the speci!ic error in the console window which shows that the .ustom$,ception<andler is called be!ore redirecting to the speci!ic page. Creating 2lugin for t%e 'truts 0pplication -@ 0 2lugin is defined as t%e component w%ic% are easil" integrated wit% t%e applications and %elps to en%ance t%e functionalit" of t%e s"stem 0 plug-in is an" 1a#a class t%at is initialized w%en struts application starts up and destro" w%en application s%uts down (e %a#e alread" seen man" plugin a#ailable for t%e struts li5e #alidations+ tiles etc T%e struts framewor5 also gi#es t%e de#eloper flexibilit" to create t%eir own plugin classes and t%en implement in t%e struts applications

Example For +ustom Plugins <2 )*+ .reating the =lugin .lass %he struts provide org.apache.struts.action.=lug&n interface. All the custom 'lugin should implement the =lug&n interface and override the init)+ and destro")+ methods.

pac5age com.visualbuilder.pluginJ

import >ava0.servlet.Servlet 0ceptionJ import org.apache.struts.action.ActionServletJ import org.apache.struts.action.'lug#nJ import org.apache.struts.config.(oduleEonfigJ public class Eustom'lugin implements 'lug#n K

public Eustom'luginGH K superGHJ L public void destro3GH K S3stem.out.printlnG7%he plug in $estro3ed7HJ L public void initGActionServlet controller, (oduleEonfig configH thro(s Servlet 0ception K controller.getServletEonte0tGH.setAttributeG7test'lugin7,7%esting for the ob>ect7HJ S3stem.out.printlnG7%he plug in initialiIed7HJ L L 6@8 Struts-config.xml file 450ml version678.97 encoding67#S,2::5V287 5;

4F$,E%)' struts2config 'UB-#E 72==Apache Software Foundation==$%$ Struts Eonfiguration 8.@== +7 7http<==struts.apache.org=dtds=struts2config"8"@.dtd7; 4struts2config; 4F22 666666666666666666666666666666666666666666666666 Form Bean $efinitions 22; 4form2beans;4=form2beans; 4F22 66666666666666666666666666666666666666666 .lobal 0ception $efinitions 22; 4global2e0ceptions;4=global2e0ceptions; 4F22 6666666666666666666666666666666666666666666 .lobal Forward $efinitions 22; 4global2forwards;4=global2forwards; 4F22 6666666666666666666666666666666666666666666 Action (apping $efinitions 22; 4action2mappings; 4action path67=plugin7 t3pe67com.visualbuilder.%est'luginAction7 input67=inde0.>sp7 ; 4forward name67SUEE SS7 path67=inde0.>sp7=; 4=action; 4=action2mappings;

4F22 6666666666666666666666666666666666666666 (essage !esources $efinitions 22; 4message2resources parameter67(essage!esources7 =; 4F22 6666666666666666666666666666666666666666 Eustom 'lugin $efinitions 22; 4plug2in class+ame67com.visualbuilder.plugin.Eustom'lugin7;4=plug2in; 4=struts2config; Creating 2lugin for t%e 'truts 0pplication -= (3) Action Class to Access the Attribute Set in the Plugin

pac5age com.visualbuilderJ

import >ava0.servlet.http.SttpServlet!eBuestJ import >ava0.servlet.http.SttpServlet!esponseJ

import org.apache.struts.action.ActionJ import org.apache.struts.action.ActionFormJ import org.apache.struts.action.ActionForwardJ import org.apache.struts.action.Action(appingJ

public class %est'luginAction extends Action K

public ActionForward e0ecuteGAction(apping mapping, ActionForm form, SttpServlet!eBuest reBuest, SttpServlet!esponse responseHthro(s 0ception K S3stem.out.printlnGservlet.getServletEonte0tGH.getAttributeG7test'lugin7HHJ return mapping.findForwardG7SUEE SS7HJ L L

6B8 9utput

Note:-The program will :ust print 1The plug in initiali5ed1 when the server starts and =rint 1Testing

!or the ob:ect1 when "ou call the 1(plugin.do1 action. (ildCard C%aracter mapping for t%e 0ctions-@ Bow a da"s t%e complex application are alwa"s bigger in size 'o t%e number of action mappings will also increases (ildcards can be used to combine similar mappings into one more generic mapping and %elps to reduce t%e size of t%e config files

(ildcard patterns can contain one or more of t%e following special to5ens/

(atches Iero or more characters e0cluding the slash G`=`H character.

CC

(atches Iero or more characters including the slash G`=`H character.

Mcharacter

%he backslash character is used as an escape seBuence. %hus MC matches the character asterisk G`C`H, and MM matches the character backslash G`M`H.

6ote <2#n the action mapping and action forwards, the wildcard2matched values can be accessed with the token K+L where + is a number from 8 to V indicating which wildcard2matched value to substitute. %he whole reBuest U!# can be accessed with the K9L token.

%he action mapping attributes that will accept wildcard2matched strings are<

attribute catalog command forward include input multipartElass name parameter prefi0 roles suffi0 t3pe

%he action forward attributes that will accept wildcard2matched strings are<

catalog command path

The belo( example (ill demonstrate the Use of (ildcard characters.

(-) Struts#con$ig%xml

6ote5# &n the action mapping the parameter is passed as >*?. The :sp which invoked the action replaces the parameter with the name o!the :sp in all places.

450ml version678.97 encoding67#S,2::5V287 5; 4F$,E%)' struts2config 'UB-#E 72==Apache Software Foundation==$%$ Struts Eonfiguration 8.@== +7 7http<==struts.apache.org=dtds=struts2config"8"@.dtd7; 4struts2config; 4F22 666666666666666666666666666666666666666666666666 Form Bean $efinitions 22; 4form2beans; 4form2bean name67#nputForm7 t3pe67com.visualbuilder.#nputForm7 =; 4form2bean name67!egisterForm7 t3pe67com.visualbuilder.!egisterForm7=; 4=form2beans; 4F22 66666666666666666666666666666666666666666 .lobal 0ception $efinitions 22; 4global2e0ceptions;4=global2e0ceptions; 4F22 6666666666666666666666666666666666666666666 .lobal Forward $efinitions 22; 4global2forwards;4=global2forwards; 4F22 6666666666666666666666666666666666666666666 Action (apping $efinitions 22; 4action2mappings; Caction path34DsubmitE4 type34com.!isualbuilder.Submit.;0'ction4 name34.;0&orm4 scope34re+uest4

!alidate34false4 input34D.;0.?sp4DF

4=action2mappings;

4F22 6666666666666666666666666666666666666666 (essage !esources $efinitions 22; 4message2resources parameter67(essage!esources7 =; 4=struts2config; 6=7 0ction Classes

Su4mit)egisterAction%(a&a $ile

package com.visualbuilderJ

import >ava0.servlet.http.SttpServlet!eBuestJ import >ava0.servlet.http.SttpServlet!esponseJ import org.apache.struts.action.ActionJ import org.apache.struts.action.ActionFormJ import org.apache.struts.action.ActionForwardJ import org.apache.struts.action.Action(appingJ import org.apache.struts.action.Action(essageJ import org.apache.struts.action.Action(essagesJ

public class Submit!egisterAction e0tends Action K

public ActionForward e0ecuteGAction(apping mapping, ActionForm form, SttpServlet!eBuest reBuest, SttpServlet!esponse responseH throws 0ception K S3stem.out.printlnG7Ealled Submit!egisterAction file 7HJ return mapping.get#nputForwardGHJ L L Su4mit'nputAction%(a&a $ile

package com.visualbuilderJ

import >ava0.servlet.http.SttpServlet!eBuestJ import >ava0.servlet.http.SttpServlet!esponseJ import org.apache.struts.action.ActionJ import org.apache.struts.action.ActionFormJ import org.apache.struts.action.ActionForwardJ import org.apache.struts.action.Action(appingJ

public class Submit#nputAction e0tends Action K public ActionForward e0ecuteGAction(apping mapping, ActionForm form, SttpServlet!eBuest reBuest, SttpServlet!esponse responseHthrows 0ception K

S3stem.out.printlnG7Ealled Submit#nputAction file 7HJ return mapping.get#nputForwardGHJ L L 678'ction &orms

'nputForm%(a&a $ile

package com.visualbuilderJ

import org.apache.struts.validator._alidatorFormJ

public class #nputForm e0tends _alidatorForm K

String nameJ String emailJ String phoneJ

public String get mailGH K return emailJ L public void set mailGString emailH K this.email 6 emailJ L public String get+ameGH K return nameJ L public void set+ameGString nameH K this.name 6 nameJ L public String get'honeGH K return phoneJ L public void set'honeGString phoneH K this.phone 6 phoneJ L L )egisterForm%(a&a $ile

package com.visualbuilderJ

public class !egisterForm e0tends #nputForm K

private String AddressJ private String marksJ

public String get(arksGH K return marksJ L public void set(arksGString marksH K this.marks 6 marksJ L public String getAddressGH K return AddressJ L public void setAddressGString addressH K Address 6 addressJ L L (4) Input.jsp File

4TU taglib uri67http<==struts.apache.org=tags2bean7 prefi067bean7T; 4TU taglib uri67http<==struts.apache.org=tags2html7 prefi067html7T; 4TU taglib uri67http<==struts.apache.org=tags2logic7 prefi067logic7T; 4F$,E%)' S%(- 'UB-#E 72==/@E==$%$ S%(- A.98 %ransitional== +7; 4html<html; 4html<form action67=submit#nput.do7 method67post7; 4table; 4tr; 4td colspan67?7; 4logic<messages'resent; 4html<messages id67msg7; 4p; 4strong;4font color67red7;4bean<write name67msg7 =;4=font;4=strong; 4=p; 4=html<messages;

4=logic<messages'resent; 4=td; 4=tr; 4tr; 4td colspan67?7; 4logic<messages'resent message67true7; 4html<messages message67true7 id67msg7; 4p; 4strong;4bean<write name67msg7 =;4=strong; 4=p; 4=html<messages; 4=logic<messages'resent; 4=td; 4=tr; 4tr;4td; nter the name4=td; 4td;4html<te0t propert367name7 =;4=td;4=tr; 4tr;4td; nter the 'hone4=td; 4td; 4html<te0t propert367phone7 =;4=td;4=tr; 4tr;4td; nter the mail4=td; 4td;4html<te0t propert367email7 =;4=td;4=tr; 4=table;4html<submit;Submit 4=html<submit; 4=html<form; 4=html<html;

6A8 1egsiter.?sp &ile

4TU taglib uri67http<==struts.apache.org=tags2bean7 prefi067bean7T; 4TU taglib uri67http<==struts.apache.org=tags2html7 prefi067html7T; 4TU taglib uri67http<==struts.apache.org=tags2logic7 prefi067logic7T; 4F$,E%)' S%(- 'UB-#E 72==/@E==$%$ S%(- A.98 %ransitional== +7; 4html<html; 4html<form action67=submit!egister.do7 method67post7; 4table; 4tr; 4td colspan67?7; 4logic<messages'resent; 4html<messages id67msg7; 4p; 4strong;4font color67red7;4bean<write name67msg7 =;4=font;4=strong; 4=p; 4=html<messages; 4=logic<messages'resent; 4=td;

4=tr; 4tr; 4td colspan67?7; 4logic<messages'resent message67true7; 4html<messages message67true7 id67msg7; 4p; 4strong;4bean<write name67msg7 =;4=strong; 4=p; 4=html<messages; 4=logic<messages'resent; 4=td; 4=tr; 4tr;4td; nter the name4=td; 4td;4html<te0t propert367name7 =;4=td;4=tr; 4tr;4td; nter the 'hone4=td; 4td; 4html<te0t propert367phone7 =;4=td;4=tr; 4tr;4td; nter the mail4=td; 4td;4html<te0t propert367email7 =;4=td;4=tr; 4tr;4td; nter the Address 4=td; 4td;4html<te0t propert367address7 =;4=td;4=tr; 4tr;4td; nter the (arks 4=td; 4td;4html<te0t propert367marks7 =;4=td;4=tr; 4=table;4html<submit;Submit 4=html<submit; 4=html<form; 4=html<html;

6G8 9utput

6ote5# #hen user submits the Register !orm and calls the submitRegister.do action then automaticall" the control calls the submitRegister ction class and prints 1 .alled SubmitRegister ction !ile 1 and same as !or the submit&nput.do calls the submit&nput ction class and prints 1.alled Submit&nput ction !ile 1 on the console. !ploading t%e Files to 'er#er !sing 'truts-@ Man" applications gi#es t%e utilit" to upload t%e data from client applications to t%e ser#er 'truts also gi#es t%e flexibilit" to upload t%e files using t%e org.apache.struts.upload.FormFile class T%e org.apache.struts.upload.FormFile class is a special class in struts w%ic% represent t%e propert" t"pe of file T%e following example will demonstrate to upload an" txt file and place it in t%e upload folder b" t%e name of temp txt

$xample:-

(-) Struts#con$ig%xml $ile

450ml version678.97 encoding67#S,2::5V287 5;

4F$,E%)' struts2config 'UB-#E 72==Apache Software Foundation==$%$ Struts Eonfiguration 8.@== +7 7http<==struts.apache.org=dtds=struts2config"8"@.dtd7; 4struts2config; 4F22 666666666666666666666666666666666666666666666666 Form Bean $efinitions 22; 4form2beans; 4form2bean name67inputForm7 t3pe67com.visualbuilder.#nputForm7 =; 4=form2beans; 4F22 66666666666666666666666666666666666666666 .lobal 0ception $efinitions 22; 4global2e0ceptions;4=global2e0ceptions; 4F22 6666666666666666666666666666666666666666666 .lobal Forward $efinitions 22; 4global2forwards;4=global2forwards; 4F22 6666666666666666666666666666666666666666666 Action (apping $efinitions 22; 4action2mappings; 4action path67=submit7 t3pe67com.visualbuilder.#nputAction7 name67inputForm7 scope67reBuest7 validate67false7 input67=inde0.>sp7=; 4=action2mappings; 4controller ma0FileSiIe67?(7 =; 4F22 6666666666666666666666666666666666666666 (essage !esources $efinitions 22; 4message2resources parameter67(essage!esources7 =; 4=struts2config;

(") 'nputForm%(a&a File

package com.visualbuilderJ import org.apache.struts.upload.FormFileJ import org.apache.struts.validator._alidatorFormJ

public class #nputForm e0tends _alidatorForm K

private FormFile file+ameJ public FormFile getFile+ameGH K (3) InputAction.java file

package com.visualbuilderJ

import >ava.io.B3teArra3,utputStreamJ import >ava.io.File+otFound 0ceptionJ import >ava.io.File,utputStreamJ import >ava.io.#, 0ceptionJ import >ava.io.#nputStreamJ import >ava.io.,utputStreamJ

import >ava0.servlet.http.SttpServlet!eBuestJ import >ava0.servlet.http.SttpServlet!esponseJ

import org.apache.struts..lobalsJ import org.apache.struts.action.ActionJ

import org.apache.struts.action.ActionFormJ import org.apache.struts.action.ActionForwardJ import org.apache.struts.action.Action(appingJ import org.apache.struts.action.Action(essageJ import org.apache.struts.action.Action(essagesJ import org.apache.struts.upload.FormFileJ

public class #nputAction e0tends Action K public ActionForward e0ecuteGAction(apping mapping, ActionForm form, SttpServlet!eBuest reBuest, SttpServlet!esponse responseH throws 0ception K #nputForm inputForm 6 G#nputFormH formJ == retrieve the file representation FormFile file 6 inputForm.getFile+ameGHJ == retrieve the file name String file+ame 6 file.getFile+ameGHJ == retrieve the content t3pe

:ntroduction to Modules in 'truts 0pplication Cenerall"+ all t%e applications and s"stems are modularized so t%at t%e time of de#elopment and complexit" can be reduced T%e struts also gi#e t%e flexibilit" to %a#e more t%an one independent modules in t%e application T%e separate struts-config files are introduced for eac% module T%is %elps de#elopers to de#elop t%e complex applications more effecti#el" as different independent applications can be de#eloped separatel" and t%en combined toget%er to ma5e a complete s"stem T%e struts gi#es a special 0ction class+ 'witc%0ction + w%ic% is used for t%e switc%ing between t%e modules T%e below example will demonstrate t%e modules in t%e 'truts 0pplications

The !ollowing things needs to be changed to make more than one modules in the application.

ll the module speci!ic con!ig !iles should be kept on the module speci!ic directories under #$%-&N' !older. ll the :sp !iles !or the module should be kept under the module !older. ll the module speci!ic !iles should be passed in the ctionServlet in the #eb.,ml !ile.

%here are three approaches for switching from one module to another.

3ou can use the org.apache.struts.actions.Switch ction !rom the $,tras @ R6 "ou can use a ;!orward8 )global or local+ and speci!" the conte,tRelative attribute with a value o! true6 or "ou can speci!" the 1module1 parameter as part o! an" o! the Struts @S= h"perlink tags )&nclude6 &mg6 9ink6 Rewrite6 or 'orward+.

Note:- The coming e,ample will demonstrate the all three approaches !or the application ote!" In the #elo$ example $e are creating the admin and register module. %ou can do$nload the $hole source from do$nload lin&. 'e onl( sho$ the code $hich is $ritten for the modules so that (ou can understand the exact logic to s$itch the modules.

(-) 2e4%xml $ile +hanges

;servlet8 ;servlet-name8action;(servlet-name8 ;servlet-class8org.apache.struts.action. ctionServlet;(servlet-class8 ;init-param8 7param#name8con$ig79param#name8 7param#&alue892E:#'6F9struts#con$ig%xml79param#&alue8 79init#param8 7init#param8 7param#name8con$ig9a!min79param#name8 7param#&alue892E:#'6F9a!min9struts#a!min%xml79param#&alue8 79init#param8 7init#param8 7param#name8con$ig9register79param#name8 7param#&alue892E:#'6F9register9struts#register%xml79param#&alue8 79init#param8

;load-on-startup8A;(load-on-startup8 ;(servlet8 (") Struts#con$ig%xml $or !e$ault .o!ule%

450ml version678.97 encoding67#S,2::5V287 5; 4F$,E%)' struts2config 'UB-#E 72==Apache Software Foundation==$%$ Struts Eonfiguration 8.@== +7 7http<==struts.apache.org=dtds=struts2config"8"@.dtd7; 4struts2config; 4F22 666666666666666666666666666666666666666666666666 Form Bean $efinitions 22; 4form2beans;4=form2beans; 4F22 66666666666666666666666666666666666666666 .lobal 0ception $efinitions 22; ()) index.jsp file for *efault +odule.

4TU taglib uri67http<==struts.apache.org=tags2bean7 prefi067bean7T; 4TU taglib uri67http<==struts.apache.org=tags2html7 prefi067html7T; 4TU taglib uri67http<==struts.apache.org=tags2logic7 prefi067logic7T; 4F$,E%)' S%(- 'UB-#E 72==/@E==$%$ S%(- A.98 %ransitional== +7; 4html<html; %his is the default (odule Application4br=; -inks created for own Forward action 4br=; 4a href67switchAdmin.do7;Admin4=a;4br=; 4a href67switch!egister.do7;!egister4=a;4br=; -inks created for the SwitchAcion4br=; 4a href67switchtoAdmin.do5prefi06=adminPpage6=inde0.>sp7;Admin4=a;4br=; 4a href67switchto!egister.do5prefi06=regsiterPpage6=inde0.>sp7;!egister4=a;4br=; -inks created for the html<link tag4br=; 4html<link module67=admin7 page67=inde0.>sp7;admin4=html<link; 4html<link module67=register7 page67=inde0.>sp7;register4=html<link; 4br=; 4=html<html; (,) in!ex%(sp $ile $or A!min .o!ule%

4TU taglib uri67http<==struts.apache.org=tags2bean7 prefi067bean7T; 4TU taglib uri67http<==struts.apache.org=tags2html7 prefi067html7T; 4TU taglib uri67http<==struts.apache.org=tags2logic7 prefi067logic7T; 4F$,E%)' S%(- 'UB-#E 72==/@E==$%$ S%(- A.98 %ransitional== +7; 4html<html; %his is the Admin (odule File 4a href67=switch%o!egister.do5prefi06=registerPpage6=inde0.>sp7;!egister4=a; 4=html<html; (;) in!ex%(sp $ile $or )egister .o!ule%

4TU taglib uri67http<==struts.apache.org=tags2bean7 prefi067bean7T; 4TU taglib uri67http<==struts.apache.org=tags2html7 prefi067html7T; 4TU taglib uri67http<==struts.apache.org=tags2logic7 prefi067logic7T; 4F$,E%)' S%(- 'UB-#E 72==/@E==$%$ S%(- A.98 %ransitional== +7; 4html<html; %his is the !egsiter (odule File 4a href67=switch%oAdmin.do5prefi06=adminPpage6=inde0.>sp7;Admin4=a; 4=html<html;

(<) Output5#

6ote5# Bn running the de!ault module inde,.:sp !ile the !ollowing output will be displa"ed on the screen.

Customizing t%e 0ction'er#let Class for t%e application 'truts follow t%e Model-View-Controller pattern 0ction'er#let pro#ides t%e ,controller, in t%e MVC design pattern for web applications t%at is commonl" 5nown as ,Model =, T%e standard #ersion of 0ction'er#let is configured based on t%e following ser#let

initialization parameters+

con$ig - Eomma2separated list of conte0t2relative pathGsH to the &(- resourceGsH containing the configuration information for the default module. G(ultiple files support since Struts 8.8H [=/ B2#+F=struts2config.0ml]. con$ig9=>mo!ule? 2 Eomma2separated list of Eonte0t2relative pathGsH to the &(- resourceGsH containing the configuration information for the module that will use the specified prefi0 G=^ KmoduleLH. %his can be repeated as man3 times as reBuired for multiple modules. con$igFactory 2 %he Java class name of the (oduleEonfigFactor3 used to create the implementation of the (oduleEonfig interface. con&ert6ull 2 Force simulation of the Struts 8.9 behavior when populating forms. #f set to true, the numeric Java wrapper class t3pes Glike >ava.lang.#nteger H will default to null Grather than 9H. GSince Struts 8.8H [false] rulesets 2 Eomma2delimited list of full3 Bualified classnames of additional org.apache.commons.digester.!uleSet instances that should be added to the $igester that will be processing struts2config.0ml files. B3 default, onl3 the !uleSet for the standard configuration elements is loaded. &ali!ating 2 Should we use a validating &(- parser to process the configuration file Gstrongl3 recommendedH5 [true] chain+on$ig 2 Eomma2separated list of either conte0t2relative or classloader pathGsH to load commons2chain catalog definitions from. #f none specified, the default Struts catalog that is provided with Struts will be used.

%he main power of struts is that 3ou can customiIe the controller behaviour if needed b3 3our application. %he below e0ample will demonstrate to override the default functionalit3 of the controller and do some application specific processing before and after the reBuest has been processed. (-) Struts#con$ig%xml $ile

450ml version678.97 encoding67#S,2::5V287 5;

4F$,E%)' struts2config 'UB-#E 72==Apache Software Foundation==$%$ Struts Eonfiguration 8.@== +7 7http<==struts.apache.org=dtds=struts2config"8"@.dtd7; 4struts2config; 4F22 666666666666666666666666666666666666666666666666 Form Bean $efinitions 22; 4form2beans; 4form2bean name67inputForm7 t3pe67com.visualbuilder.#nputForm7 =;

4=form2beans; 4F22 66666666666666666666666666666666666666666 .lobal 0ception $efinitions 22; 4global2e0ceptions;4=global2e0ceptions; 4F22 6666666666666666666666666666666666666666666 .lobal Forward $efinitions 22; 4global2forwards;4=global2forwards; 4F22 6666666666666666666666666666666666666666666 Action (apping $efinitions 22; 4action2mappings; 4action path67=submit7 t3pe67com.visualbuilder.SubmitAction7 name67inputForm7 scope67reBuest7 validate67false7 input67=inde0.>sp7=; 4=action2mappings; 4F22 6666666666666666666666666666666666666666 (essage !esources $efinitions 22; 4message2resources parameter67(essage!esources7 =; $e#.xml file

The mapping !or the ctionServlet class is written in the web.,ml !ile so we have to change it !or mapping our .ustom ctionServlet class.

450ml version678.97 encoding67U%F2:75; 4web2app version67?.A7 0mlns67http<==>ava.sun.com=0ml=ns=>?ee7 0mlns<0si67http<==www.w@.org=?998=&(-Schema2instance7 0si<schema-ocation67http<==>ava.sun.com=0ml=ns=>?ee http<==>ava.sun.com=0ml=ns=>?ee=web2 app"?"A.0sd7; 4servlet; 4servlet2name;action4=servlet2name; 4servlet2class;com.visualbuilder.EustomActionServlet4=servlet2class; 4init2param; 4param2name;config4=param2name; 4param2value;=/ B2#+F=struts2config.0ml4=param2value; 4=init2param; 4load2on2startup;?4=load2on2startup;

4=servlet; 4servlet2mapping; 4servlet2name;action4=servlet2name; 4url2pattern;C.do4=url2pattern; 4=servlet2mapping; 4welcome2file2list; 4welcome2file;inde0.>sp4=welcome2file; 4=welcome2file2list; 4=web2app;

(3)+ustomActionSer&let%(a&a $ile

This is the !ile which is the replaces the Struts .ontroller class. #e e,tends the Struts ctionServlet to get the de!ault behaviour and override the process method.

package com.visualbuilderJ

import >ava.io.#, 0ceptionJ import >ava0.servlet.Servlet 0ceptionJ import >ava0.servlet.http.SttpServlet!eBuestJ import >ava0.servlet.http.SttpServlet!esponseJ import org.apache.struts.action.ActionServletJ

public class EustomActionServlet e0tends ActionServlet K private static final long serial_ersionU#$ 6 8-J public void processGSttpServlet!eBuest reBuest, SttpServlet!esponse responseH throws #, 0ception, Servlet 0ception K ==%,$, )ou can put the Eode before the reBuest handling. S3stem.out.printlnG7Before Sandling !eBuest7HJ super.processGreBuest,responseHJ ==%,$, )ou can put the Eode after the reBuest handling. S3stem.out.printlnG7After Sandling !eBuest7HJ L L (4)'nputForm%(a&a $ile

package com.visualbuilderJ

import org.apache.struts.validator._alidatorFormJ

public class #nputForm e0tends _alidatorForm K

String nameJ String emailJ

String phoneJ

public String get mailGH K return emailJ L public void set mailGString emailH K this.email 6 emailJ L public String get+ameGH K return nameJ L public void set+ameGString nameH K this.name 6 nameJ L public String get'honeGH K return phoneJ L public void set'honeGString phoneH K this.phone 6 phoneJ L L ()) ,u#mitAction.java file

package com.visualbuilderJ import >ava0.servlet.http.SttpServlet!eBuestJ

import >ava0.servlet.http.SttpServlet!esponseJ

import org.apache.struts.action.ActionJ import org.apache.struts.action.ActionFormJ import org.apache.struts.action.ActionForwardJ import org.apache.struts.action.Action(appingJ import org.apache.struts.action.Action(essageJ import org.apache.struts.action.Action(essagesJ

public class SubmitAction e0tends Action K public ActionForward e0ecuteGAction(apping mapping, ActionForm form, SttpServlet!eBuest reBuest, SttpServlet!esponse responseH throws 0ception K S3stem.out.printlnG7Ealled Submit file 7HJ return mapping.get#nputForwardGHJ L

(,)'n!ex%(sp $ile

4TU taglib uri67http<==struts.apache.org=tags2bean7 prefi067bean7T; 4TU taglib uri67http<==struts.apache.org=tags2html7 prefi067html7T; 4TU taglib uri67http<==struts.apache.org=tags2logic7 prefi067logic7T; 4F$,E%)' S%(- 'UB-#E 72==/@E==$%$ S%(- A.98 %ransitional== +7; 4html<html; 4html<form action67=validate.do7 method67post7; 4table; 4tr; 4td colspan67?7; 4logic<messages'resent; 4html<messages id67msg7; 4p; 4strong;4font color67red7;4bean<write name67msg7 =;4=font;4=strong; 4=p; 4=html<messages;

4=logic<messages'resent; 4=td; 4=tr; 4tr; 4td colspan67?7; 4logic<messages'resent message67true7; 4html<messages message67true7 id67msg7; 4p; 4strong;4bean<write name67msg7 =;4=strong; 4=p; 4=html<messages; 4=logic<messages'resent; 4=td; 4=tr; 4tr;4td; nter the name4=td; 4td;4html<te0t propert367name7 =;4=td;4=tr; 4tr;4td; nter the 'hone4=td; 4td; 4html<te0t propert367phone7 =;4=td;4=tr; 4tr;4td; nter the mail4=td; 4td;4html<te0t propert367email7 =;4=td;4=tr; 4=table;4html<submit;Submit 4=html<submit; 4=html<form; 4=html<html;

6H89utput

6ote5# #henever the reCuest is submitted to the application "ou see two line %e!ore <andling ReCuest and !ter <andling ReCuest printing on the console and the line .alled Submit !ile is printed in between. This shows that !or ever" reCuest the code o! .ustom ctionServlet gets called. Customizing .e$uest2rocessor Class for t%e application T%e pre#ious example %as s%own "ou to customize t%e controller before and after an" re$uest processed But 'truts pro#ide a class named -e.uest/rocessor w%ic% actuall" done all t%e processing for a particular re$uest :n 'truts @ > t%e w%ole t%ings are done b" t%e Action,ervlet class But wit% t%e next release t%e re$uest processing code s%ifted to -e.uest/rocessor class -e.uest/rocessor contains t%e processing logic t%at t%e 0ction'er#let performs as it recei#es eac% ser#let re$uest from t%e container Dou can customize t%e re$uest processing be%a#ior b" subclassing t%is class and o#erriding t%e met%od6s7 w%ose be%a#ior "ou are interested in c%anging t%e following met%ods are a#ailable in t%e -e.uest/rocessor Class

process.ultipart()<2 Sandles the multipart reBuest containing the images etc. processPath()<2 #dentif3 and return the path component process@ocale()<2 Automaticall3 select a -ocale for the current user, if reBuested. process+ontent()<2 Set the default content t3pe with character encodings for all responses process6o+ache()<2 Set the no2cache headers for all responses, if reBuested. processPreprocess()<2 .eneral2purpose preprocessing hook that can be overridden as reBuired b3 subclasses. process.apping()<2 Select the mapping used to process the selection path for this reBuest. process)oles()<2 #f this action is protected b3 securit3 roles, make sure that the current user possesses at least one of them. processActionForm()<2 !etrieve and return the ActionForm associated with this mapping, creating and retaining one if necessar3. processPopulate()<2 'opulate the properties of the specified ActionForm instance from the reBuest parameters included with this reBuest. process ali!ate()<2 #f this reBuest was not cancelled, and the reBuest`s Action(apping has not disabled validation, call the validate method of the specified ActionForm, and forward to the input path if there were an3 errors. processForAar!()<2 'rocess a forward reBuested b3 this mapping Gif an3H. process'nclu!e()<2 'rocess an include reBuested b3 this mapping Gif an3H. processAction+reate()<2 !eturn an Action instance that will be used to process the current reBuest, creating a new one if necessar3. processActionPer$orm()<2 Ask the specified Action instance to handle this reBuest. processForAar!+on$ig()<2 Forward or redirect to the specified destination, b3 the specified mechanism.

6ote5# The below e,ample will demonstrate the overriding o! methods in the ReCuest=rocessor class. The e,ample will override process=reprocess)+ method o! the ReCuest=rocessor .lass. ;

6;8Struts-config.xml file

6ote - ReCuest=rocessor mapping is given b" the ;controller8 tag in the struts-con!ig.,ml !ile.

450ml version678.97 encoding67#S,2::5V287 5;

4F$,E%)' struts2config 'UB-#E 72==Apache Software Foundation==$%$ Struts Eonfiguration 8.@== +7 7http<==struts.apache.org=dtds=struts2config"8"@.dtd7; 4struts2config; 4F22 666666666666666666666666666666666666666666666666 Form Bean $efinitions 22; 4form2beans; 4form2bean name67inputForm7 t3pe67com.visualbuilder.#nputForm7 =; 4=form2beans; 4F22 66666666666666666666666666666666666666666 .lobal 0ception $efinitions 22; 4global2e0ceptions;4=global2e0ceptions; 4F22 6666666666666666666666666666666666666666666 .lobal Forward $efinitions 22; 4global2forwards;4=global2forwards; 4F22 6666666666666666666666666666666666666666666 Action (apping $efinitions 22; 4action2mappings; 4action path67=submit7 t3pe67com.visualbuilder.SubmitAction7 name67inputForm7 scope67reBuest7 validate67false7 input67=inde0.>sp7=; 4=action2mappings; 4F22 6666666666666666666666666666666666666666666 Eontroller (apping $efinition 22; Ccontroller contentType34textDhtml=charset3UT&-I4 locale34true4 debug34;4 nocache34true4 processorClass34com.!isualbuilder.Custom1e+uest*rocessor4 DF

4F22 6666666666666666666666666666666666666666 (essage !esources $efinitions 22; 4message2resources parameter67(essage!esources7 =; 4=struts2config; 6=7 Custom.e$uest2rocessor 8a#a file

package com.visualbuilderJ

import >ava0.servlet.http.SttpServlet!eBuestJ import >ava0.servlet.http.SttpServlet!esponseJ import org.apache.struts.action.!eBuest'rocessorJ

public class Eustom!eBuest'rocessor e0tends !eBuest'rocessor K

public boolean process'reprocessGSttpServlet!eBuest reBuest, SttpServlet!esponse responseH K S3stem.out .printlnG7Ealled the preprocess method before processing the reBuest7HJ return super.process'reprocessGreBuest,responseHJ L L 6ote5# ,nl3 the above specified files are addition to the previous e0ample i.e.7EustomiIing the ActionServlet Elass for the application7.

678 9utput

The te,t 1.alled the preprocess method be!ore processing the reCuest1 gets printed each time the reCuest is processed b" the Struts. This shows that it is calling the .ustomReCuest=rocessor and not the ReCuest=rocessor class. Composable.e$uest2rocessor in 'truts @ A :ntroduction /- 0 popular tec%ni$ue for organizing t%e execution of complex processing flows is t%e ,C%ain of .esponsibilit", pattern :n t%is pattern t%e different EcommandsF are combined into a single c%ain wit% a series of processing elements and t%e context parameter is passed along wit% all t%e parameter 0ll t%e commands contain a single execute met%od 0 Boolean #ariable determines w%et%er t%e command executes successfull" or not T%is pattern promotes t%e idea of loose coupling+ a common programming practice

From the version 8.@, the struts replaces the !eBuest'rocessor with .omposableReCuest=rocessor class which follows the .hain o! Responsibilit" pattern GEo!H design pattern. #t is configured via the following conte0t initialiIation parameters<

org%apache%struts%chain%+ATA@O3/6A.E 2 +ame of the Eatalog in which we will look up the Eommand to be e0ecuted for each reBuest. #f not specified, the default value is struts. org%apache%struts%chain%+O..A6D/6A.E 2 +ame of the Eommand which we will e0ecute for each reBuest, to be looked up in the specified Eatalog. #f not specified, the default value is servlet2standard.

ach step of the processing is represented as a separate Eommand in the Ehain. User can easil3 customiIe b3 changing, removing and replacing the chain commands. %he Eommand classes are following packages<2

*. org.apache.struts.chain.commands.

A. org.apache.struts.chain.commands.servlet packages.

The follo(ing table (ill listed out all the command ob?ects of Co1. Command Description

Select#ocale

Select a locale for this reBuest, if one hasn`t alread3 been selected, and place it in the reBuest.

Set,riginalU!#

Store the U!# of the original reBuest in the reBuest.

!eBuest+oEache

#f appropriate, set the following response headers< 7'ragma7, 7Eache2Eontrol7, and 7 0pires7.

!emoveEached(essages

!emoves an3 Action(essages ob>ect stored in the session under .lobals.( SSA. "* ) and .lobals. !!,!"* ) if the messages` isAccessed method returns true. %his allows messages to be stored in the session, displa3ed one time, and be released.

SetEontent%3pe

Set the default content t3pe Gwith optional character encodingH for all responses if reBuested.

SelectAction

$etermine the Action(apping associated with this path.

AuthoriIeAction

#f the mapping has a role associated with it, ensure the reBuesting client has the specified role. #f the client does not, raise an error and stop processing of the reBuest.

EreateActionForm

#nstantiate Gif necessar3H the ActionForm associated with this mapping Gif an3H and place it into the appropriate scope.

'opulateActionForm

'opulate the ActionForm associated with this reBuest, if an3.

_alidateActionForm

'erform validation Gif reBuestedH on the ActionForm associated with this reBuest Gif an3H.

Select#nput

#f validation failed, select the appropriate ForwardEonfig for return to the input page.

0ecuteEommand

-ookup and e0ecute a chain command if the current ActionEonfig is so2configured.

SelectForward

#f this mapping represents a forward, forward to the path specified b3 the mapping.

Select#nclude

Select the include uri Gif an3H for the current action mapping.

'erform#nclude

#f selected, include the result of invoking the path in this reBuest.

EreateAction

#nstantiate an instance of the class specified b3 the current Action(apping Gif necessar3H.

0ecuteAction

%his is the point at which 3our Action`s e0ecute method will be called.

0ecuteForwardEommand

-ookup and e0ecute a chain command if the current ForwardEonfig is so2configured.

'erformForward

Finall3, the process method of the !eBuest'rocessor takes the ActionForward returned b3 3our Action class, and uses it to select the ne0t resource Gif an3H. (ost often the ActionForward leads to the presentation page that renders the response.

The default Chain-config file supplied by the apache is as follo(s:-

450ml version678.97 5; 4F22 ^#d< chain2config.0ml A:8:@@ ?99Y28?29@ 8W<@?<5?\ niallp ^ -icensed to the Apache Software Foundation GASFH under one or more contributor license agreements. See the +,%#E file distributed with this work for additional information regarding cop3right ownership. %he ASF licenses this file to )ou under the Apache -icense, _ersion ?.9 Gthe 7-icense7HJ 3ou ma3 not use this file e0cept in compliance with the -icense. )ou ma3 obtain a cop3 of the -icense at

http<==www.apache.org=licenses=-#E +S 2?.9 Unless reBuired b3 applicable law or agreed to in writing, software distributed under the -icense is distributed on an 7AS #S7 BAS#S, /#%S,U% /A!!A+%# S ,! E,+$#%#,+S ,F A+) *#+$, either e0press or implied. See the -icense for the specific language governing permissions and limitations under the -icense. 22; 4F22 %his file contains definitions of the standard Ehain ,f !esponsibilit3 chains that emulate Struts 8.? processing functionalit3. %hese chains are defined in a catalog named 7struts7 so that the application can use the default catalog for its own purposes, without an3 potential for name clashes. ^#d< chain2config.0ml A:8:@@ ?99Y28?29@ 8W<@?<5?\ niallp ^ 22; 4catalog name67struts7; 4define name67lookup7 class+ame67org.apache.commons.chain.generic.-ookupEommand7=; 4F22 6666666666 Servlet Eomplete !eBuest Ehain 6666666666666666666666666 22; 4chain name67servlet2standard7; 4F22 stablish e0ception handling filter 22; 4command class+ame67org.apache.struts.chain.commands. 0ceptionEatcher7 catalog+ame67struts7 e0ceptionEommand67servlet2e0ception7=; 4lookup catalog+ame67struts7 name67process2action7 optional67false7=; 4lookup catalog+ame67struts7 name67process2view7 optional67false7=;

4=chain; 4F22 6666666666 Action 'rocessing chain 666666666666666666666666 22; 4chain name67process2action7; 4F22 %his chain attempts to emulate Gmost ofH the standard reBuest processing in the standard org.apache.struts.action.!eBuest'rocessor class, b3 performing the corresponding tasks in individual Eommands that are composable. %he following list defines a cross reference between the process&00 methods and the Eommands that perform the corresponding functionalit3< process(ultipart #ntegrated into servlet and legac3 classes process'ath SelectAction Gwhich also does process(appingH process 0ception 0ceptionEatcher = 0ceptionSandler process-ocale Select-ocale processEontent SetEontent%3pe process+oEache !eBuest+oEache process'reprocess -ookupEommand with optional67true7. (ultiple occurrences of this can easil3 be added, to support additional processing hooks at an3 point in the chain without modif3ing the standard definition. processEached(essages !emoveEached(essages process(apping SelectAction Gwhich also does process'athH process!oles AuthoriIeAction

processActionForm EreateActionForm process'opulate 'opulateActionForm process_alidate _alidateActionForm = Select#nput processForward SelectForward process#nclude Select#nclude = 'erform#nclude processActionEreate EreateAction processAction'erform 0ecuteAction 22; 4F22 -ook up optional preprocess command 22; 4lookup catalog+ame67struts7 name67servlet2standard2preprocess7 optional67true7=; 4F22 #dentif3 the -ocale for this reBuest 22; 4command class+ame67org.apache.struts.chain.commands.servlet.Select-ocale7=; 4F22 Set Gif neededH the U!# of the original reBuest 22; 4command class+ame67org.apache.struts.chain.commands.servlet.Set,riginalU!#7=; 4F22 Set Gif neededH no cache S%%' response headers 22; 4command class+ame67org.apache.struts.chain.commands.servlet.!eBuest+oEache7=; 4F22 Set Gif neededH the S%%' response content t3pe 22; 4command class+ame67org.apache.struts.chain.commands.servlet.SetEontent%3pe7=;

4F22 !emove messages cached in the Session 22; 4command class+ame67org.apache.struts.chain.commands.!emoveEached(essages7=; 4F22 #dentif3 the ActionEonfig for this reBuest 22; 4command class+ame67org.apache.struts.chain.commands.servlet.SelectAction7=; 4F22 AuthoriIe the selected ActionEonfig for this reBuest 22; 4command class+ame67org.apache.struts.chain.commands.servlet.AuthoriIeAction7=; 4F22 Ereate Gif neededH the ActionForm for this reBuest 22; 4command class+ame67org.apache.struts.chain.commands.EreateActionForm7=; 4F22 'opulate the ActionForm for this reBuest 22; 4command class+ame67org.apache.struts.chain.commands.servlet.'opulateActionForm7=; 4F22 _alidate the ActionForm for this reBuest 22; 4command class+ame67org.apache.struts.chain.commands.servlet._alidateActionForm7=; 4F22 Select the appropriate ForwardEonfig for return to input page 22; 4command class+ame67org.apache.struts.chain.commands.servlet.Select#nput7=; 4F22 -ookup and e0ecute a chain command if the current ActionEonfig is so2configured. 22; 4command class+ame67org.apache.struts.chain.commands. 0ecuteEommand7=; 4F22 Select the appropriate ForwardEonfig for action mappings that onl3 have an ActionForward 22; 4command class+ame67org.apache.struts.chain.commands.servlet.SelectForward7=; 4F22 Select the include uri Gif an3H for the current action mapping 22;

4command class+ame67org.apache.struts.chain.commands.Select#nclude7=; 4F22 'erform the include Gif neededH 22; 4command class+ame67org.apache.struts.chain.commands.servlet.'erform#nclude7=; 4F22 Ereate Gif neededH the Action for this reBuest 22; 4command class+ame67org.apache.struts.chain.commands.servlet.EreateAction7=; 4F22 0ecute the Action for this reBuest 22; 4command class+ame67org.apache.struts.chain.commands.servlet. 0ecuteAction7=;

4=chain; 4F22 6666666666 _iew 'rocessing chain 666666666666666666666666 22; 4chain name67process2view7; 4F22 -ookup and e0ecute a chain command if the current ForwardEonfig is so2configured. 22; 4command class+ame67org.apache.struts.chain.commands. 0ecuteForwardEommand7=; 4F22 Follow the returned ForwardEonfig Gif an3H 22; 4command class+ame67org.apache.struts.chain.commands.servlet.'erformForward7=; 4=chain; 4F22 6666666666 Servlet 0ception Sandler Ehain 666666666666666666666666 22; 4chain name67servlet2e0ception7;

4F22 %his chain is designed to be invoked Gb3 o.a.s.c. 0ceptionEatcherH if an unhandled e0ception is thrown b3 an3 subseBuent command in a processing chain Gincluding the one that invokes a Struts actionH. %he standard definition of this chain supports the e0ception mapping of Struts 8.8, but can be replaced in order to handle e0ceptions differentl3. 22; 4F22 0ecute the configured e0ception handler Gif an3H 22; 4command class+ame67org.apache.struts.chain.commands.servlet. 0ceptionSandler7=; 4F22 Follow the returned ForwardEonfig Gif an3H 22; 4command class+ame67org.apache.struts.chain.commands.servlet.'erformForward7=; 4=chain; 4=catalog; 0dding Bew Command &b8ects in 'truts Co. 2attern T%e 'truts new Co.6C%ain of .esponsibilit"7 structure gi#es us more flexibilit" to add our commands in between t%e re$uest processing and also wit% less effort 0ll t%e user needs is to extend org.apache.struts.chain.commands.Action0ommand1ase class and o#erride t%e execute() met%od in it

%he below e0ample will demonstrate how do we insert our own command ob>ects in the e0isting Struts Eo! without changing the actual flow and the Eomposeable!eBuest'rocessor will call the file implicitl3. For an3 t3pe of addition and deletion of the commands onl3 the chain2config.0ml file is changed and the Struts automaticall3 take care of the flow.

(-) Struts#con$ig%xml

450ml version678.97 encoding67#S,2::5V287 5; 4F$,E%)' struts2config 'UB-#E 72==Apache Software Foundation==$%$ Struts Eonfiguration 8.@== +7 7http<==struts.apache.org=dtds=struts2config"8"@.dtd7; 4struts2config; 4F22 666666666666666666666666666666666666666666666666 Form Bean $efinitions 22; 4form2beans; 4form2bean name67inputForm7 t3pe67com.visualbuilder.#nputForm7 =; 4=form2beans; 4F22 66666666666666666666666666666666666666666 .lobal 0ception $efinitions 22; 4global2e0ceptions;4=global2e0ceptions; 4F22 6666666666666666666666666666666666666666666 .lobal Forward $efinitions 22; 4global2forwards;4=global2forwards; 4F22 6666666666666666666666666666666666666666666 Action (apping $efinitions 22; 4action2mappings; 4action path67=submit7 t3pe67com.visualbuilder.SubmitAction7 name67inputForm7 scope67reBuest7 validate67false7 input67=inde0.>sp7=; 4=action2mappings; 4F22 6666666666666666666666666666666666666666666 Eontroller (apping $efinition 22; 4controller content%3pe67te0t=htmlJcharset6U%F2:7 locale67true7 debug6787 nocache67true7 processorElass67org.apache.struts.chain.Eomposable!eBuest'rocessor7 =; 4F22 6666666666666666666666666666666666666666 (essage !esources $efinitions 22; 4message2resources parameter67(essage!esources7 =; 4=struts2config;

(") +ustom+omman!%(a&a File

6ote5# The !ollowing !ile is created !or the command ob:ect. &! it returns true it means some e,ception occurred so it wont call the ne,t .ommand in the chain and returns to the input :sp !ile.

package com.visualbuilder.commandJ

import org.apache.struts.chain.commands.ActionEommandBaseJ import org.apache.struts.chain.conte0ts.ActionEonte0tJ

public class EustomEommand e0tends ActionEommandBase K U,verride public boolean e0ecuteGActionEonte0t ct0H throws 0ception K boolean result6trueJ S3stem.out.printlnG7Ealled the logic for the Eustom Eommand7HJ return falseJ L L

(3) +hain#con$ig%xml $ile

6ote 5# The !ollowing command will be added in the chain-con!ig.,ml !ile an"where in the processaction chain.

4F22 0ecute the Eustom Eommand for this reBuest 22; 4command class+ame67com.visualbuilder.command.EustomEommand7=; 'ecurit" in 'truts

%mplementation &or Container

anaged

%mplementation &or 'pplication

anaged

Authentication and AuthoriIation are specified in web.0ml. #t uses multiple authentication schemes, such as 'assword Authentication Form2 based Authentication Elient side $igital Eertificates etc.. !edirects are handled automaticall3. User data can be provided b3 a variet3 of stores 0ml file or flat files. #n tomcat the $ata is provided in %,(EA%"S,( =conf=tomcat2users.0ml

0tending !eBuest'rocessor Gin previous versionsHor AuthoriIeAction GAfter 8.@H. Eookies Using Servlet Filters. Using SS- &% with Struts to enable S%%'S.

The $olloAing is the Example to implement the +ontainer Speci$ic Security in Tomcat%

(-) tomcat#user%xml File

450ml version6`8.9` encoding6`utf2:`5; 4tomcat2users; 4role rolename67tomcat7=; 4role rolename67role87=; 4role rolename67admin7=; 4user username67tomcat7 password67tomcat7 roles67tomcat7=; 4user username67both7 password67tomcat7 roles67tomcat,role87=; 4user username67role87 password67tomcat7 roles67role87=; 4user username67visualbuilder7 password67test7 roles67admin7=; 4=tomcat2users; 6@8 Web.xml file

450ml version678.97 encoding67U%F2:75; 4web2app version67?.A7 0mlns67http<==>ava.sun.com=0ml=ns=>?ee7 0mlns<0si67http<==www.w@.org=?998=&(-Schema2instance7 0si<schema-ocation67http<==>ava.sun.com=0ml=ns=>?ee http<==>ava.sun.com=0ml=ns=>?ee=web2 app"?"A.0sd7; 4servlet; 4servlet2name;action4=servlet2name; 4servlet2class;org.apache.struts.action.ActionServlet4=servlet2class; 4init2param; 4param2name;config4=param2name; 4param2value;=/ B2#+F=struts2config.0ml4=param2value; 4=init2param; 4load2on2startup;?4=load2on2startup; 4=servlet; 4servlet2mapping; 4servlet2name;action4=servlet2name; 4url2pattern;C.do4=url2pattern; 4=servlet2mapping; 4welcome2file2list; 4welcome2file;inde0.>sp4=welcome2file; 4=welcome2file2list; 4securit32constraint; 4web2resource2collection; 4web2resource2name;application4=web2resource2name; 4url2pattern;=C4=url2pattern; 4=web2resource2collection; 4auth2constraint; 4role2name;admin4=role2name; 4=auth2constraint; 4=securit32constraint; 4login2config; 4auth2method;BAS#E4=auth2method; 4realm2name;securit3app4=realm2name;

4=login2config; 4securit32role; 4description;%esting the Application Securit34=description; 4role2name;admin4=role2name; 4=securit32role; 4=web2app;

9utput:-

%he following screen appears when 3ou tr3 to run the application. #t will ask for username and password and once 3ou enter 7visualbuilder7 as username and 7test7 as password then onl3 it will displa3 the pages of the application. T%e same wa" we extends t%e default be%a#iour of t%e 'truts application+ we can #alidate t%e user and aut%orize t%em to some resources in t%e application (e %a#e to 8ust mention t%e role for t%e resource in t%e struts-config xml file T%e following example will demonstrate t%e 0pplication managed securit" :f t%e user enters t%e role as admin onl" t%en t%e submit will be called ot%erwise t%e exception page is displa"ed on t%e screen

6;8 Struts-config.xml &ile

450ml version678.97 encoding67#S,2::5V287 5; 4F$,E%)' struts2config 'UB-#E 72==Apache Software Foundation==$%$ Struts Eonfiguration 8.@== +7 7http<==struts.apache.org=dtds=struts2config"8"@.dtd7; 4struts2config; 4F22 666666666666666666666666666666666666666666666666 Form Bean $efinitions 22; 4form2beans; 4form2bean name67inputForm7 t3pe67com.visualbuilder.#nputForm7 =; 4=form2beans; 4F22 66666666666666666666666666666666666666666 .lobal 0ception $efinitions 22; 4global2e0ceptions;4=global2e0ceptions; 4F22 6666666666666666666666666666666666666666666 .lobal Forward $efinitions 22;

4global2forwards;4=global2forwards; 4F22 6666666666666666666666666666666666666666666 Action (apping $efinitions 22; 4action2mappings; 4action path67=submit7 t3pe67com.visualbuilder.SubmitAction7 scope67reBuest7 validate67false7 name67inputForm7 input67=inde0.>sp7 roles34admin4DF 4=action2mappings; 4F22 6666666666666666666666666666666666666666666 Eontroller (apping $efinition 22; 4controller content%3pe67te0t=htmlJcharset6U%F2:7 locale67true7 debug6787 nocache67true7 processorElass67org.apache.struts.chain.Eomposable!eBuest'rocessor7 =; 4F22 6666666666666666666666666666666666666666 (essage !esources $efinitions 22; 4message2resources parameter67(essage!esources7 =; 4=struts2config;

(") chain#con$ig%xml File

6ote5# The onl" change with in this !ile is to replace line number * b" the line number A. (3) 0ustom0ommand.java File

6ote5# &! an" securit" check application is to be created in the struts *.D or higher then org.apache.struts.chain.commands. bstract uthori5e ction is to be e,tended but in case o! previous versions the ReCuest=roceesorEs method processRoles)+ is to be overridden to check the securit" setting o! the user.

package com.visualbuilder.commandJ

import org.apache.struts.action.ActionServletJ import org.apache.struts.chain.commands.AbstractAuthoriIeActionJ import org.apache.struts.chain.conte0ts.ActionEonte0tJ import org.apache.struts.chain.conte0ts.ServletActionEonte0tJ import org.apache.struts.config.ActionEonfigJ import org.apache.struts.util.(essage!esourcesJ import >ava0.servlet.http.SttpServlet!eBuestJ public class EustomEommand e0tends AbstractAuthoriIeAction K == 2222222222222222222222222222222222222222222222222222222 'rotected (ethods protected boolean isAuthoriIedGActionEonte0t conte0t, String[] roles, ActionEonfig mappingH throws 0ception K == #dentif3 the S%%' reBuest ob>ect ServletActionEonte0t servletActionEonte0t 6 GServletActionEonte0tH conte0tJ SttpServlet!eBuest reBuest 6 servletActionEonte0t.get!eBuestGHJ == Eheck the current user against the list of reBuired roles ifGreBuest.get'arameterG7user7H F6 null PP reBuest.get'arameterG7user7H.eBualsG7admin7H HK return GtrueHJ L == $efault to unauthoriIed return GfalseHJ L

protected String get rror(essageGActionEonte0t conte0t, ActionEonfig actionEonfigH K ServletActionEonte0t servletActionEonte0t 6 GServletActionEonte0tH conte0tJ == !etrieve internal message resources

ActionServlet servlet 6 servletActionEonte0t.getActionServletGHJ (essage!esources resources 6 servlet.get#nternalGHJ return resources.get(essageG7notAuthoriIed7, actionEonfig.get'athGHHJ L L

6ote5# Rest all the same as the previous composablereCuestprocessor e,ample !or the application.

Output5# 6ote5# &! the role admin is entered onl" then the submit action gets called otherwise the !ollowing e,ception comes to the screen.

You might also like