DigitalJoel

2011/03/17

How to create a custom taglib containing an EL function for JSP

Filed under: java — Tags: , — digitaljoel @ 10:49 pm

At some point in your use of JSP, there’s something you’re going to need to do for which you can’t find a spring or jstl tag. In that case, you can create a custom function in your custom tag library. It sounds more difficult than it is. All you will need is a tag library descriptor, and your class that implements the function. That’s about it. Here’s my TLD file.

<taglib xmlns="http://java.sun.com/xml/ns/j2ee" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee/web-jsptaglibrary_2_0.xsd" 
    version="2.0">

    <tlib-version>2.0</tlib-version>
    <uri>http://www.your-domain.com/taglib</uri>

    <function>
        <name>doMyStuff</name>
        <function-class>com.mydomain.util.ElFunctions</function-class>
        <function-signature>java.lang.String doMyStuff( java.util.Collection )</function-signature>
    </function>
</taglib>

This file should be placed in your WEB-INF directory. In the function-signature, be sure to use fully qualified names.

Next is the class that implements the function.

package com.mydomain.util.ElFunctions;

import java.util.Collection;

/**
 * Functions for use in expression language in the jsp views.
 */
public class ElFunctions
{

    /**
     * This is the function that is called by the Expression Language processor.  It must be static.
     * @param myparam
     * @return
     */
    public static String doMyStuff( Collection<SomeType> myparam )
    {
        // do stuff here and return the results
    }
}

Finally, just reference the function in my jsp file.

<%-- where you declare your taglibs, include this one, which references the tld we created in the first step. --%>

<%@ taglib prefix="my" uri="/WEB-INF/my.tld" %>

<!-- more html and whatever, in my case I'm using spring:message to output the results of my method call -->

<spring:message text="${my:doMyStuff(bean.collection)}" />

The call to ${my:doMytuff(bean.collection)} causes the EL processor to call my function when it evaluates that snippet. In this case, ‘bean’ would be some java bean available to the view, and ‘collection’ would be a property on the bean that returns the collection expected as input to doMyStuff.

Advertisements

7 Comments »

  1. Hey thanks a lot! =D It helped me!

    Comment by Antonio Carlos — 2012/02/06 @ 7:47 am

    • glad it helped.

      Comment by digitaljoel — 2012/02/06 @ 8:30 am

      • can i call more than one function using the same tld file?

        Comment by new_guest — 2012/09/13 @ 1:04 am

  2. You can define any number of functions in your tld file, and they can even be from different java classes if you want. Juts add another function element and use the fully qualified class name as before.

    Comment by digitaljoel — 2012/09/13 @ 9:20 am

  3. can you please link to a fully working code? I’ve looked at various/similar example and they are not working for me.

    and can you answer some questions for me?

    1. how do I use the class/jar file? do I just import it into my project?
    2. where is the class/jar file located? if I’m not importing it? I have a CLASSPATH variable in my setup (running windows 7 here)
    3. if I am testing my code just in my local development machine (i.e. tomcat7 running in localhost at port 8080), what should be the value of URI in the TLD file?

    thank you very much

    Comment by mrjayviper — 2013/07/28 @ 9:02 pm

    • I do not have a link to a sample project, but here are answers to your questions.

      1) The implementation class must be on your classpath somewhere. It could simply be in your war project or in another project that is included in the war.
      2) When running in tomcat usually all the supporting jars are placed in WEB-INF/lib within the war file containing the web project you wish to run.
      3) The URI in the TLD should point to the path of the TLD file. You can see in this example that it points to /WEB-INF/my.tld, so in this project there would exist a file called my.tld and when it is packaged into the war it would be placed within the WEB-INF directory within the war.

      From your questions it sounds like you should do some reading about war files and dynamic java web projects. Google should help you there.

      Comment by digitaljoel — 2013/07/30 @ 10:31 am

  4. I have used Enum”(Contant cont)” instead of “Collection myparam”, and got following error
    javax.el.ELException: Problems calling function ‘tf:getValueOfContant’

    Comment by LAKHAN — 2013/10/23 @ 4:58 am


RSS feed for comments on this post. TrackBack URI

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Blog at WordPress.com.