!The article has been taken from the book 'Struts 2 in Action'.If you have already read the book you need not to read it again
Throughout Struts 2 web applications, a need exists to link the Java runtime with the text-based world of HTML, HTTP, JSP, and other text-based view-rendering technologies. There must be a way for these text-based documents to reference runtime data objects in the Java environment. A common solution to this problem is the use of expression languages. As we’ve seen, Struts 2 uses OGNL for this purpose. We’ll now take the opportunity to cover the features of this expression language that you’ll most likely need to use in Struts 2 development.
Here are details
Page 1
Page 2
Page 3
Page 4
Page 5
Search from Struts2 Library
Showing posts with label OGNL. Show all posts
Showing posts with label OGNL. Show all posts
Thursday, September 25, 2008
OGNL 5
| <--PREVIOUS |
Advanced expression language features
As we’ve indicated, OGNL is a full-featured expression language. In fact, its features rival that of some fullfledged programming languages. In this section, we give a brief summary of some of the advanced features that you might use in a pinch. Some of these things are basic features of OGNL, but advanced in the context of Struts 2 usage. Take our terminology with a grain of salt. Also, we’ll make little effort to introduce use cases for these features. We consider their usage to be nonstandard practice. With that said, we also know that these power tools can save the day on those certain occasions that always seem to occur.
LITERALS AND OPERATORS
Like most languages, the OGNL expression language supports a wide array of literals. Table below summarizes these literals.
The only thing out of the ordinary would be the usage of both single and double quotes for string literals. Note, however, that a string literal of a single character must use double quotes, or it’ll be interpreted as a char literal. Table below shows the operators.
As you can see, all the usual suspects are here. This would probably be a good time to note that the OGNL expression language also allows multiple comma-separated expressions to be linked in a single expression. The following snippet demonstrates this process:
user.age = 10, user.name = "chad", user.username
This relatively meaningless example demonstrates an expression that links three subexpressions. As with many languages, each of the first two expressions executes and passes control on to the next expression. The value returned by the last expression is the value returned for the entire expression. Now we’ll see how to invoke methods with OGNL.CALLING METHODS
One power that many a JSP developer has wished for is the ability to call methods from the expression language. Until recently, this was rare. Actually, even the simplest property reference involves a method call. But those simple property references can invoke methods based on JavaBeans conventions. If the method you want to invoke doesn’t conform to JavaBeans conventions, you’ll probably need the OGNL method invocation syntax to get to it. This can sometimes get you out of a jam. It can also be useful in calling utility methods on helper beans. Table below shows how it works
Note that in this table we assume that a random number generator bean, named utilityBean, has been pushed onto the ValueStack prior to the evaluation of these OGNL expressions. With this bean in place, you can omit the object name in the OGNL expression, because it resolves to the ValueStack by default. First, we invoke the makeRandomNumber() method as you might expect. In the second example, we show that you can even use a full method invocation syntax to access JavaBeans properties, though you don’t have to. The result is no different than when using the simpler property notation.
We should note that these method invocation features of the OGNL expression language are turned off during the incoming phase of Struts 2 data transfer. In other words, when the form input field names are evaluated by the params interceptor, method invocations, as well as some other security-compromising features of the expression language, are completely ignored. Basically, when the params interceptor evaluates OGNL expressions, it’ll only allow them to point to properties onto which it should inject the parameter values. Nothing else is permitted.
ACCESSING STATIC METHODS AND FIELDS
In addition to accessing instance methods and properties, you can also access static methods and fields with the OGNL expression language. There are two ways of doing this. One requires specifying the fully qualified class name, while the other method resolves against the ValueStack. The syntax that takes the full class name is @[fullClassName]@[property or methodCall]. Here are examples of using full class names to access both a static property and a static method:
@manning.utils.Struts2PortfolioConstants@USER
@manning.utils.PortfolioUtilityBean@startImageWrapper()
Besides the @ signs, these are no different than normal property specification or method invocation. As we said, you can forgo specifying the class name if and only if your property or method will resolve on the ValueStack. Here we have the same two examples, but they assume that some object on the ValueStack exposes what they need. The syntax replaces the class name with the vs symbol, which stands for ValueStack:
@vs@USER
@vs@startImageWrapper()
That wraps up our coverage of some of the advanced features of OGNL. You’ll probably find yourself coming back to this quick reference in the future as you butt heads with some odd wall or two. Again, we recommend taking it easy on the OGNL power tools. However, we’re compelled to tell you that OGNL contains even more powerful features than we’ve felt comfortable divulging. For the full details, we refer you directly to the primary OGNL documentation found at www.ognl.org.
| <--PREVIOUS |
OGNL 4
| <--PREVIOUS | NEXT---> |
WORKING WITH MAPS
OGNL also makes referencing properties and elements of maps delightfully simple.
Table below shows a variety of syntax idioms for referencing Map elements and properties.
As you can see, you can do a lot with maps. The main difference here is that, unlike Lists, the value in the index box must be an object. If the value in the box is some sort of numeric data that would map to a Java primitive, such as an int, then OGNL automatically converts that to an appropriate wrapper type object, such as an Integer, to use as the key. If a string literal is placed in the box, that becomes a string object which will be used for the key. The last row in the table shows a special syntax for maps with strings as keys. If the key is a string, you may use this simpler, JavaBeans-style property notation.
As for other object types that you might use as a key, you ultimately have the full power of OGNL to reference objects that might serve as the key. The possibilities are beyond the capacity of the table format. Note that, as with the List syntax, the direct reference to the name property on the uncast map element depends on the configuration of the OGNL type conversion to know the specific element type of the map.
You can also create Maps on the fly with the OGNL literal syntax. Table below demonstrates this flexible feature.
As you can see, the syntax for creating a Map literal is similar to that for creating a List literal. The main difference is the use of the # sign before the leading brace.
Warning
OGNL uses the # sign in a few different ways. Each is distinct. The uses are completely orthogonal, so you shouldn’t be confused as long as you’re alert to the fact that they’re different use cases. In particular, this isn’t the same use of the # sign as we saw when specifying a nonroot object from the ActionContext for an expression to resolve against. We’ll also see another use of the # sign in a few moments.
Dynamic maps are especially useful for radio groups and select tags. The Struts 2 tag libraries come with special tags for creating user interface components. Just note that you can use literal maps to feed values into some of the UI components. If you wanted to offer a true/false selection that displays as a Yes/No choice, #{true : 'Yes', false : 'No'} would be the value for the list attribute. The value for the value attribute would evaluate to either true or false.
FILTERING AND PROJECTING COLLECTIONS
OGNL supports a couple of special operations that you can conduct on your collections. Filtering allows you to take a collection of objects and filter them according to some rule. For instance, you could take a set of users and filter them down to only those who’re more than 20 years old. Projection, on the other hand, allows you to transform a collection of objects according to some rule. For instance, you could take a set of user objects, having both first and last name properties, and transform it into a set of String objects that combines the first and last name of each user into a single string. To clarify, filtering takes a Collection of size N and produces a new collection containing a subset of those elements ranging from size 0 to size N. On the other
hand, projecting always produces a Collection with exactly the same number of elements as the original Collection; projecting produces a one-for-one result set.
The syntax for filtering is as follows:
collectionName.{? expression }
In the expression, you can use #this to refer to the object from the collection being evaluated. This is another distinct use of the # sign. The syntax for projection is as follows:
collectionName.{ expression }
Table below shows some examples of both of these useful operations in action.
As you can see, each filtering or projection simply returns a new collection for your use. This convenient notation can be used to get the most out of a single set of data. Note that you can combine filtering and projection operations. That about covers it for aspects of OGNL that are commonly used in Struts 2. In the next section, we’ll cover some of the advanced features that might help you out in a pinch, but, still, we recommend keeping it simple unless you have no choice.
| <--PREVIOUS | NEXT---> |
Monday, September 22, 2008
OGNL 3
| <--PREVIOUS | NEXT---> |
WORKING WITH JAVA COLLECTIONS
Java Collections are a mainstay of the Java web developer’s daily workload. While the JavaBeans specification has always supported indexed properties, working with actual Java Collections, while convenient in the Java side, has always been a hassle in contexts such as JSP tags. One of the great things about the OGNL expression language is its simplified handling of Collections. We’ll now summarize the OGNL syntax used to reference these properties.
WORKING WITH LISTS AND ARRAYS
References to lists and arrays share the same syntax in OGNL. Table below summarizes the basic syntax to access list or array properties.
As the table demonstrates, the syntax for referencing elements or properties of
lists and arrays is intuitive. Basically, OGNL uses array index syntax for both. This
makes perfect sense, due to the ordered, indexed nature of lists.
A couple of things warrant remarks. First, the reference to the name property of a list element assumes something important. As we know, Java Lists are type-agnostic. In Java, we always have to cast the element to the appropriate type, in this case User, before we try to reference the name property. This syntax assumes that has been done. We should also note that you can reference other properties, such as length and size, of arrays and lists. In particular, note that OGNL makes the List class’s non-JavaBeans-conformant size method answer to a simple property reference. This is something nice that OGNL provides as free service to its valued customers!
OGNL also allows you to create List literals. This can be useful if you want to directly create a set of values to feed to something like a select box. Table below shows the syntax for creating these literals.
You probably only want to do this with trivial data, since creating complex data in the view layer would make a mess. Nonetheless, sometimes this will be the perfect tool for the job.
| <--PREVIOUS | NEXT---> |
OGNL 2
| <--PREVIOUS | NEXT---> |
Expression language features commonly used in Struts 2
First, we should review the most common uses of the OGNL expression language in Struts 2 development. In this section, we’ll look at how the expression language serves its purpose for most daily development. Basically, we use it to map the incoming data onto your ValueStack objects, and we use it in tags to pull the data off of the ValueStack while rendering the view. Let’s look at the expression language features most commonly used in this work.
REFERENCING BEAN PROPERTIES
First of all, we need to define what makes an expression. The OGNL expression language refers to something called a chain of properties. This concept is simple.
Take the following expression:
person.father.father.firstName
This property chain consists of a chain of four properties. We can say that this chain references, or targets, the firstName property of person’s grandfather. You can use this same reference both for setting and getting the value of this property, depending on your context.SETTING OR GETTING?
When we use OGNL expressions to name our form input parameters, we’re referring to a property that we’d like to have set for us. The following code snippet shows the form from our Struts 2 Portfolio application’s Registration.jsp page:
<s:form action="Register">
<s:textfield name="username" label="Username"/>
<s:password name="password" label="Password"/>
<s:textfield name="portfolioName" label="Enter a portfolio name."/>
<s:submit/>
</s:form>
The name of each input field is an OGNL expression. These expressions refer to, for example, the username property exposed on the root OGNL object. As we’ve just learned, the root object is our ValueStack, which probably contains our action object and perhaps a model object. When the params interceptor fires, it’ll take this expression and use it to locate the property onto which it should set the value associated with this name. It’ll also use the OGNL type converters to convert the value from a string to the native type of the target property. There is one common complication that arises when the framework moves data onto the properties targeted by the OGNL expressions.
Take the deeper expression:
user.portfolio.name
If a request parameter targets this property, its value will be moved onto the name property of the portfolio object. One problem that can occur during runtime is a null value for one of the intermediate properties in the expression chain. For instance, what if the user hasn’t been created yet? If you recall, we’ve been omitting initialization for many of our properties in our sample code. Luckily, the framework handles this. When the framework finds a null property in a chain that it needs to navigate, it’ll attempt to create a new instance of the appropriate type and set it onto the property. However, this requires two things on the developer’s part. First, the type of the property must be a class that conforms to the JavaBeans specification, in that it provides a no-argument constructor. Without this, the framework can’t instantiate an object of the type. Next, the property must also conform to the JavaBeans specification by providing a setter method. Without this setter, the framework would have no way of injecting the new object into the property. Keep these two points in mind and you’ll be good to go.
In addition to targeting properties onto which the framework should move incoming data, we also use OGNL when the data leaves the framework. After the request is processed, we use the same OGNL expression to target the same property from a Struts 2 tag. Recall that the domain model data stays on the ValueStack from start to finish. Thus, tags can read from the same location that the interceptors write.
The following snippet shows the property tag doing just this:
<h5>Congratulations! You have created </h5>
<h3>The <s:property value="portfolioName" /> Portfolio</h3>
In this snippet, we see that the Struts 2 property tag takes an OGNL expression as its value attribute. This expression targets the property from which the property tag will pull the data for its rendering process, a simple process where it merely converts the property to a string and writes it into the page. As you can see, OGNL expressions, as commonly used in Struts 2, serve as pointers to properties. Whether the use case is writing to or reading from that property is up to the context. Though not nearly as common, you can also use the fuller features of the OGNL expression language, operators in particular, to write self-contained expressions that, for instance, set the data on a property themselves. But, as this is outside of the normal Struts 2 use case, we’ll only discuss such features in the advanced section.
| <--PREVIOUS | NEXT---> |
OGNL
Struts2 and OGNL
Throughout Struts 2 web applications, a need exists to link the Java runtime with the text-based world of HTML, HTTP, JSP, and other text-based view-rendering technologies. There must be a way for these text-based documents to reference runtime data objects in the Java environment. A common solution to this problem is the use of expression languages. As we’ve seen, Struts 2 uses OGNL for this purpose. We’ll now take the opportunity to cover the features of this expression language that you’ll most likely need to use in Struts 2 development.
What is OGNL?
The Object-Graph Navigation Language exists as a mature technology completely distinct from Struts 2. As such, it has purposes and features much larger than its use within Struts 2. OGNL is an expression and binding language. In Struts 2, we use the OGNL expression language to reference data properties in the Java environment, and we use OGNL type converters to manage the type conversion between HTTP string values and the typed Java values.
In this last section, we’ll try to summarize the syntax and some of the more useful features of the OGNL expression language. First we’ll cover the syntax and features most commonly used in Struts 2 development. Then we’ll cover some of the other OGNL features that you might find handy. OGNL has many of the features of a full programming language, so you’ll find that most everything is possible. Also note that this section doesn’t try to be a complete reference to OGNL. If you want more OGNL power, visit the website at www.ognl.org for more information.
Keep those JSPs clean! While OGNL has much of the power of a fullfeatured language, you might want to think twice before squeezing the trigger. It’s a well-established best practice that you should keep business logic out of your pages. If you find yourself reaching for the OGNL power tools, you might well be pulling business logic into your view layer. We’re not saying you can’t do it, but we recommend giving it a moment’s thought before complicating your view pages with too much code-style logic. If you’re getting complex in your OGNL, ask yourself if what you’re doing should be done in the action or, at least, encapsulated in a helper bean that you can use in your page.
Subscribe to:
Posts (Atom)