The latest version of JSTL is JSTL 1.1. Without any hesitation, JSTL is now extremely important in ensuring the success of the J2EE web application projects. JSTL is basically part of JSP 2.0 specification and requires Java Servlet 2.4 and higher to support its tags.

After completing this tutorial, you are expected to be able to apply JSTL technology to your JSP, know what are JSTL tags, know how and when to use certain tags under certain circumstances according to your needs.

Specifics Information on JSTL and Netbeans

This tutorial has been compiled, tested and run under:

  1. Netbeans 5.5
  2. JSTL 1.1 library package
  3. Tomcat 5.5.7 as server

If you have installed NetBeans successfully, JSTL library (.jar) can be found on your local hard disk. It is bundled together with Netbeans. For your information, it can be found in: netbeans_installation_folder\enterprise1\config\TagLibraries\JSTL11

You can also download JSTL taglib library from Jakarta apache project online website on Some included jar for JSTL 1.1 library are jaxen-full.jar, jstl.jar, saxpath.jar, standard.jar, xalan.jar. However, only jstl.jar and standard.jar are required. So why do we need those other jar files? Well, standard.jar depends on other jars like xalan.jar, saxpath.jar, dom.jar, etc to work properly. You can use J2SE 1.4.2 and higher to avoid these dependencies. However, as the JSTL taglib library has been bundled together with the NetBeans, you do not need to download it anymore.


  1. What is JSTL?
  2. Why use JSTL?
  3. Implementation of JSTL Core Tags
  4. Implementation of JSTL Formatting Tags
  5. Implementation of JSTL Function Tags
  6. Conclusion
  7. Appendix

1. What is JSTL?

JSTL stands for JSP Standard Tag Library. JSTL has been standardized and is being one of the most important technologies in implementing J2EE Web Application. The main objective of the JSTL is basically to simplify the Java codes within JSP (scriptlets) as well as to increase the level of reusability within our J2EE web application. Before JSTL is introduced, J2EE Web Applications (especially in the presentation layer – JSP) are extremely complex and are very tough to be maintained. It is true that the new developer may take some time to understand all the underlying codes within J2EE Web Application This is where JSTL should help.

Here is a simple JSTL flow concept; JSTL is compiled into a servlets (Java codes) before being displayed to JSP. Some classes of standard.jar are required to parse and translate these JSTL tags into servlets (Java codes). Lastly but not least, the servlet that has been compiled will be executed accordingly.

There are many more advantages of using JSTL compared to scriptlets. Therefore, it is recommended to replace scriptlets with JSTL in the presentation layer (JSP).

There are 5 major types of JSTL tags:

  1. JSTL Core tags, prefixed with c
  2. JSTL Format tags, prefixed with fmt
  3. JSTL Function tags, prefixed with fn
  4. JSTL Database tags, prefixed with sql
  5. JSTL XML tags, prefixed with x

JSTL Core Tags

<%@ taglib uri="" prefix="c" %>

Mainly used for replacement of scriptlet logical tags as well as basic URL handling tag such as catch, choose, if, forEach, param, when, redirect, import, url, etc.

JSTL Format Tags

<%@ taglib uri="" prefix="fmt" %>

Mainly used for displaying number and date time format. This could be used for internationalization support as well. Tags examples are setLocale, setTimeZone, setBundle, formatNumber, formatDate, etc.

JSTL Function Tags

<%@ taglib uri="" prefix="fn" %>

Very useful JSTL tags. Most are used in conjunction with JSTL core tags. These tags are designed for manipulating string.

JSTL Database Tags

<%@ taglib uri="" prefix="sql" %>

Tags are used to interact with database level. With database tags you could do transaction, update and query the database from your UI level. Personally, I do not prefer these tags. The MVC design pattern should always be retained.


<%@ taglib uri="" prefix="x" %>

Similar to core tags, except xml tags will deal with xml stuffs like parsing xml documents, validating xml documents, output an xpath and etc.

For depth details to all JSTL tags, you can find more information within your NetBean's installation folder i.e. installation_netbeans_folder\enterprise1\docs\

