>> Delivering Value
Struts 2.0 Session - 5 May, 2009 Presentation By Training & Development
Introduction Good Evening Guys! Welcome back to the Struts 2 training program. We are on Day 5, the end of first week of Struts training. We have seen 5 10% of Struts 2
As I have always been maintaining if you lay a strong foundation by learning the concepts thoroughly the rest will just be a cake walk So, the point is, the first 20% of Struts 2 is really important and the rest is just based on this 20%
2
Introduction On Day 1 we learned the history of Web Let us do a quick overview on what we have learned so far
Applications starting from HTTP till Struts 2
On Day 2 we learned about a few important
concepts which form the basis of Struts 2 namely Filters, Command pattern, Annotations and Dependency Injection
On Day 3 we learned the background of how
Struts 2 was formed. We also setup the environment and did two great projects namely Hello World and Ph.D in Mathematics
On Day 4 we dissected the Hello World
Project and Ph.D Project to know the internals. We also got introduced to important concepts called Interceptors, Value Stack and OGNL
Let us now do a random recap on the first 4
days
3
Mr. Thinker What are the main problems with Servlets?
Separation of Concern is nonexistent. HTML code is embedded in Java making it difficult to maintain
4
Dumbo Vs. Jumbo Jumbo! Does JSPs completely replace Servlets?
No Dumbo. JSPs still get converted to Servlets. So, for each JSP we see, there will be a corresponding servlet in the background
5
Mr. Thinker What are the problems with JSPs?
Separation of concern is still a problem. Java code is embedded in HTML which is equally undesirable
6
Mr. Thinker How do Filters help?
Repetitive tasks can be moved to a Filter. (Eg. Session checking, authentication etc)
7
Mr. Thinker How is dependency injection achieved generally?
Dependency Injection is achieved generally by performing Setter Injection.
8
Dumbo Vs. Jumbo Command Pattern is basis of what framework?
Command Pattern is the basic building of Struts Framework
9
Mr. Thinker What is the ancestor framework of Struts2?
Webwork
10
Dumbo Vs. Jumbo Web Work is based on what Framework?
X Work
11
Mr. Thinker X Work implements which design pattern?
Command Pattern
12
Mr. Thinker What is the first component in Struts 2 that receives the request from the client.
FilterDispatcher. It is a Filter class
13
Dumbo Vs. Jumbo What is the name of the file that contains all the configuration details related to the framework?
struts.xml
14
Mr. Thinker Can action class be a normal Java class?
Yes, the action class can be a normal java class without extending or implementing anything else
15
Mr. Thinker What is the return type of the execute method in Action class?
The return type is String
16
Dumbo Vs. Jumbo With what is the return of action class checked?
The return of action class is checked with the action element’s result element in the struts.xml file
17
Mr. Thinker Interceptors are similar to what?
Interceptors are similar to Filters
18
Mr. Thinker Where are interceptors configured?
Interceptors are configured in struts.xml
19
Mr. Thinker Where is the default setting of interceptor set?
The default interceptor to be used is set in a file called “strutsdefault.xml”
20
Dumbo Vs. Jumbo What is the difference between an Interceptor and an Interceptor Stack?
An interceptor stack is a stack of interceptors. What a great answer!!
21
Dumbo Vs. Jumbo What is the order in which the interceptors get executed in an interceptor stack?
The interceptors in the interceptor stack are executed in the order in which they are defined in the Interceptor stack
22
Mr. Thinker What is OGNL?
Object Graph Notation Language
23
Mr. Thinker What is value stack?
Value stack is a stack of objects
24
Dumbo Vs. Jumbo I have an object called PurchaseOrder inside which I have Asset inside which I have Invoice. Inside Invoice I have invoiceNo. How can I access invoiceNo using OGNL?
purchaseOrder.asset.invoice.invoiceNo
25
Mr. Thinker What is the order of objects in value Stack?
Temporary Objects, Model Object, Action Object, Named Object (Application, session, request etc)
26
Mr. Thinker What is the name of the interceptor that sets the variables of action class from the screen fields?
ParamsInterceptor
27
Mr. Thinker What is the kind of dependency Injection when the params interceptor sets the value of action variables from screen fields?
Setter Injection
28
Ms. Natasha Oh My God! That was a very thorough recap!! Good Job guys. Now go back to your work. You can always come back when required Now let us give some time to the trainer to start what he has to say today ! Action, Action , More Action!
29
Primary responsibilities of Action
30
Primary responsibilities of Action Actions encapsulate the unit of work Actions provide locus for data transfer Actions return control string for result routing
31
Encapsulating the unit of work Struts 2 is an action based framework The primary purpose of the action then is to fulfill the business logic. (i.e.
serve as the starting point of model layer)
The primary purpose of the execute method is exactly this. Executing
business logic
32
Dumbo Vs. Jumbo Just one quick question. I know that execute method should purely only contain the business logic. But before executing the business logic there might be a need for other things. One of them is populating the business objects which I know is handled by the params interceptor. But how about any other validations that need to happen before executing the business logic methods?
That’s not a bad question considering your stature. Yes, validations are definitely a likely requirement before executing the business logic. Struts 2 is not so dumb to not address this issue. This is addressed. This will be addressed later on today. But for now, listen to what he has to say. The execute method should only contain business logic
33
Locus for data transfer Being the model component, action is responsible for taking around the
model data all around
As we have already seen, action class has model variables which are class
level variables
Hence it is so easy to access these model data from within the action class We have also already seen that throughout the framework it is easy to access
these data because of the magic called “Value Stack”
34
Returning control string for result routing After executing the business logic it is the action’s responsibility to inform
which page should be displayed
For this, the action method uses the return string The return string is checked against the struts.xml’s action element’s result
element and the corresponding page is displayed to the user
35
Dumbo Vs. Jumbo That was good explanation about action. Tell me something. You had mentioned that Struts 2 is an action based framework. Hence Action class is the hero even though there are other character artists like value stack, OGNL, interceptors etc. Being the Hero, I was expecting more help from the framework in this area. But I do not see any help being rendered by the framework in the action class. Action class is a java class entirely written by the developer. So, what is the fun!!!
I know you are always pessimistic and sarcastic. But there is an answer from Struts 2. Do not worry. Struts 2 provides a lot of help in the action layer. Stay tuned to know more
36
The Action Interface The Action Interface is the first answer to Dumbo’s question Action Interface is provided by the framework The interface contains one method called execute The package is “com.opensymphony.xwork2.Action” Your actions can implement this Action Interface in order to tap the
benefits provided by this interface
37
Constituents of Action Interface The Action Interface provides just one method as follows – String execute( ) throws Exception The Action Interface provides various constants: – public static final String ERROR "error" – public static final String INPUT "input" – public static final String LOGIN "login" – public static final String NONE "none" – public static final String SUCCESS "success" That is all what the Action Interface provides
38
Dumbo Vs. Jumbo Well!! Are you fooling me? What is so great about this interface? It just provides one method which anyway I am using and few string constants. First tell me what are these string constants and then tell me something better than this action interface.
Answer to your question: These string constants can be used by the developer as return strings in the execute method. So, instead of saying return “success”, you can say return SUCCESS. Just a convenient method. Similarly the framework uses these as well. Answers to your second question are the next few slides
39
The ActionSupport class Dumbo is very true in stating that Action interface is not so great.
Fortunately we have an answer
ActionSupport is the best example of how flexible and easy the framework
is
ActionSupport provides implementations of various important interfaces
including Action
If your actions extend this class, you automatically gain access to these
important default behaviors of various interfaces
Interceptors combine with ActionSupport class to provide us with a great
channel to solve complex problems
40
The ActionSupport class (Contd.) Interceptor
+
Action Support
Great Combination to solve complex problems
• The following provides the relationship between the components that we saw
now.
«interface» Action
ActionSupport
YourAction
41
Exercise • Change the Address Capture project such that it uses ActionSupport
class
42
The ActionSupport class The following are the interfaces that the ActionSupport class implements: – Action – Validateable – ValidationAware – TextProvider – LocaleProvider
43
Exercise We already have a Person class In the Person class add one more attribute called age In the screen where you captured the address, capture the age of the
person also
Now run this program and display the age in the result screen apart
from the addresses that you already displaying
44
Dumbo Vs. Jumbo We have seen the details of Action Support class. But how do we use it in practice? What are the advantages of using this class?
There are lots of advantages. Yes that would be the next topic for the day
45
Validation The action support class implements an interface called Validateable which
has a method called validate( )
If your action extends ActionSupport you can override this validate method
to include any validations
46
Exercise In the Address Capture Application, include the following
in the action class:
public void validate() { if (this.getPerson().getAge() < 18) { this.addActionError("The Age should be greater than 18. Sorry!!"); } } Now run the Address Capture application. Enter the age
as a value less than 18
Observe the behavior
47
Exercise Now add the following element to the struts action
element for the address capture action
/AddressCapture.jsp Now run the address capture application. Enter the age
as a value less than 18
Observe the behavior Now add the following to AddressCapture.jsp inside the
form tag
<s:actionerror /> Now run the address capture application. Enter the age
as a value less than 18
48
Dumbo Vs. Jumbo Lot of magic has happened over the past few minutes. Naturally I would like to know what happens internally
That’s why the trainer is here
49
The Internals of the Validation flow Let us take a close look at struts-default.xml
... < interceptor-stack name="defaultStack"> ... ... <param name="excludeMethods">input,back,cancel,browse ...
50
The Internals of the Validation flow (Contd.) When the user submits the request from the browser, struts-default.xml is referred The default stack is mentioned as defaultStack So each and every interceptor in this stack is invoked one by one When the params interceptor is reached, the screen values are copied to Action
class variables
After params interceptor, somewhere down the line, there is an interceptor called
DefaultWorkflowInterceptor with a reference called “workflow”
So, the doIntercept method of DefaultWorkflowInterceptor is called This method in turn invokes the validate method of OUR ACTION Please note that the validate method does not return any value The validate method just puts an error message using addActionError method 51
The Internals of the Validation flow (Contd.) The doIntercept method after invoking validate method checks if there any errors
raised, by using hasErrors method
If there are errors then the workflow is cut short. The action method is not
executed. Instead the workflow is returned back to the page by passing the return string as “input”
If there are no errors, then the next interceptor is invoked
52
Dumbo Vs. Jumbo Things are beginning to fall in place but I have so many questions. What is the importance of the two interfaces Validateable and ValidationAware? Are these used anywhere apart from the ActionSupport class
Yes of course. The trainer will show you the source code of DefaultWorkflowInterceptor where you can see that the interfaces Validateable and ValidationAware are used to typecast the Action class to these interface types and then invoke the validate and hasErrors methods respectively. Now you know the power of interfaces and type casting!!
53
Dumbo Vs. Jumbo Yes. Cool man. My next question. You remember when we did our exercise, there were a few errors which gradually got corrected by themselves. As soon as I just added the validate method and ran the application I got some exception that there is no result definition blah blah blah. What was that?
A Small correction. The errors did not vanish by themselves. To answer your question, whenever a validation error is raised (like in our case), the interceptor returns a string called “input”. You can then catch this string in the struts.xml and provide a corresponding page. When we first ran the application, there was no result with name as input. As a result it threw an exception. After we added a new result row with name as input, that issue was resolved 54
Dumbo Vs. Jumbo But then we faced the next problem. The system just displayed the input page but did not show any error message or nothing. It just showed whatever I entered. Is not a bug in struts?
No, definitely not. Since we have mentioned this jsp in our result element the control is passed back to this page. However we did not specify to the struts framework that the error should be displayed. We then added the code <s:actionerror /> which tells the framework that the error should be displayed on the page. So, the error was promptly displayed after we included this code in the action
55
Dumbo Vs. Jumbo Wow man. That was great explanation. One last question. I was surprised to see that whatever I entered originally was still there even after the error was raised. How are the values maintained over requests.
That is the power of value stack. We saw that the params interceptor is responsible for passing the values from screen to action. This gets executed before validation. Hence the values will be available in the action class. When the error is thrown, the JSP page retrieves the value from the value stack which in turn gets it back from the action class. So, the values are still there. So, it is automatic. You do not have to do anything extra to achieve this functionality. 56
Dumbo Vs. Jumbo Technology has improved so much aaa!! Now what next!! BTW, the error message is hard coded in the action class. It’s a bad practice you know. Is there a better way?
Yes, that’s our next topic
57
Resource Bundles and Internationalization As already seen, the ActionSupport class implements TextProvider and
LocaleProvider interfaces
These are the interfaces used for internationalization and resource bundling Let us now see how we can take advantage of this provision from Struts
58
Exercise Create a properties file called struts.properties under default package Add the following: – struts.custom.i18n.resources=guest Create a properties file called guest.properties under default package Add the following: – address.age.error = Age should be greater than 18!! In the Action class instead of hardcoding the error use the following: – this.addActionError(this.getText("address.age.error"); Run and observe the behavior Any error messages can be added in future by just adding a set of key
value pairs in the guest.properties and correspondingly referring them from the action class 59
Dumbo Vs. Jumbo All is well. But is it mandatory that the resource bundle should be named as guest. Can I name it as whatever I want?
Good Man. One more question. I see that the error message is displayed at the top of the page. Is there a way I can have error messages displayed above each field instead of at the top
Yes it is possible. Let us do this exercise to understand:
Yes of course. That’s why we have struts.properties. you can name it as whatever in struts.properties instead of guest
60
Exercise Note down the name of the age field in the Address Capture JSP Now in the action class instead of the addActionError do the
following: – this.addFieldError(“”,this.getText("add ress.age.error"));
Run and observe the behavior You will find that the error message is displayed above the Age field
instead of at the top
61
Exercise Add a new field called salary Add a validation for this field as follows: – If Age > 25 then Salary is mandatory This should be displayed at the field level If there are no validation errors, the next page should display all
details including Salary
62
Session 5 We are coming to the end of an interesting session on Struts. 2.. Stay tuned to learn more interesting concepts in Struts 2 next week. Have a great weekend.
63
Session 5 Thank You !
64