CHAPTER 9 Posing conditions with tags Based on these requirements, we see the need for the following two tags to be developed: TestTag The role of the TestTag is to pose a condition on the value of a reference object. If this condition is evaluated to be true the body of the TestTag is added to the response that goes to the user. WithTag The role of WithTag is to wrap one or more of the TestTags and man age them. This includes obtaining and handing over the reference object that the TestTags test (as sketched in figure 9.1), and serving as a repository for information that Figure 9.1 WithTag exposing a ReferenceObject for two nested all the TestTags need to share (e.g., TestTags to refer to and evaluate if one of the test tags was evaluated to be true). Additionally, WithTag selects one of two test evaluation policies: The first allows only the first TestTag that was evaluated as true to be added to the response; the second allows any TestTag evaluated as true to be added to the response. To help clarify what these tags do, let s look at an example in which a JSP uses them (listing 9.2): Listing 9.2 Using our new conditional tags with a Boolean value < % Boolean b = new Boolean(true); b d true d false B The object, in this case a Boolean, on which the condition will be evaulated. C Usage of the cond:with tag, specifying that the object for condition evaluation is b. D Usage of the test tag, with the condition specified with a special syntax (discussed later).
Note: If you are looking for good and high quality web space to host and run your application check Lunarwebhost Tomcat Web Hosting services
The advanced condition tag family Based on these complications, it would appear that our initial IfTag is too simplistic to be properly built upon and extended. We can conclude from this that we should implement a new set of tags to cope with complex conditions (including else clauses). Building this more flexible tag library is the subject of the next section. 9.3 The advanced condition tag family Following the discussion in the previous section, an advanced condition tag should: Allow the developer to create the equivalent of a chain of Java if-else-if statements that are based on the same object. Provide a straightforward syntax for the JSP developer (for example, obviate the entering of needless IDs and object references, even if they want to query a certain object more than once). Eliminate the simple and sometime useless conversion of the conditioned object to a boolean, and let the developer specify a more exact condition (such as: the object is a String that contains the sub-string MSIE ). Considering these requirements, it is clear that what we are looking for is not a single complex tag but a family of tags working together. A single tag, as powerful as it might be, is going to be too complex to develop and use. The library we will develop, which we ll call the advanced condition tags, will have to obtain the Java object on which we want to perform conditions, and evaluate various conditions on the object s values. Also, we want it to have more than one conditional fragment of JSP to be evaluated if its condition is true. For example, we want to have the following ability as demonstrated in this pseudo JSP fragment: < %--Define the object that we are going to query --%> < %--Some JSP is evaluated here--%> < %-- Some other JSP is evaluated here--%> If both tests are evaluated as true, we want both to run (not exactly an if-else behavior but very useful).
Note: If you are looking for good and high quality web space to host and run your application check Lunarwebhost Java Web Hosting services
CHAPTER 9 Posing conditions with tags The problem with the above code fragment is that it does not constitute valid JSP syntax (because JSP tags follow the rules for XML tags). The issue with this fragment is that tag must be closed. An alternative is: Some JSP if the condition is true. Some JSP if the condition is false. Another possible alternative is: Some JSP if the condition is true. Some JSP if the condition is false. Though legal JSP, both options have problems that render them undesirable. Namely: In the first option, there is no implicit link between if and else. To rectify this, we had to link if and else explicitly by supplying an id in and referencing this id in . This syntax is somewhat messy and places an unneeded burden on the JSP developer. The second option, though possible if we use a BodyTag to implement our and tags, runs the risk of introducing unwanted side effects. Since resides within the body of , the must always evaluate its body to determine whether a exists within it. Hence, the body of the is evaluated, even if the condition is false (in which case, it would be evaluated and ignored). This is a problem, because evaluating the body even when the condition is false will cause any scriptlets or tags within the body to be executed, potentially causing side effects like throwing an exception or wasting processing time. It s similar to having a standard Java if statement that executes both branches when evaluated, but returns the results of only the proper branch. In both cases, the type of condition you impose is bound to be simple since the number of attributes in the tags is becoming unmanageable (we need attributes to point to the property/object, to link the if and else, and to specify a complex condition).
Note: If you are looking for good and high quality web space to host and run your application check Lunarwebhost Java Web Hosting services
IfTag A simple condition tag } protected boolean evalBoolean(Object o) { if(o instanceof Boolean) { d return ((Boolean)o).booleanValue(); } if(o instanceof Number) { return ((Number)o).intValue() != 0; } return new Boolean(o.toString()).booleanValue(); } } B Sends the pointed variable (our condition) to boolean evaluation. C Based on the returned value includes the body (if true) or excludes it (false). D Evaluates the condition value as boolean (the simple way). There is nothing too complex in implementing IfTag. All the reflection work is implemented by ReflectionTag and the rest of the work is actually evaluating the pointed value as a boolean and whether to include the tag s body in the response (returning EVAL_BODY_INCLUDE) or exclude it (returning SKIP_BODY). What is not obvious about IfTag is why it exports a new JSP scripting variable with the result of the condition evaluation. The reason for this is to allow other IfTags and scriptlets to read and possibly react, based on the result of the condition. Because we may not need this capability in all cases, exporting the scripting variable occurs only when the tag s user provides an id attribute value. 9.2.2 The problem with IfTag IfTag is quite useful for pages in which the content developer is interested in performing very simple conditions on various values. But when trying to develop pages that require the use of complex conditions (such as those provided by the Java s switch and if else), we run into a problem. At the very least we would like our tag to be able to handle the case wherein the condition fails via an else clause. As we will soon see, extending the tag as it currently stands to support an else clause proves to be somewhat problematic. To support an else clause, you might expect that we could simply add an else tag to our library and proceed with syntax such as the following: Some JSP if the condition is true. Some JSP if the condition is false.
Note: If you are looking for good and high quality web space to host and run your application check Lunarwebhost Tomcat Web Hosting services
CHAPTER 9 Posing conditions with tags Here the tag poses a condition on the value of the bean property as specified with the tag attributes object and property. Based on this usage pattern, let s start building our conditional tag. 9.2.1 Implementing IfTag The first issue to note regarding IfTag is that we want it to be able to pose conditions on the property values of JavaBeans (as in the previous code snippet). We can inherit most of the necessary functionality for this from ReflectionTag that was developed in chapter 8. IfTag will also need to implement some conditional logic inside doStartTag() once it gets the JavaBean property. Our IfTag will only look at the value of the object or property it received in its attributes, convert the value to a boolean, and, if the boolean value is true, evaluate the tag s body into the response. Implementing this logic is no problem if the value on which we base our condition is already boolean; in other cases we just convert the value to a boolean. For IfTag, we ve chosen an extremely simple conversion logic (since the goal of the tag is to demonstrate conditional execution, not necessarily data-type conversion). With this in mind, let s take a look at IfTag s implementation. Listing 9.1 Source code for IfTag handler package book.conditions; import javax.servlet.jsp.PageContext; import javax.servlet.jsp.JspException; import book.util.LocalStrings; import book.reflection.ReflectionTag; public class IfTag extends ReflectionTag { static LocalStrings ls = LocalStrings.getLocalStrings(IfTag.class); public int doStartTag() throws JspException { boolean b = evalBoolean(getPointed()); b if(null != id) { pageContext.setAttribute(id, new Boolean(b), PageContext.PAGE_SCOPE); } if(b) { c return EVAL_BODY_INCLUDE; } return SKIP_BODY;
Note: If you are looking for good and high quality web space to host and run your application check Lunarwebhost Tomcat Web Hosting services
IfTag A simple condition tag < % if(browserDetect.isMsIE()) { %> You are using Microsoft Internet Explorer < % } else { %> I guess that you are using Netscape Navigator < % } %> Using a bean to encapsulate the condition result inside a property yields an improved JSP; yet, if all we are doing here is checking the value of a bean, why should we use a scriptlet? Note also that we are still using the Java if statement, which requires that the JSP author know some Java syntax (especially when the bean returns different data types). To clean up this syntax and reduce the likelihood of errors, we can create a custom tag that will perform conditional evaluation. The creation of such a tag is the subject of the rest of this chapter. We start by exploring a basic custom tag that implements the functionality usually found within a simple if condition. Next we ll look at the shortcomings involved with that if condition and seek an improved implementation of conditioning using custom JSP tags. 9.2 IfTag A simple condition tag Let s start by developing a tag that lets the content developer evaluate conditions based on the value of some object or its property within a JSP. We ll want the JSP author to be able to specify an object (either by name and scope or as a runtime expression) and a boolean property of that object to evaluate. The tag will then evaluate whether the object s property is true or false. Before jumping into the code, let s see how it will look in a JSP. The following JSP fragment shows a possible use of the custom condition tag: “/> Tomcat Web Hosting services
CHAPTER 9 Posing conditions with tags Almost any form of dynamic content generation requires you to evaluate conditions. You may, for example, want to generate different content based on the user s browser (e.g., Internet Explorer does not support some of Navigator s JavaScript, and vice versa), or based on the internal state of server-side objects. If a shopping cart is empty you might not wish to show it to the user, for example. Deciding on what condition- based content to send to the user is a common issue in any web application. In this chapter, we ll see how JSP authors use conditions to serve their dynamic content without tags, and discuss how this approach could be improved through custom tags. We ll then build a custom tag library that will allow us to evaluate conditions and return dynamic content based on the condition results within our JSPs. 9.1 Evaluating conditions in JSPs For JSPs without custom tags, evaluating such conditions must be done in a script- let.The following JSP fragment shows, for instance, how to employ the User-Agent header in producing HTML that matches a specific browser: < % String userAgent = request.getHeader("User-Agent"); if((null != userAgent) && (-1 != userAgent.indexOf("MSIE"))) { %> You are using Microsoft Internet Explorer < % } else { %> I guess that you are using Netscape Navigator < % } %> The problem with putting conditions inside scriptlets is that the syntax is rather involved. In order to provide conditional HTML using Java, the content developer must be aware of the Java operators, condition syntax, data types, and when and where to put curly brackets and semicolons (all within scriptlets, which are inherently difficult to debug in the first place). To overcome the problems associated with evaluating conditions in scriptlets, some developers use beans to encapsulate most of the condition logic. For example, the following code fragment produces a browser detection bean and later performs conditions on some of the bean s properties. “/>
Note: If you are looking for good and high quality web space to host and run your application check Lunarwebhost Tomcat Web Hosting services
9 Posing conditions with tags In this chapter Using tags to evaluate conditions Using tags as if-then-else statements Supporting complex conditions with a tag language Supporting complex conditions with JavaBeans 279
Note: If you are looking for good and high quality web space to host and run your application check Lunarwebhost Tomcat Web Hosting services
Part III Advanced techniques Now that you are well versed in common tag development techniques, we will show you in chapters 9 through 12 how to apply these techniques to solve some advanced yet common problems. In this section, we examine how to use custom tags for everyday development tasks, such as evaluating conditions in a JSP, iterating over a set of values, accessing a database, and integrating with the many services in the Java 2 Enterprise Edition.
Note: If you are looking for good and high quality web space to host and run your application check Lunarwebhost Tomcat Web Hosting services
CHAPTER 8 Using JavaBeans with tags thus reducing the amount of real Java code in our JSPs. By removing Java syntax from JSPs, we further our cause of decoupling presentation logic and business logic; and by making the syntax cleaner and easier, reduce the possibility of writing incorrect or error-prone code. Future chapters show how to perform conditioning and iteration through tags, and how the availability of these bean-property related tags makes it possible to write out JSP files with minimal coding. We will also use bean integration in other future tags (such as conditioning) for which the know-how acquired in this chapter will prove worthwhile.
Note: If you are looking for good and high quality web space to host and run your application check Lunarwebhost JSP Web Hosting services