<someTags:aTag attribute="<%= pageContext.getAttribute("aName") %>">
or the value of a custom JavaBeans component:
<%= aCustomer.getAddress().getCountry() %>
EL은 페이지 작성자가 간단한 구문을 이용해 객체에 접근할수 있게한다.
<someTags:aTag attribute="${aName}">
And to access a nested JavaBeans property, you would use something like:
<someTags.aTag attribute="${aCustomer.address.country}">
아니 .. 이것은 자바스크립트 구문이 아니오? 라고 당신은 물을수있다.
당신은 정확하게 맞다. ( You are absolutely right! ^^)
당신이 자바스크립트로 작업해 봤다면 당신은 홈그라운드에 온 기분일것이다. 왜냐하면 EL은 구조화된 데이타에 접근하는데 자바스크립트의 구문을 빌려다 쓴다.
Note: 스펙이 어쩌구 저쩌구 RFC가 어쩌구저쩌구,, 하다가...
한가지 기쁜 소식은 jsp2.0이 릴리즈 되었다는 것이다. 어쩌구 저쩌구,, 이제 실습해보자.
Accessing Application Data
당신은 어플리케이션의 데이터가 객체 일지라도 dot(.) 연산자를 이용하거나 bracket(['name']) 연산자를 이용해 속성에 접근할수 있다.
EL의 ${data} 표현은 스코프 범위내의 data 라는 변수의 값을 표현한다.
당신은 (.) 연산자나 ([]) 연산자를 이용해 특성을 검색할수 있다.
- (.) 연산자는 ${customer.name} 와 같이 쓸수있다.
- ([]) 연산자는 ${customer["name"]}. 과 같이 name 값을 받을수 있으며, 또한 ${customers[0]} 와 같이 customers collection에서 첫번째 값을 참조 할수 있다.
EL은 .연산자와 []연산자를 동일하게 취급한다. 따라서,${customer.name}와 ${customer["name"]} 은 동일한값을 나타낸다. 보시다 시피.. 모든 EL 표현식은 반드시 ${ 로 시작해 } 로 끝난다.
EL은 대부분의 일반적인 데이터를 처리하기 위해 수학식,관계성 그리고 로직컬 연산자를 지원한다.
추가로 empty 라는 특수한 연산자가 있는데 ${empty param.name} 표현식에서 param값이 없을때 true이다. 당근 ${!empty param.name}은 param값이 있을때 true 이다.
표 1을 보자.
Table 1: Expression language operators |
Operator |
Description |
+ |
Addition |
- |
Subtraction |
* |
Multiplication |
/ or div |
Division |
% or mod |
Modulus (Remainder) |
== or |
Equality |
!= or != |
Inequality |
< or lt |
Less than |
> or gt |
Greater than |
<= or le |
Less than or equal to |
>= or ge |
Greater than or equal to |
&& or and |
Logical AND |
|| or or |
Logical OR |
! or not |
Boolean complement |
empty |
Check for empty value |
Implicit Objects
연산자에 더불어 EL은 어플리케이션 데이타에 접근을 위한 implicit 객체를 정의한다.
Table 2: Implicit objects provided by the expression language |
Implicit Object |
Content |
applicationScope |
A collection of scoped variables from page scope |
cookie |
A collection of all cookies |
header |
HTTP request headers as strings |
headerValues |
HTTP request headers as collections of strings |
initParam |
A collection of all application parameter names |
pageContext |
The javax.servlet.jspPageContext object for the current page |
pageScope |
A collection of all page scope objects |
param |
A collection of all request parameters as strings |
paramValues |
All request parameters as collections of strings |
requestScope |
A collection of all request scope objects |
sessionScope |
A collection of all session scope objects |
Twin Tag Libraries
런타입 기반의 JSTL과 표현식기반의 JSTL을 지원하기 위해 쌍둥이 태그라이브러리가 논의되었다.
런타임기반의 JSTL은 단지 _rt 라는 접미사만 덧붙이면 된다.
Table 3: EL-based tag libraries |
Functional Area |
URI |
Prefix |
Core |
http://java.sun.com/jstl/core |
c |
XML Processing |
http://java.sun.com/jstl/xml |
x |
Internationalization |
http://java.sun.com/jstl/fmt |
fmt |
Database Access |
http://java.sun.com/jstl/sql |
sql |
Table 4: Runtime-based tag libraries |
Functional Area |
URI |
Prefix |
Core |
http://java.sun.com/jstl/core_rt |
c_rt |
XML Processing |
http://java.sun.com/jstl/xml_rt |
x_rt |
Internationalization |
http://java.sun.com/jstl/fmt_rt |
fmt_rt |
Database Access |
http://java.sun.com/jstl/sql_rt |
sql_rt |
EL기반의 태그라이브러리 사용을 위한 태그리브 선언 예:
<@ taglib prefix="c" uri="http://java.sun.com/jstl/core">
런타임 기반의 태그리브 선언예:
<@ taglib prefix="c_rt" uri="http://java.sun.com/jstl/core_rt">
한번 선언한뒤 다음처럼 태그라이브러리를 사용할수 있다. : <c:aTag>
.
The Core Tag Library
코어 태그라이브러리는 액션,포함,출력,스코프내의 변수조작,상태로직,반복,URL조작,에러처리등을 지원한다.
General Purpose Tags
출력하고,지정하고,삭제하고 에러처리 하기 위해 다음과 같은 태그를 사용한다.
:<c:out>
, <c:set>
, <c:remove>
, and <c:catch>
.
아래 예처럼 출력하기 위해 <c:out> 태그를 사용한다.
The name of your city is: <c:out value="${customer.city}" default="unknown"/>
default 밸류를 지원한다. 표현식에서 city 값이 없으면 unknown이 출력된다.
<c:set var="name" value="expression"/>
<c:remove>
태그를 사용할때는 아래 예처럼 스코프를 명확히 명시해야 한다:
<c:remove var="cache" scope="application/>
<c:catch>
이태그는 뒤에 설명한다.
Conditional Actions
JSTL 조건식을 ( <c:if> 태그사용) 지원한다. 그리고 상호간에 배타적인 조건을 실행한다. ( using <c:choose>
, <c:when>
, and <c:otherwise>
).
<c:if>태그는 런타임 정보에 의존하여 으로 페이지 일부분을 조건적으로 포함할수 있다.
예로서 아래 코드는 고객이 캐나다에 거주하는지 체크한다.
<c:if test="${customer.country == 'Canada'}">
This customer is based in Canada.
</c:if>
이것은 <c:catch>를 이용한 <c:if>태그 사용의
또다른 예제이다.
<c:catch var="exception">
<!-- execution we can recover from. -->
...
</c:catch>
<c:if test="${exception != null}">
Processing could not be performed. Here is why....
</c:if>
아래 예제와 같이 <c:choose>, <c:when> 그리고
<c:otherwise> 태그를 이용해 if/then/else 문과 동일한 결과를 얻을수 있다.
<c:choose>
<c:when test="${customer.country == 'UK'}">
UK has mild winters.
</c:when>
<c:when test="${customer.country == 'Canada'}">
Canada has wild winters.
</c:when>
<c:when test="$customer.country == 'UAE'}">
UAE has hot winters and good gold.
</c:when>
<c:otherwise>
Country is unknown.
</c:otherwise>
</c:choose>
Iteration Actions
객체집합의 반복문은 <c:forEach> 를 사용할수 있다. 아래예제는 고객 리스트를 출력한다.
<c:forEach var="customer" items="${customers}">
Customer: <c:out value="${customer}"/>
</c:forEach>
<c:forEach>태그는 시작과 끝을 지정하여 반복문을 사용할수 있다. 아래예를 보라
<c:forEach var="k" begin="1" end"100">
<c:out value="${i % 2 == 0}"/>
</c:forEach>
좀더 완벽한 예로 모든 헤더 정보를 받아오는 아래 예문을 살펴보자
<%@ taglib prefix="c" uri="http://java.sun.com/jstl/core" %>
<html>
<head>
<title>JSTL Implicit Objects</title>
</head>
<body bgcolor="#FFFFCC">
<h3>Header info:</h3>
<c:forEach var="head" items="${headerValues}">
param: <c:out value="${head.key}"/><br>
values:
<c:forEach var="val" items="${head.value}">
<c:out value="${val}"/>
</c:forEach>
<p>
</c:forEach>
</body>
</html>
특별히 원하는 헤더정보를 출력하고 싶다면 (예: User-Agent
), 다음과 같은 구문으로 대치하면 된다. : ${header['User-Agent']}
.
URL Actions
<jsp:include> 액션은 해당 페이지와 동일한 컨텍스트에 위치한 정적 또는 동적인 리소스를 포함할수 있다. 이 액션은 널리 사용되지만 remote 환경에서의 사용은 불가능하다.
JSTL은 광범위한 URL 설정이 가능하다. 예로 <c:import> 액션은 local 또는 remote 상의 리소스를 포함할수 있다. 아래에 예제가 있다.
<c:import url="./copyright.html"/>
<c:import url="http://www.somewhere.com/hello.xml"/>
<c:url>액션은 모드 URL의 rewriteing tasks를 고려한다. 이것은 <c:param>액션을 포함할수도 있다.
아래예제를 살펴보자.
<c:url value="http://www.somewhere.com/customers/register" var="registrationURL">
<c:param name="name" value="${param.name}"/>
<c:param name="country" value="${param.country}"/>
</c:url>
<a href='<c:out value="${registrationURL}"/>'>Customer Registration</a>
마지막으로 , <c:redirect>은
( HTTP redirect을 지원하기 위함) 아래 예처럼 사용가능하다.
<c:redirect url="https://www.somewhere.com/register">
XML Tags
XML의 비중은 날로 커지고 있다. 그리고 JSTL은 XML 액션을 제공한다.
XML액션은 core, 흐름제어 그리고 변환 액션이 으로 분류되어 있다.
XML core 액션은 위에서 언근한 Core 액션과 흡사하며, <x:out>, <x:set>
, and <x:parse> 를 포함한다. Core 액션과 XML core 액션의 가장 큰차이점으로 Core 액션은 XPath를 사용할수 없지만 XML 액션은 XPath 표현을 지원한다.
사실, XML액션은 XPath 표현에 기반을 둔다. XPath가 친숙하지 않다면 XML document 파트에 정의되어있다. (원본 문서 참조 ~.. 실상 별거 없음 단지 xml의 노드를 경로로 사용하는거 뿐임 )
XML 흐름제어 액션들은 앞에서 언급한 코어 액션과 동일하다.
<x:if>
, <x:choose>
, <x:when>
, <x:otherwise>
, and <x:forEach>
.
차이점이라면 역시 xpath를 이용한다는것이다. 아래에 예제가 있다. :
<x:forEach select="$output/portfolio/stock">
<x:out select="price"/>
</x:forEach>
이제, set of examples 을 보자
xml-ex1.jsp 는 xml문서를 처리하기 위해 core와 xml태그 라이브러리를 사용한다.
이예제에서 xml문서는 jsp페이지 내에 포함되고 <x:parse>태그는 이것을 해석한다.
그리고 XPath 표현은 xml문서에서 items를 선택하는데 사용된다.
Code Sample 1: xml-ex1.jsp
<%@ taglib prefix="c" uri="http://java.sun.com/jstl/core" %>
<%@ taglib prefix="x" uri="http://java.sun.com/jstl/xml" %>
<html>
<head>
<title>JSTL Support for XML</title>
</head>
<body bgcolor="#FFFFCC">
<h3>Books Info:</h3>
<c:set var="xmltext">
<books>
<book>
<title>Book Title A</title>
<author>A. B. C.</author>
<price>17.95</price>
</book>
<book>
<title>Book Title B</title>
<author>X. Y. Z.</author>
<price>24.99</price>
</book>
</books>
</c:set>
<x:parse xml="${xmltext}" var="output"/>
<b>The title of the first book is</b>: <x:out select="$output/books/book[1]/title"/>
<br>
<b>The price of the second book</b>: <x:out select="$output/books/book[2]/price"/>
</body>
</html>
xmo-ex1.jsp를 웹브라우저에서 실행하면 아래 그림과 같은 결과를 볼수 있다.
Figure 1: JSTL support for XML
위 예제에서 xml 문서가 jsp페이지 내에 txt타입으로 포함되었다. 하지만 실제 어플리케이션에서 xml문서는 로칼 혹은 리모트 웹서버에 존재할수도 있다. 리모트 리소를 사용하기 위해서는 <c:import>를 이용하면 된다. ( http://www.javacourses.com/stocks.xml 을 참조하는 Code Sample 2 를 보라)
Note: If you'd like to see how JSP pages can be used (and the amount of code involved) in processing stocks.xml
, take a look at Web Application Development with JSP pages and XML.
Code Sample 2: stocks.xml
<?xml version="1.0" encoding="UTF-8"?>
<portfolio>
<stock>
<symbol>SUNW</symbol>
<name>Sun Microsystems</name>
<price>17.1</price>
</stock>
<stock>
<symbol>AOL</symbol>
<name>America Online</name>
<price>51.05</price>
</stock>
<stock>
<symbol>IBM</symbol>
<name>International Business Machines</name>
<price>116.10</price>
</stock>
<stock>
<symbol>MOT</symbol>
<name>Motorola</name>
<price>15.20</price>
</stock>
</portfolio>
이 문서는 아래 코드와 같이 사용해서 import 될수 있다.
<c:import url="http://www.javacourses.com/stocks.xml" var="xmldoc"/>
XML Conditional Logic
XLM 태그라이브리 의 조건로직은 core 태그라이브리에서와 동일하다. 하나의 예로 아래코드는 xml문서를 해석한후 SUNW 라는 심볼을 가진 stock을 선택한다.
<x:parse xml="${xmldoc}" var="output"/>
<x:if select="$output/portfolio/stock[symbol = 'SUNW']">
You still have Microsystems Stocks!
</x:if>
if/then/else
<x:choose> action이용해 if/then/else 절을 구현할수 있다.
이것은 다음과 같은 순서로 구성된다. : <x:when>
-- <x:otherwise>.
각각의 <x:when>
엘리먼트는 하나의 속성을 가지며, XPath 표현으로 선택된다.
예제:
<x:parse xml="${xmldoc}" var="output"/>
<x:choose>
<x:when select="$output/portfolio/stock[price > '70']">
You still have stocks worth over $70.
</x:when>
<x:otherwise>
You have no stocks worth over $70.
</x:otherwise>
</x:choose>
Iteration (반복)
<x:forEach>은 주어진 XPath 표현식에 의해 반복 작업을 수행한다.
아래 예 Code Sample3(xml-ex2.jsp) 은 xml문서에서 stock 정보를 어떻게 출력하는지 잘 보여주고 있다.
Code Sample 3: xml-ex2.jsp
<%@ taglib prefix="c" uri="http://java.sun.com/jstl/core" %>
<%@ taglib prefix="x" uri="http://java.sun.com/jstl/xml" %>
<html>
<head>
<title>JSTL Support for XML</title>
</head>
<body bgcolor="#FFFFCC">
<h3>Portfolio</h3>
<c:import url="http://www.javacourses.com/stocks.xml" var="xmldoc"/>
<x:parse xml="${xmldoc}" var="output"/>
<p>
<table border="2" width="50%">
<tr>
<th>Stock Symbol</th>
<th>Company Name</th>
<th>Price</th>
</tr>
<tr>
<x:forEach select="$output/portfolio/stock" var="item">
<td><x:out select="symbol"/></td>
<td><x:out select="name"/></td>
<td><x:out select="price"/></td></tr>
</x:forEach>
</table>
</body>
</html>
아래 그림과 같은 결과를 얻을수 있다.
Figure 2: Importing and parsing an XML document, then iterating over its nodes
Transforming XML
많은 웹 어플리케이션이 jsp페이지에서 xslt 스타일시트를 이용해 xml 을 변형한다. 그리고 JSTL 역시 이것을 지원한다.
아래 예를 보자.
Code Sample 4: stocks.xsl
<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl=
"http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="html" indent="yes"/>
<xsl:template match="/">
<html>
<body>
<xsl:apply-templates/>
</body>
</html>
</xsl:template>
<xsl:template match="portfolio">
<table border="2" width="50%">
<xsl:for-each select="stock">
<tr>
<td>
<i><xsl:value-of select="symbol"/></i>
</td>
<td>
<xsl:value-of select="name"/>
</td>
<td>
<xsl:value-of select="price"/>
</td>
</tr>
</xsl:for-each>
</table>
</xsl:template>
</xsl:stylesheet>
아래 xml-ex3.jsp는 리모트 웹서버 상에 존재하는 xml 문서를 stocks.xsl 스타일시트를 이용해 어떻게 변환하는지 보여주고 있다.
Code Sample 5: xml-ex3.jsp
<%@ taglib prefix="c" uri="http://java.sun.com/jstl/core" %>
<%@ taglib prefix="x" uri="http://java.sun.com/jstl/xml" %>
<html>
<head>
<title>JSTL: Importing XML Document</title>
</head>
<body bgcolor="#FFFFCC">
<h3>Transforming stocks.xml into HTML using stocks.xsl</h3>
<c:import url="http://www.javacourses.com/stocks.xml" var="xmldocument"/>
<c:import url="./stocks.xsl" var="xslt"/>
<x:transform xml="${xmldocument}" xslt="${xslt}"/>
</body>
</html>
다음과 같은 결과를 얻는다.
Figure 3: Transforming an XML document using an XSLT stylesheet
Conclusion
JSTL (The JavaServer Pages Standard Tag Library )은 확신한다.
The JavaServer Pages Standard Tag Library (JSTL) satisfies the demand for a set of standard JSP custom tags to handle common tasks needed by all JSP pages, including conditional processing, XML processing, internationalization, and database access. As you can see from this article, JSTL is easy to work with, and its reusable standard custom tags lead to faster development of web applications.
Now that you know the basics of the JSTL, you can explore the rest of the tag libraries on your own. Have fun!
For More Information
JavaServer Pages
JavaServer Pages Standard Tag Library
JSTL 1.0 Specification (JSR-52)
JSTL 1.0 Implementation
Acknowledgments
Special thanks to Pierre Delisle (Editor and Co-Lead of the JSTL Specification) at Sun Microsystems for his contributions to this article.
About the Author
Qusay H. Mahmoud provides Java consulting and training services. He has published dozens of articles on Java, and is the author of Distributed Programming with Java (Manning Publications, 1999) and Learning Wireless Java (O'Reilly, 2002).