JSP Custom Tags Prerequisites Servlet API Mapping to JSP implicit objects JavaServer Pages Basic syntax Implementation via servlet API XML What is a Custom Tag? User defined JSP language elements (as opposed to standard tags) Encapsulates recurring tasks Distributed in a “custom made” tag library, which defines a set of related custom tags and contains the objects that implement the tags. Why Use Custom Tags? Improved separation of presentation and implementation Reduce/eliminate scripting tags Encapsulate common or application-specific page idioms Provide an HTML-friendly layer of abstraction Only three data-oriented JSP actions: <jsp:useBean> <jsp:setProperty> <jsp:getProperty> Why Use Custom Tags? Custom tags separate presentation from business logic in that page content is created by page designers while the business logic's are captured in the form of custom tags. Now custom tags is not just for business logic but it can encapsulate other relatively complex functionality such as complex display, iteration, formatting and so on. Because custom tags encapsulate business logic, they are reusable and easier to maintain. In fact, in most cases, you will use custom tags that are created by someone else. Because custom tags hide complexity from page authors, it is easier to author pages. And there are many tools that support custom tags. Custom tags provide portable semantics. Where does custom tags fit in? This picture shows how custom tags fit into the Web application architecture. Typically HTTP requests coming from the client are handled by the centralized controller, which in turn forwards them to JSP pages. The JSP pages then call server side objects for business logic processing. These server side objects can be either in the form of Java Beans or custom tags Custom Tags against JavaBeans Pros – Custom tags can manipulate JSP contents while beans cannot – Complex operations can be reduced to a significantly simpler form with custom tags than beans Cons – Custom tags require quite a bit of more work to set up than do beans What Can They Do? Generate content for a JSP page Access a page’s JavaBeans Introduce new JavaBeans Introduce new scripting variables Any combination of the above Plus anything else you can do with Java What Can They Do? Custom tags have a rich set of features. They can Be customized via attributes passed from the calling page. Pass variables back to the calling page. Access all the objects available to JSP pages. Communicate with each other. You can create and initialize a JavaBeans component, create a public EL variable that refers to that bean in one tag, and then use the bean in another tag. Be nested within one another and communicate via private variables. Anatomy of a Custom Tag Like the standard actions, custom tags follow XML syntax conventions <prefix:name attribute=”value” attribute=”value”/> or <prefix:name attribute=”value” attribute=”value”> body content </prefix:name> Start and End Tags In XML and JSP <prefix:name attribute=”value” … /> is equivalent to <prefix:name attribute=”value” … ”></prefix:name> Given this equivalence, the model used by the JSP custom tag API acts as if there is always a start tag and an end tag. How Do They Work? Like most J2EE technologies, there are two aspects to the development of a custom tag library. Individual tags are implemented as Java classes called Tag Handlers. An XML file called the Tag Library Descriptor (TLD) maps a set of tag handlers into a library. The Java classes and TLD can be deployed individually or via a JAR file. How Do They Work? When a JSP page containing a custom tag is translated into a servlet, the tag is converted to operations on an object called a tag handler. The Web container then invokes those operations when the JSP page's servlet is executed. JSP tag extensions let you create new tags that you can insert directly into a JavaServer Page just as you would the built-in tags you learned about in earlier chapters. The JSP 2.0 specification introduced Simple Tag Handlers for writing these custom tags. Three things make up custom tag architecture Tag handler class – Defines tag's behaviour Tag library descriptor (TLD) – Maps XML elements to tag handler class JSP file (user of custom tags) – Uses tags To use a custom tag in a JSP page, you must: * Declare the tag library containing the tag before the usage of any custom tags from that tag library * Use custom tags using custom tag syntax in a JSP page It is assumed that the tag library has been configured and deployed with individual Web application or globally for all Web applications running on the server. Tag Handlers A tag handler class must implement one of the following interfaces: javax.servlet.jsp.tagext.Tag javax.servlet.jsp.tagext.IterationTag javax.servlet.jsp.tagext.BodyTag Usually extends utility class javax.servlet.jsp.tagext.TagSupport or javax.servlet.jsp.tagext.BodyTagSupport class Located in the same directory as servlet class files /WEB-INF/classes/<package-directory-structure> A tag handler can optionally implement javax.servlet.jsp.tagext.TryCatchFinally Tag attributes are managed as JavaBeans properties (i.e., via getters and setters) Tag Library Descriptor TLD TLD TLD TLD defines tag syntax maps tag names to handler classes constrains tag body content specifies tag attributes Attribute names and optional types Required vs. optional Compile-time vs. run-time values TLD specifies tag variables (name, scope, etc.) TLD declares tag library validator and lifecycle event handlers, if any Tag Library Descriptor XML file that describes – – – – tag name bodycontent attributes tag handler class Container knows which tag is associated with which tag handler class via this file Located – Usually under WEB-INF directory Custom location can specified in JSP file – Via uri attribute of taglib directive What is Tag Library? Is a collection of related tags – Tag(s) can be packaged in a Tag Library Typically packaged as a jar file containing – A tag library descriptor (TLD) • e.g. META-INF/taglib.tld – *.class files for the tag handler class(es) – Any additional associated resource(s) What is Tag Library? We already talked about tag library. A tag library is a collection of related tags. It is a customary that you package related tags into a single tag library. A tag library is typically packaged as a jar file which contains TLD file along with tag handler classes and any related classes. When a tag library is packaged as a jar file, the TLD file should reside under META-INF directory and the tag handler classes should reside under classes directory. Declaring a tag library Include taglib directive before tags are used Syntax – <%@ taglib prefix="myprefix" uri=”myuri” %> – prefix: identifies the tag library – uri: uniquely identifies the tag library descriptor (TLD) directly or indirectly Using Custom Tags Tags are made available within a JSP page via the taglib directive: <%@ taglib uri=”uri” prefix=”prefix” %> Directive’s uri attribute references the TLD (established via WAR file’s web.xml) Directive’s prefix attribute provides a local namespace for the TLD’s tags Steps for implementing, using & deploying custom tags The steps you follow in order to implement and deploy custom tags are relatively straight-forward. First, you write tag handlers. Under JSP 2.0 architecture, tag handlers are Java classes. Second, you write so called tag library descriptor, TLD file, in short. Third, you package a set of tag handlers and TLD file into what is called tag library in either unpacked or packed form. Then, you write JSP pages that use these tags. Then you deploy the tag library along with JSP pages. Now let's talk about 3 things here by using examples - tag handler, TLD file, and JSP pages. Example 1- Create "Hello" Tag JSP tag extensions let you create new tags that you can insert directly into a JavaServer Page just as you would the built-in tags you learned about earlier. The JSP 2.0 specification introduced Simple Tag Handlers for writing these custom tags. To write a custom tag you can simply extend SimpleTagSupport class and override the doTag() method, where you can place your code to generate content for the tag. Consider you want to define a custom tag named <ex:Hello> and you want to use it in the following fashion without a body: <ex:Hello /> To create a custom JSP tag, you must first create a Java class that acts as a tag handler. So let us create HelloTag class as follows: package myTags; import javax.servlet.jsp.tagext.*; import javax.servlet.jsp.*; import java.io.*; public class HelloTag extends SimpleTagSupport { public void doTag() throws JspException, IOException { JspWriter out = getJspContext().getOut(); out.println("Hello Custom Tag!"); } } Example 1- Create "Hello" Tag Above code has simple coding where doTag() method takes the current JspContext object using getJspContext() method and uses it to send "Hello Custom Tag!" to the current JspWriter object. Let us compile above class and copy it in a directory available in environment variable CLASSPATH. Here we have copied it to ROOT\WEB-INF\classes\myTags Note :You need to include the following to compile: TOMCAT_HOME/lib/jsp-api.jar to your CLASSPATH Finally create following tag library file: <Tomcat-Installation-Directory>webapps\ROOT\WEBINF\custom.tld. <taglib> <tlib-version>1.0</tlib-version> <jsp-version>2.0</jsp-version> <short-name>Example TLD</short-name> <tag> <name>Hello</name> <tag-class>myTags.HelloTag</tag-class> <body-content>empty</body-content> </tag> </taglib> Example 1- Create "Hello" Tag Now it's time to use above defined custom tag Hello in our JSP program(Hello.jsp) as follows: Note : Hello.jsp should also be saved in WEB-INF folder <%@ taglib prefix="ex" uri="WEB-INF/custom.tld"%> <html> <head> <title>A sample custom tag</title> </head> <body> <ex:Hello/> </body> </html> Start Tomcat server and Try to call above JSP in a browser using: http://localhost:8080/Hello.jsp This should produce following result: Hello Custom Tag! Accessing the Tag Body: You can include a message in the body of the tag as you have seen with standard tags. Consider you want to define a custom tag named <ex:Hello> and you want to use it in the following fashion with a body: <ex:Hello> This is message body </ex:Hello> Let us make following changes in above our tag code to process the body of the tag: package myTags; import javax.servlet.jsp.tagext.*; import javax.servlet.jsp.*; import java.io.*; public class HelloTag extends SimpleTagSupport { StringWriter sw = new StringWriter(); public void doTag() throws JspException, IOException{ getJspBody().invoke(sw); getJspContext().getOut().println(sw.toString()); }} Accessing the Tag Body: In this case, the output resulting from the invocation is first captured into a StringWriter before being written to the JspWriter associated with the tag. Now accordingly we need to change TLD file as follows: <taglib> <tlib-version>1.0</tlib-version> <jsp-version>2.0</jsp-version> <short-name>Example TLD with Body</short-name> <tag> <name>Hello</name> <tag-class>myTags.HelloTag</tag-class> <body-content>scriptless</body-content> </tag> </taglib> Now let us call above tag with proper body as follows: Accessing the Tag Body: <%@ taglib prefix="ex" uri="WEB-INF/custom.tld"%> <html> <head> <title>A sample custom tag</title> </head> <body> <ex:Hello> This is message body </ex:Hello> </body> </html> This will produce following result: This is message body Custom Tag Attributes: You can use various attributes along with your custom tags. To accept an attribute value, a custom tag class needs to implement setter methods, identical to JavaBean setter methods as shown below: package myTags; import javax.servlet.jsp.tagext.*; import javax.servlet.jsp.*; import java.io.*; public class HelloTag extends SimpleTagSupport { private String message; public void setMessage(String msg) { this.message = msg; } StringWriter sw = new StringWriter(); public void doTag()throws JspException, IOException { if (message != null) { /* Use message from attribute */ JspWriter out = getJspContext().getOut(); out.println( message ); } else { /* use message from the body */ getJspBody().invoke(sw); getJspContext().getOut().println(sw.toString()); } } } Custom Tag Attributes: The attribute's name is "message", so the setter method is setMessage(). Now let us add this attribute in TLD file using <attribute> element as follows: <taglib> <tlib-version>1.0</tlib-version> <jsp-version>2.0</jsp-version> <short-name>Example TLD with Body</short-name> <tag> <name>Hello</name> <tag-class>myTags.HelloTag</tag-class> <body-content>scriptless</body-content> <attribute> <name>message</name> </attribute> </tag> </taglib> Custom Tag Attributes: Now let us try following JSP with message attribute as follows: <%@ taglib prefix="ex" uri="WEB-INF/custom.tld"%> <html> <head> <title>A sample custom tag</title> </head> <body> <ex:Hello message="This is custom tag" /> </body> </html> This will produce following result: This is custom tag Hope above example makes sense for you. It would be worth to note that you can include following properties for an attribute: Custom Tag Attributes: Property Purpose Name The name element defines the name of an attribute. Each attribute name must be unique for a particular tag. Required This specifies if this attribute is required or optional. It would be false for optional. Rtexprvalue Declares if a runtime expression value for a tag attribute is valid Type Defines the Java class-type of this attribute. By default it is assumed as String Description Informational description can be provided. Fragment Declares if this attribute value should be treated as a JspFragment. Custom Tag Attributes: Following is the example to specify properties related to an attribute: ..... <attribute> <name>attribute_name</name> <required>false</required> <type>java.util.Date</type> <fragment>false</fragment> </attribute> ..... If you are using two attributes then you can modify your TLD as follows: ..... <attribute> <name>attribute_name1</name> <required>false</required> <type>java.util.Boolean</type> <fragment>false</fragment> </attribute> <attribute> <name>attribute_name2</name> <required>true</required> <type>java.util.Date</type> </attribute> ..... THANK YOU