Additionally, JSTL accepts the conditional operators like 'eq', 'ne', '==', 'null', 'empty', 'not', '!=', '>=', '<=', 'and', '&&', 'or', '||' all are valid.

Here is the mapping of relational and logical operators with JSP Notations.


JSP Notation

























While other arithmetic operators such as +, -, and * can also be used together with the JSTL tag as well.


2. Why use JSTL?

Advantage of JSTL

  1. Scriptlets (Java codes within JSP) are complex and are extremely hard to be maintained. Unlike scriptlets, JSTL makes our JSP readable and maintainable.
  2. HTML programmer may find it hard to modify the JSP with the scriptlets as he or she may not have the Java programming knowledge. However, if we are using JSTL to replace our scriptlets, HTML programmer can easily understand on what's going on in the JSP as JSTL is in the form of XML tags similar to the normal HTML tags.
  3. JSTL has been standardized and is reusable tags.
  4. The name of each tag in JSTL is self-explanatory and is easy to understand.
  5. JSTL requires less code compared to scriptlets.

Shortcomings of JSTL

  1. Scriptlets provide you with greater flexibility. As scriptlets is simply a Java codes, you can do anything that you want as you normally do with a Java programming. On the other hand, JSTL is a very specific and each tag has its own purposes.

JSTL Tutorial

Until now, you should have known the basic of the JSTL theoretically. Let's move on to real JSTL practice. Start your NetBeans.

Create New Project

Let's first us create new project for this tutorial. After Netbeans has already been started, choose File and New Project…


A wizard dialog will show up, choose Web on the left panel and choose Web Application on the right panel. Then click Next to continue.

In the step 2, we are required to fill in our project's information details. Use self-explanatory name for the project name. Ok, let's call it JstlDemo. We can keep the rest as default. Then click Finish.



At this point, our web application is ready. File called index.jsp will be automatically created for us.

Preparing the Library

JSTL requires 2 jars; jstl.jar and standard.jar. These two files are not included in our default library. We need to add these libraries to our project.

On the left projects tab panel, we can see a folder named Libraries. Right click on this folder and Add Library…



After this one, we will see list of available libraries. Choose JSTL 1.1 and Add Library.

If you carefully look at the index.jsp, it contains the JSTL tag but it is commented.


<%@taglib uri="" prefix="c"%>


You may try to uncomment it to test whether you have correctly imported the JSTL libraries.

3. Implementation of JSTL Core Tags

First, let's make a new JSP page. Right click on Web Pages folder, New and JSP…



Then a new dialog will show up as displayed above. Let's call it Jstl_Hello_World.jsp. Then click Finish to create the jsp. Now we have 2 JSPs – index.jsp and Jstl_Hello_World.jsp.

We will create a table in index.jsp for the sample of this tutorial. Place these codes inside the tag <body> in index.jsp

<table border="1">



<a href="/Jstl_Hello_World.jsp">Hello World!</a>



Print out String "Hello World!"




Now for the Jstl_Hello_World.jsp, we are going to write some JSTL tags to print out the sentence "Hello World". Do not forget to uncomment the taglib directive for the JSTL library.

<%@taglib uri="" prefix="c"%> 
<c:out value="Hello World!" />

The above codes simply print the sentence "Hello World" to the JSP.

<c:set var="sentence" value="Hello World with <c:set/>" />

<c:out value="${sentence}" />

Above codes will do similar thing. The difference is that the sentence was stored into a variable named "sentence" via <c:set> tag and then display it from by using ${variable_name}

 <c:remove var="sentence" />

<c:out value="${sentence}" />

The tag <c:remove> works in opposite with <c:set>. In the above codes, the <c:out> will not print anything out anymore because the variable called "sentence" has been removed.

Press Shift+F11 to build the project and F6 to run. We will see something like this for the index.jsp. We may click the "Hello World"link to see our first JSTL tag in action.



And this is the result after we click the link.

Ok, we have completed our first Hello World JSTL. Now let's move on to the logical JSTL core tags. We need to create another link in our index.jsp. The link will contain 3 parameters which hold some values which are boolean, string and numeric. We are goint to see a simple demonstration on how we are supposed to use logical JSTL core tags.

Create a new JSP file. Follow exactly the same way as we created the Jstl_Hello_World.jsp but name it Jstl_Core_Tags.jsp. Then we need to modify our index.jsp to contain the link to our newly created JSP. So please add below codes to our index.jsp just right after our first link to open the Hello World JSTL tags.



<a href="/Jstl_Core_Tags.jsp?valid=true&name=eric&mark=8">JSTL Core Tags</a>



JSTL if tag and EL operators



What we do here is basically to send some parameters so that they are accessible from the target page.

On the target page, we can retrieve these parameters via ${param.parameter_name} and we are going to use the logical JSTL tags to compare some values. Add below codes to Jstl_Core_Tags.jsp

<c:if test="${param.valid}">

A test shows that parameter valid is ${param.valid}


This tag is used to determine whether parameter valid value is true or false. If the value is true then it prints out the sentence. On the other hand, if it is false, it should not print anthing out. You may like to try to modify the valid value to be false in the index.jsp. The sentence should not be printed out if the value is false. Until now, you should know that if you would like to access any parameters, you may use the keyword "param". It is similar to the request.getParameter.

<c:if test="${ != null}">

A test shows that parameter name contains value of ${} via != operator


The above tag is to check whether parameter name is null or not. If it is not null then it prints out the sentence and it prints nothing if the value is null.

<c:if test="${ ne null}">

A test shows that parameter name contains value of ${} via ne operator


Above codes are working similarly with the previous codes. We just want to test JSP notation "ne" for not equal function as what "!=" does.

<c:if test="${not empty(}">

A test shows that parameter name contains value of ${} via empty operator


Above codes are another feature of JSP notation to check a value whether it is empty or not. It is basically pretty much the same as the second and third tag do. The difference lies on the value null and empty. What is the difference between empty and null? Well, empty is not necessarily be null but null always be empty. Null means that the variable is simply not existed while empty means that the variable is existed and initialized but it contains nothing. Please be careful when dealing with null values as it may cause you the famous NullPointerException.

<c:if test="${param.mark >= 0 and param.mark <= 10}">

A test shows that parameter mark contains value of ${param.mark} which lies in range of 0 to 10


Above codes are used to check whether parameter with the name of "mark" is within the range of 0 to 10. If yes then it prints the sentence.

Again, press Shift+F11 to build the project and F6 to run. The index.jsp will now looks like this


Try to click on the second link (JSTL Core Tags) and it should look like below screenshot.


You may be interested to try out some different parameters values for this JSTL tag. Remember, you will learn a lot by practice. Let's move forward to more advance JSTL core tags.

Create another JSP page. This time, we can name it with Jstl_Core_Tags_2.jsp. We also need to create another link in index.jsp to open up this page as well. Add below codes to create the additional new link in index.jsp.



<c:url value="Jstl_Core_Tags_2.jsp" var="url">

<c:param name="test_for_each" value="one,two,three" />

<c:param name="test_for_token" value="one;two;three" />


<a href='<c:out value="${url}" />'>JSTL Core Tags 2</a>



Play around with JSTL forEach, forTokens, choose, when, and otherwise



Now, we could see the new JSTL tag in index.jsp here. <c:param> is normally used to embed a parameter values to the URL link. While, <c:url> tag is basically used for creating a link of URL and stores the link in variable named "url". In fact, this combination of <c:url> and <c:param> tags will do the same as the link that we hard coded before. The final link should be in form of Jstl_Core_Tags_2.jsp;jsessionid=…?param_1_name=param_1_value&param_2_name

=param_2_value. This is how we are creating a dynamic link using JSTL tag. After this, we can use <c:out> to display it.

In this case, we have 2 parameters named test_for_each and test_for_tokens. Next, we need to write JSTL forEach and JSTL forTokens tags in Jstl_Core_Tags_2.jsp to see how they work.

<c:forEach var="part_each" items="${param.test_for_each}">

<c:out value="${part_each}" />



Above codes will take values of the parameter "test_for_each"and stores it in variable called "part_each". Within the tag forEach, we print the variable "part_each" using <c:out>. It loops through default separator ',' (comma) until it reaches the end. <c:forEach> is extremely useful when you are sending some Collection object to the JSP and you need to iterate the content of the Collections to your JSP.

<c:forEach var="i" begin="1" end="20" step="2">


<c:when test="${i < 11}"><c:out value="${i}" /> (small)<br></c:when>

<c:when test="${i < 16}"><c:out value="${i}" /> (medium)<br></c:when>

<c:otherwise><c:out value="${i}" /> (large)<br></c:otherwise>



Above codes are the sample of more advanced forEach loop. We first declare a variable "i" and we also define the beginning, ending and stepping value for the variable "i". The above tag means that it should loop from 1 to 20 in increment of 2. To make it more interesting, we could add a condition to check whether the current value of variable "i"is in the range of small, medium or large by using JSTL tag <c:choose>, <c:when> and <c:otherwise>. This one (<c:choose>, <c:when> and <c:otherwise>) is equivalent to switch case default syntax in conventional programming language.

<c:forTokens var="part_token" items="${param.test_for_token}" delims=";">

<c:out value="${part_token}" />



This tag works in same way as forEach tag. But it has additional delims attribute to tokenize values with certain delimiters. What does it mean? It means that it will separate or tokenize the values within its items attribute with the delimiter. So if you have the String of "1,2,3" and the delimiter is ",", the result would be three items i.e. 1, 2 and 3. How about if we want to separate the values for multiple delimiters? You can initialize it using multiple delimiters as delims=";|()" to tokenize the values.

Let's see how it works. Press Shift+F11 to build the project and F6 to run.


And this is how the result looks like.


Next, we are going to explain on <c:redirect> and <c:import>. These 2 tags are simple. <c:redirect> simply redirects us to another page and <c:import> is similar to <jsp:include> that will extend imported page to current page.

Let's see how it works. Create 2 new JSP called JstL_Core_Tags_Redirect.jsp and Jstl_Core_Tags_Import.jsp.

Add this to Jstl_Core_Tags_Redirect.jsp

<c:redirect url="index.jsp" />

It is going to redirect the page back to index.jsp

Add this to Jstl_Core_Tags_Import.jsp

<c:import url="index.jsp" />

It will import or include index.jsp after Jstl_Core_Tags_Import.jsp loads.

This is what we get when we run Jstl_Core_Tags_Redirect.jsp. Just type the address as shown in circled area and the page will redirect us back to index.jsp.


Interesting right? Well, do same thing for Jstl_Core_Tags_Import.jsp. Open browser then type the full address manually and we will get index.jsp is loaded after Jstl_Core_Tags_Import.jsp loads.


4. Implementation of JSTL Formatting Tags

Now, you should have understood the JSTL core tags very well. As you can see, the JSP is more readable and more maintainable. If you try to achieve all the previous examples using scriptlets, your JSP may be larger in size and much more complex. Well, it is time to move on to the second JSTL tags which is JSTL Formatting tags. Similarly, create a new JSP and name it Jstl_Fmt_Tags.jsp. Add one more link in our existing index.jsp but this time let's make it in another table to ensure the simplicity of the example.

<table border="1">



<a href="/Jstl_Fmt_Tags.jsp">JSTL Formatting Tags</a>



Internationalizing and Formatting




Now, we need to include another JSTL tag. Here is how to import the fmt JSTL taglib directive.

<%@ taglib uri="" prefix="fmt" %>

Let's try something interesting on the JSTL internationalization support.

<c:out value="${pageContext.request.locale}" /> 

Above codes will simply print out our default locale. The value will be retrieved from each client's specific browser. In IE browser, you can find your Locale on Tools-Internet Options… and then Languages…


