Search from Struts2 Library

Sunday, September 21, 2008

Bean tag

The bean tag is like a hybrid of the set and push tags. The main difference is that you don’t need to work with an existing object. You can create an instance of an object and either push it onto the ValueStack or set a top-level reference to it in the Action-Context. By default, the object will be pushed onto the ValueStack and will remain there for the duration of the tag. In other words, the bean will be on the ValueStack for the execution of all tags that occur in between the opening and closing tags of the bean tag. If you want to persist the bean longer than the body of the tag, you can specify a reference name for the bean with the var attribute. This reference will then exist in the ActionContext as a named parameter accessible with the # operator for the
duration of the request.
There are a few requirements on the object that can be used as a bean. As you might expect, the object must conform to JavaBeans standards by having a zero-argument constructor and JavaBeans properties for any instance fields that you intend to initialize with param tags. We’ll demonstrate all of this, including the use of param tags, shortly. First, table below details the attributes for the bean tag.



Our first example demonstrates how to create and store the bean as a named parameter in the ActionContext. In this case, we’ll create an instance of a utility bean that helps us simulate a for loop. This counter bean comes with Struts 2. For this example, we’ll create the bean and use the var attribute to store it in the ActionContext as a named parameter. The following markup shows how this is done:

<s:bean name="org.apache.struts2.util.Counter" var="counter"> <s:param name="last" value="7"/> </s:bean> <s:iterator value="#counter"> <li><s:property/></li> </s:iterator>
Figure below how this markup will render in the result page.

Now let’s look at how it works. The bean tag’s name attribute points to the class that should be instantiated. The var attribute, repeating a common Struts 2 tag API pattern, specifies the reference name under which the bean will be stored in the ActionContext. In this case, we call the bean counter and then refer to that bean instance in the iterator tag’s value attribute with the appropriate OGNL. Since the bean is in the ActionContext, rather than on the ValueStack, we need to use the # operator to name it, resulting in the OGNL expression #counter. The bean tag is the first of a few tags we’ll explore that are parameterized. In the case of the counter, we can pass in a parameter that sets the number of elements it will contain, in effect setting the number of times the iterator tag will execute its body markup.

TIP:
The var attribute occurs in the usage of many Struts 2 tags. Any tag that creates an object, the bean tag being a good example, offers the var attribute as a way to store the object under a name in the ActionContext. The name comes from the value given to the var attribute. Most tags that offer the var attribute make it optional; if you don’t want to store the created object in the ActionContext, it will simply be placed on the top of the ValueStack, where it’ll remain during the body of the tag.
WARNING!
If you’re using a version of Struts 2 that is older than 2.1, the var attribute should be replaced with the id attribute.

Now that the counter bean has been created and stored, we can use it from the Struts 2 iterator tag to create a simulation of for loop-style logic. The bean tag doesn’t have to be used with the iterator tag; it’s in this example because the counter bean is meant to be used with the iterator tag. The counter bean works in combination with the iterator tag, which we’ll cover shortly, to provide a pseudo for loop functionality. Generally, the iterator tag iterates over a Collection, thus its number of iterations is based upon the number of elements in the Collection. For a for loop, we want to specify a number of iterations without necessarily providing a set of objects. We just
want to iterate over our tag’s body a certain number of times. The counter bean serves as a fake Collection of a specified number of dummy objects that allows us to control the number of iterations. In the case of our example, we do nothing more than print a number to the result stream during each iteration. Note that we use the property tag without any attributes; this idiom will simply write the top property on the ValueStack to the output.

NOTE
:
The bean tag allows you to create any bean object that you might want to use in the page. If you want to make your own bean to use with this tag, just remember that it needs to follow javaBeans conventions on several important points. It has to have no-argument constructor, and it must expose JavaBeans properties for any parameters it’ll receive with the param tag, such as the counter bean’s last parameter.




Now, let’s look at how to use the bean tag to push a newly created bean onto the ValueStack rather than store it in the ActionContext. While we’re at it, we’ll further demonstrate the use of the param tag to pump parameters into our homeroasted bean. This is all simple. To use the ValueStack as the temporary storage location for our bean, we just use an opening-and-closing-style tag configuration. All tags inside the body of the bean tag will resolve against a ValueStack that has an instance of our JokeBean on top. Here’s the example:

<s:bean name="manning.utils.JokeBean" > <s:param name="jokeType">knockknock</s:param> <s:property value="startAJoke()"/> </s:bean>

In this example, also from the chapter 6 sample code, we create an instance of a utility bean that helps us create jokes. If you look at the sample application, you’ll see that this outputs the first line of a joke—“knock knock.” Though inane, this bean does demonstrate the sense of utility beans. If you want to provide a canned joke component to drop into numerous pages, something that unfortunately does exist in the real world, you could embed that functionality into a utility bean and grab it with the bean tag whenever you liked. This keeps the joke logic out of the core logic of the action logic. This markup demonstrates using the bean tag to push the bean onto the
ValueStack rather than place it as a named reference in the ActionContext. Note that we no longer need to use the var attribute to specify the reference under which the bean will be stored. When it’s on top of the ValueStack, we can just refer to its properties and methods directly. This makes our code concise. The bean is automatically popped from the stack at the close tag.
Using the bean is easy. In this case, we use the OGNL method invocation syntax, startAJoke(). We do this just to demonstrate that the bean tag doesn’t have to completely conform to JavaBeans standards—startAJoke() is clearly not a proper getter.
Finally, note that we pass a parameter into our JokeBean that controls the type of joke told by the bean. This parameter is automatically received by our bean as long as the bean implements a JavaBeans property that matches the name of the parameter. If you look at the source code, you can see that we’ve done this. FYI: this joke bean also supports an "adult" joke mode, but you’ll probably be disappointed; it’s quite innocuous.
The bean tag is ultimately straightforward. What you want to be clear about is the difference between the use of the var attribute to create a named reference in the ActionContext, and the use of the opening and closing tags to work with the bean on the ValueStack. The real trick here is in understanding the ValueStack, Action-Context, and how OGNL gets to them. That’s why we began this chapter with a thorough introduction to these concepts. If you’re confused, you might want to refer back to those earlier sections.
With those fundamental concepts in place, the conventions of the bean tag, and
other similar tags, should be straightforward enough. If you have all this straight, congratulate
yourself on a mastery of what some consider to be the most Byzantine aspect of Struts 2

No comments: