Saturday, January 28, 2012

JSTL Practice: Basic and Flow Control Tags

In this post, we will practice several JSTL core tag:
out, set, remove, if, choose and forEach

Before practice

We use JSTL 1.2 here so have to find the jstl-1.2.jar and put it into WEB-INF/lib,
and the code fragment on the page

<%@ page isErrorPage="true" language="java"
    contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!-- This is the uri for JSTL 1.2 -->
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<!-- EL is required -->
<%@ page isELIgnored ="false" %>

This denotes use JSTL 1.2 core tag with prefix 'c:'

The out tag

The out tag is like the 'out.print',
it output the value that you assigned.

Assume we have the fragment below to put the attributes in request scope and session scope
( JSP object has four scope, from top to bottom: application, session, request and page)

// put the value "123" with name "UID" into request scope
((HttpServletRequest)request).setAttribute("UID", "123");
// put the value "ABC" with name "UID" into session scope
((HttpServletRequest)request).getSession().setAttribute("UID", "ABC");
// put the value "ZZZ" with name "Test" into session scope
((HttpServletRequest)request).getSession().setAttribute("Test", "ZZZ");

and the fragment below on JSP page

<!-- the UID is 123 from Request scope
    (the lowest scope contains the attribute) -->
<c:out value="${UID}" /><br />
<!-- the UID is ABC from Session scope -->
<c:out value="${sessionScope.UID}" /><br />
<!-- the Test is ZZZ from Session scope
    (the lowest scope contains the attribute) -->
<c:out value="${Test}" /><br />

The result will be

The EL '${UID}' will try to find the attribute 'UID', starts from the lowest scope (Page scope),
then Request scope and stop when find it.

If there are two or more value with the same attribute name in different scope (in this case, Session scope)
and we want to get the attribute in higher scope,
we have to use '${sessionScope.UID}'

The attributes not used here
escapeXml 
defalut value: true,
usage:
true denotes the output value will be encoded to prevent XSS (Cross-site scripting) attack.
false denotes just output what you assign.

default
default value: "" (empty string)
usage: Output this default value if can not find the value you assigned.

The set tag

The set tag is like the 'setAttribute', it put the attribute into Page scope as default,
or put the attribute into the scope you assigned.

For example, assume the fragment below on the page:

<!-- set a variable in page scope -->
<c:set var="check" value="123" />
<!-- set a variable in session scope -->
<c:set var="check" value="session scope check" scope="session" />
<c:out value="${check}" /><br />
<c:out value="${sessionScope.check}" /><br />

the result will be:


The remove tag

The remove tag remove an attribute from the assigned scope,
if the scope is not assigned, it will remove the attribute from every scope.

For example, assume the fragment below on the page (cont)

<!-- remove the 'check' variable from session scope -->
<c:remove var="check" scope="session" />
<c:out value="${check}" /><br />
<c:out value="${sessionScope.check}" /><br />

The result will be

The if tag

The if tag test a condition, insert its body content into page if the condition is true.
It will store the test result if you specify the 'var' attribute in the default Page scope,
you can change the scope by specify the 'scope' attribute.

For example, assume the fragment below on the page (cont)

<!-- the UID in Request scope is 123 -->
Test one <br />
<c:if test="${UID eq check}" var="testResult" scope="request">
    UID is 123 !<br />
</c:if>
The test result is <c:out value="${testResult}" /><br />
<!-- change the check variable -->
<c:set var="check" value="ABC" />
<!-- the UID in Request scope is not ABC -->
Test two <br />
<c:if test="${UID eq check}" var="testResult" />
<!-- remove the testResult from request scope -->
<c:remove var="testResult" scope="request" />
The test result is <c:out value="${testResult}" /><br />
<!-- the UID in Session scope is not 123 -->
Test three <br />
<c:if test="${sessionScope.UID eq '123'}">
    UID in session scope is 123 !<br />
</c:if>
<!-- the UID in Session scope is ABC -->
Test four <br />
<c:if test="${sessionScope.UID eq check}" var="testResult" scope="request">
    UID in session scope is ABC !<br />
</c:if>
The test result is <c:out value="${testResult}" /><br />

The result will be:


The choose-when-otherwise tag set

The choose-when-otherwise tag set works as if-else if-else,
for example, assume the fragment below on the page (cont)

<c:choose>
    <c:when test="${sessionScope.UID eq '123'}">
        <span style="color: red;">
            UID in session scope is 123 !<br />
        </span>
    </c:when>
    <c:when test="${sessionScope.UID eq '456'}">
        <span style="color: green;">
            UID in session scope is 456 !<br />
        </span>
    </c:when>
     <c:otherwise>
         <span style="color: brown;">
             UID in session scope is <c:out value="${sessionScope.UID}" /><br />
        </span>
     </c:otherwise>
</c:choose>

The result will be:


The forEach tag

The forEach tag is used to loop through a collection,
for example, assume we have the fragment below to put a data object into request scope,
and there is a product list in the data object:

// create product list
List<Product> pdl = new ArrayList<Product>();
for (int i = 1; i <= 10; i++)
    pdl.add(new Product("ID_"+i, "NAME_"+i, i));
// create data object
Data dt = new Data(pdl);
// put data object into request scope
((HttpServletRequest)request).setAttribute("data", dt);

And the fragment below to create a table to show the product list

<!-- use forEach to convert a list to table -->
Total product: <c:out value="${data.productCount}" /> <br />
<table border="1">
    <tr>
        <th scope="col" align="center">
            ID
        </th>
        <th scope="col" align="center">
            Name
        </th>
        <th scope="col" align="center">
            Value
        </th>
    </tr>
    <c:forEach items="${data.productList }" var="product" begin="0" end="9" step="2">
        <tr>
            <td><c:out value="${product.id}" /></td>
            <td><c:out value="${product.name}" /></td>
            <td><c:out value="${product.value}" /></td>
        <tr>
    </c:forEach>
</table>

The result will be:


The attributes in this case:
items: the collection to loop through
var: denotes the current item
begin: the start position, in this case is 0 (first one)
end: the end position
step: position will increased by the value of each iteration

Note the expression '${data.productList}' denotes *.getAttribute("data").getProductList,
i.e., there should a function called getProductList in data object,
but the 'productList' member is not required.
The getter is the only thing it depends on.

Use forEach tag to do a loop

forEach tag can be used to do a loop without a collection,
for example, assume the fragment below on page:

<!-- use forEach to loop and sum 1 to 10 -->
<c:set var="sum" value="${0}" />
<c:forEach begin="1" end="10" step="1" varStatus="status">
    <c:set var="sum" value="${sum+status.count}" />
</c:forEach>
<c:out value="${sum}" />

The result will be:

the varStatus is the status of iteration.

Download:
The full project is at github
https://github.com/benbai123/JSP_Servlet_Practice/tree/master/Practice/JSTLPractice

The files in this post are
/src/test/jstl/Data.java
/src/test/jstl/Product.java
/src/test/jstl/filters/PracticeOne.java
/WebContent/practice_one.jsp

References:
http://docs.oracle.com/javaee/5/tutorial/doc
http://geekexplains.blogspot.com/2008/06/whats-scope-of-jsp-objects-how-many.html

No comments:

Post a Comment