Ok now we need to create properties files under WEB-INF/classes/ directory. These files often called as resource bundle files and should be located under this directory as it will be included in the classpath. If the file is not within the classpath, you will not be able to access it from your application. Normally, resource bundle properties files will be the place to store the language translations.

Right Click on WEB-INF folder, New and choose File/Folder…


Another dialog box will appear, choose Other on the left pane and choose Folder on the right pane.


Put the default folder name "classes". It is common to put resources files under this directory since it will automatically include all files in this directory to the web application classpath.

Here is the screenshot for this step.


Now we have the folder classes under WEB-INF folder. Next let's create the resource bundle files. Right click on the classes folder we just created. Choose New and File / Folder…


Name it and this will be our default properties file.


Again follow the same steps we create another properties file. This time name it resource_bundle_[language].properties where the language is actually the language codes for our translations. For this tutorial, let's name it Please notice that the suffix is "id" which means that this is the resource bundle for Indonesian language. You may use any suffix as you prefer at this stage i.e. (Spanish) or (Mandarin) and etc.

The new properties file, the one with suffix will be automatically nested under our default "" file.

Put some keys in our default properties file.

title=My Company


And the translated version of keys for our suffixed properties file.


welcome=Selamat Datang!


We are done with the resource bundle properties files. Let's see how they are working. Back to our Jstl_Fmt_Tags.jsp, add below codes to test our internationalization support from JSTL tag.

<fmt:setBundle basename="resource_bundle" />

<fmt:message key="title" />

<fmt:message key="welcome" />



<fmt:bundle basename="resource_bundle_id" >

<fmt:message key="title" />

<fmt:message key="welcome" />


The first and second paragraph does the same thing. The first paragraph, we are using <fmt:setBundle> while the second we are using <fmt:bundle> tag. They are doing the same thing except <fmt:bundle> works only within its tag. The <fmt:message> outside of the <fmt:bundle> should not be able to access the properties files. Therefore we need to define the opening and closing tag for <fmt:bundle> tag. While <fmt:setBundle> works in higher level and we can specify it in what scope the tag <fmt:setBundle> will have an effect.

The basename attribute in the <fmt:bundle> and <fmt:setBundle> are the name of the specific properties file while <fmt:message> is used to look up for matching available keys message in our properties file.

Next part is about date time parsing and formatting. Continue with our current JSP. Put this code.

<jsp:useBean id="now" class="java.util.Date" />

This tag is to get to java.util.Date class.

<fmt:setLocale value="en_GB" /><strong>U.K :</strong>


<fmt:formatDate value="${now}" type="both" dateStyle="full" timeStyle="default" />


<fmt:timeZone value="GMT">

<fmt:formatDate value="${now}" type="both" pattern="EEEE, dd/MMMM/yyyy, HH:mm:ss z" />



<fmt:formatNumber value="${now.time}" />


<fmt:formatNumber value="8000" type="currency" minFractionDigits="2" maxIntegerDigits="10" />

How do the above codes work? First we set the locale value to desired value (in this case, UK). Simply refer to Language Preference in our browser for some locale values.

The tag <fmt:formatDate> will format the date value which retrieved via "now" bean id. The type could be date, time or both. The dateStyle and timeStyle could be in short, medium, long, full or default. The default value for this is "short". Pattern is used if we want the date time format to be in our specific way. Pattern will always override dateStyle and timeStyle.

The tag <fmt:timeZone> will adjust the current time to GMT based time. We may want to use <fmt:setTimeZone> in certain conditions. The value attribute for this tag could be in standard abbreviation (e.g., "PST," "GMT"), a full name (e.g.,"Europe/Stockholm"), or a GMT offset (e.g., "GMT+1").

The tag <fmt:formatNumber> is to format the numerical given values. The type could be number, currency or percentage. Here are more details about it. minFractionDigits is a minimum number of digits in fractional portion. maxIntegerDigits is a maximum number of digits in integer portion. Other attributes are currencyCode and currencySymbol. These 2 are valid while the type is currency. This can be useful when you need to show prices expressed in a fixed currency, but you want the amount to be formatted according to the selected locale.

<fmt:parseDate value="25-12-2006" pattern="dd-MM-yyyy"/>

<fmt:parseNumber value="$8,000.00" pattern="$#,###.##" />

<fmt:parseDate> and <fmt:parseNumber> is to get the actual value from unparsed string. These tags are useful in the situation where we need to get users' input from a User Interface (UI) form. We can parse the values in form of what we want before inserting or updating to a database.

Now build and run the project. We will get something like this.


And this is what we get when we click the "JSTL Formatting Tags".


5. Implementation of JSTL Function Tags

Now, let's have a look at the JSTL Function tag. Create a new JSP. Let's name it Jstl_Functions_Tags.jsp. Then create a new link to direct to this new JSP.

<table border="1">



<a href="/Jstl_Functions_Tags.jsp">JSTL Functions Tags</a>



String Manipulations




Do not forget to include JSTL taglib directive for prefix fn in our JSP. Here is how to import the fn JSTL taglib directive.

<%@ taglib uri="" prefix="fn" %>

The JSTL functions tag will mainly deal with string manipulation. Let's try some of them.

<c:set var="sentence" value=" Try This String for Manipulations " />

<c:out value="${sentence}" />

Above codes are used to set a fixed string to variable "sentence" and print it out for display. Next, please pay attention on how we are going to combine JSTL core <c> tag with JSTL function <fn> tag.

<c:out value="${fn:length(sentence)}" />

Above codes will print out the length of variable "sentence". It will produce 35 since all characters are counted.

<c:out value="${fn:toUpperCase(sentence)}" />

<c:out value="${fn:toLowerCase(sentence)}" />

Above codes are used to convert our "sentence" to UPPER or LOWER case.

<c:out value="${fn:trim(sentence)}" />

<c:out value="${fn:length(fn:trim(sentence))}" />

<c:out value="${fn:replace(sentence,' ','_')}" />

Above codes are used to trim the "sentence" and count the length of trimmed "sentence". Trimming the sentence means that we are removing the extra spaces (if any) in the string either in front or in back. You need to know that the spaces within the string will NOT be trimmed. It should produce 33 since the spaces at the beginning and at the end will be discarded. While the sample above of fn:replace will replace all occurrences of spaces with underscores.

<c:out value="${fn:substring(sentence,0,8)}" />

<c:out value="${fn:substringAfter(sentence,'for')}" />

<c:out value="${fn:substringBefore(sentence,'for')}" />

<c:out value="${fn:indexOf(sentence,'g')}" />

The fn:substring will take 3 parameters. 1st parameter is our "sentence" variable itself. 2nd parameter is for the starting point and 3rd parameter is where it must stop to return result of substring. More advanced substring functions are fn:substringAfter and fn:substringBefore. See at the screenshot to see how they work.

And the fn:indexOf will return the position of defined character in our "sentence".

<c:out value="${fn:contains(sentence,'G')}" />

<c:out value="${fn:containsIgnoreCase(sentence,'G')}" />

<c:out value="${fn:startsWith(sentence,' Try')}" />

<c:out value="${fn:endsWith(sentence,'pulations ')}" />

fn:contains will return boolean value true if correct and false otherwise. However, it is case sensitive and will sensitively check for the lower case and upper case of the string. fn:containsIgnoreCase work in the same way as fn:contains but it is not case sensitive which means that it will not care whether it is in lower case or in upper case. fn:startsWith and fn:endsWith will also return boolean to check whether the "sentence" starts or ends with corresponding given value.

Again, clean build the project and run the project. The index.jsp will appear as usual and click the "Jstl_Functions_Tags" to see the result.



6. Conclusion

Now we have known what JSTL is and how to use it. Use JSTL anytime when possible. JSTL could empower our web app. From what we learnt, we could think of when or in what conditions JSTL could be used for. Some examples of use of JSTL are

  1. display format and internationalization
  2. print out values from servlets response-request or even database values as in work with POJO or java bean
  3. validating users' input on UI
  4. parsing users' input value
  5. URL handling

You could think of other several examples and extend your knowledge on JSTL. And apply it on your project.