개요
JSTL(JSP Standard Tag Library)를 설명한다.
목차
1. 개요
JSTL(JSP Standard Tag Library)를 설명한다. 프레임워크에서는 JSTL을 구성하는 4개의 태그 라이브러리 중에서 core 태그 라이브러리만을 사용한다.
종류 |
설명 |
prefix |
uri |
core |
데이터 출력, 제어문, URL 처리 등 기본 기능 |
c |
|
format |
I18N 데이터 포멧 기능 |
fmt |
|
xml |
XML 문서에 대한 처리 |
x |
|
sql |
JDBC 작업 수행 |
sql |
표 1. JSTL 태그 라이브러리
2. 설정
JSTL을 사용하려면 아래 파일이 웹 어플리케이션 디렉토리에 위치해야 한다.
파일 |
설명 |
WEB-INF/lib/jstl.jar |
JSTL API 라이브러리 |
WEB-INF/lib/standard.jar |
JSTL 구현 라이브러리 |
WEB-INF/tld/c.tld |
JSTL core TLD 파일 |
표 2. JSTL 설정을 위한 파일
J2EE 1.3에서는 JSTL 1.0 라이브러리를, J2EE 1.4에서는 JSTL 1.1 라이브러리를 사용한다. 라이브러리는 다음(http://jakarta.apache.org/taglibs/doc/standard-doc/intro.html)에서 다운로드한다.
그리고 web.xml 파일에 태그 라이브러리를 설정한다. 아래는 J2EE 1.3을 사용하는 경우의 설정이다.
web.xml
<taglib>
<taglib-uri>http://java.sun.com/jstl/core</taglib-uri>
<taglib-location>/WEB-INF/c.tld</taglib-location>
</taglib>
그리고 아래는 J2EE 1.4를 사용하는 경우의 설정이다.
web.xml
<jsp-config>
<taglib>
<taglib-uri>http://java.sun.com/jsp/jstl/core</taglib-uri>
<taglib-location>/WEB-INF/c.tld</taglib-location>
</taglib>
</jsp-config>
3. JSTL의 사용
JSTL을 사용하는 모든 JSP 파일 상단에 아래 내용을 추가한다.
Example.jsp
<%@ page contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jstl/core" %>
그런데 J2EE 1.3과 J2EE 1.4에 따라서 uri 속성의 값이 다르다. 이에 따른 수정 영향을 최소화하기 위해서 BaseJsp.jsp 파일을 사용한다.
Example.jsp
<%@ page contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>
<%@ include file="/BaseJsp.jsp" %>
BaseJsp.jsp의 내용은 아래와 같다. 프레임워크가 제공하는 태그 라이브러리 설정도 포함한다.
BaseJsp.jsp
<%@ taglib prefix="c" uri="http://java.sun.com/jstl/core" %>
<%@ taglib prefix="framework" uri="http://www.naver.com/ctl/framework" %>
<%@ taglib prefix="ui" uri="http://www.naver.com/ctl/ui" %>
4. Expression!! Language
(1) Expression!! Language 개요
JSTL은 Expression!! Language(이하 EL)를 사용한다. EL은 데이터 혹은 객체를 표현하는데 사용하는 스크립트 언어로 ${} 안에서 사용한다.
// 동적인 표현 작업 수행
${Some Expression!!}
EL로 아래의 작업을 수행한다.
JSP 저장 영역(page, request, session, application)에 대한 접근
java.util.Collection, java.util.Map, 배열 등의 객체 처리
POJO 유형의 객체 처리
수치, 비교, 논리 연산자 적용
J2EE 1.3에서는 EL을 JSTL 태그의 속성 값에서만 사용할 수 있다. 그러나 J2EE 1.4에서는 EL을 JSP와 JSTL 모두에서 사용할 수 있다.
(2) Expression!! Language 기본 객체
EL에서 사용 가능한 주요 JSP API에 대한 Alias는 아래와 같다.
종류 |
기본 객체 |
예제 |
JSP 저장 영역 |
pageScope - PageContext 속성 requestScope - HttpServletRequest 속성 sessionScope - HttpSession 속성 applicationScope - ServletContext 속성 |
${requestScope.name} |
HTTP 요청 파라미터 |
param - HttpServletRequest 파라미터 paramValues - 동일 파라미터 이름에 값이 2개 이상 존재하는 경우 |
${param.name} |
JSP 객체 |
pageContext - PageContext cookie - 이름을 키로, Cookie를 값으로 하는 java.util.Map header - 해더 이름을 키로, 해더 값을 값으로 하는 java.util.Map headerValues - 동일 해더 이름에 값이 2개 이상 존재하는 경우 initParam - JSP 초기 변수 |
${cookie.JSESSIONID.name} ${headerValues['HOST'][0]}" |
표 3. EL 기본 객체
(3) 객체 사용
기본 데이터 타입(Boolean, Integer, Long, String 등)은 아래처럼 사용한다.
request.setAttribute("name", "성선임");
// 성선임을 출력한다.
${requestScope.name}
// 성선임을 출력한다. 영역을 지정하지 않으면 page, request, session, application 순
// 으로 검색한다.
${name}
// null을 출력하지 않고 아무 것도 출력하지 않는다.
${password}
<?xml:namespace prefix = st1 ns = "urn:schemas-microsoft-com:office:smarttags" /><?xml:namespace prefix = st1 /><?xml:namespace prefix = st1 /><?xml:namespace prefix = st1 />POJO 객체의 경우에는 파라미터가 없는 get으로 시작하는 메소드에서 get을 제외한 나머지 메소드 이름의 첫번째 단어를 소문자로 해서 사용한다.
Book.java
public class Book {
private String isbn;
public Book(String isbn) {
this.isbn = isbn;
public void getIsbn() {
return this.isbn;
}
public void setIsbn(String isbn) {
this.isbn = isbn;
}
public String toString() {
return "book-object";
}
}
Example.jsp
Book book = new Book("100");
request.setAttribute("favoriteBook", book);
// toString 메소드가 반환하는 값을 출력한다. 즉 book-object를 출력한다.
${favoriteBook}
// . 연산자를 사용해서 getIsbn 메소드가 반환하는 값을 출력한다. 즉 100을 출력한다.
${favoriteBook.isbn}
// [] 연산자를 사용해도 결과는 동일하다.
${favoriteBook['isbn']}
// 값이 없는 경우에 NullPointerException이 발생하지 않는다.
${nullBook.isbn}
// 해당하는 메소드가 없는 경우에는 예외가 발생한다.
${book.title}
배열 객체는 아래처럼 사용한다.
Book[] books = new Book[2];
books[0] = new Book("100");
books[1] = new Book("200");
request.setAttribute("books", books);
// 100을 출력한다.
${books[0].isbn}
// 200을 출력한다.
${books[1].isbn}
java.util.Map 객체는 아래처럼 사용한다. 단 키의 유형은 항상 java.lang.String이어야 한다.
Map map = new HashMap();
map.put("one", new Integer(1));
map.put("sub.one", new Integer(2));
request.setAttribute("numbers", map);
// .와 [] 연산자를 모두 사용할 수 있다. 1을 출력한다.
${number.one}
${number['one']}
// 키가 . 등의 문자를 포함하면 [] 연산자를 사용한다. 2를 출력한다.
${number['sub.one']}
// java.util.Map은 키가 존재하지 않아도 예외가 발생하지 않는다.
${number.two}
(4) 연산자
EL에서 아래의 수치 연산자를 사용할 수 있다.
연산자 |
설명 |
예제 |
결과 |
+ |
더하기 |
${10 + 2} |
12 |
- |
빼기 |
${10 - 2} |
8 |
* |
곱하기 |
${10 * 2} |
20 |
/ 또는 div |
나누기 |
${10 / 2} 또는 ${10 div 2} |
5 |
% 또는 mod |
나머지 |
${10 % 3} 또는 ${10 mod 3} |
1 |
표 4. EL 수치 연산자
숫자형이 아니면 숫자형으로 자동 전환을 한 후에 연산을 수행한다.
// 101이 아닌 11을 출력한다.
${"10" + 1}
// null은 0으로 처리한다. 1을 출력한다.
${null + 1}
// 숫자가 아니면 예외가 발생한다.
${"일" + 10}
EL이 제공하는 비교 및 논리 연산자는 아래와 같다. >, < 등 XML 태그와 혼동할 우려가 있는 연산자는 문자열 연산자(gt, lt)로 표현하는 것을 권장한다.
연산자 |
예제 |
결과 |
== 또는 eq |
${5 == 5} 또는 ${5 eq 5} |
true |
!= 또는 ne |
${5 != 5} 또는 ${5 ne 5} |
false |
< 또는 lt |
${5 < 7} 또는 ${5 lt 7} |
true |
> 또는 gt |
${5 > 7} 또는 ${5 gt 7} |
false |
<= 또는 le |
${5 <= 5} 또는 ${5 le 5} |
true |
>= 또는 ge |
${5 >= 6} 또는 ${5 ge 6} |
false |
&& 또는 and |
${true && false} 또는 ${true and false} |
false |
|| 또는 or |
${true || false} 또는 ${true or false} |
true |
! 또는 not |
${!true} 또는 ${not true} |
false |
empty |
${empty name} |
name이 null이거나 빈 문자열이면 true |
not empty |
${not empty name} |
name이 null도 아니고 빈 문자열도 아니면 true |
표 5. EL 비교 및 논리 연산자
5. core
(1) c:out
객체를 화면에 출력한다.
// out.println(request.getAttribute("name"));
<c:out value="${name}"/>
// 값이 없는 경우에 기본 값을 출력하려면 default 속성을 이용한다.
<c:out value="${age}" default="값이 없습니다."/>
// 기본적으로 XML 문자를 escape한다. Escape 하지 않으려면 escapeXml을 false로 한다.
<c:out value="${name}" escapeXml="false"/>
(2) c:set
저장 영역에 객체를 저장한다.
// request.setAttribute("name", "<?xml:namespace prefix = st2 ns = "urn:schemas:contacts" /><?xml:namespace prefix = st2 /><?xml:namespace prefix = st2 /><?xml:namespace prefix = st2 />송태섭");
// scope 속성으로는 page(기본), request, session, application을 사용.
<c:set scope="request" var="name" value="송태섭"/>
// Book book = (Book) request.getAttribute("book");
// book.setIsbn("300");
<c:set scope="request" target="book" property="isbn" value="300"/>
(3) c:remove
저장 영역에서 객체를 삭제한다.
// request.removeAttribute("name");
<c:remove scope="request" var="name"/>
(4) c:if
조건문을 제어한다.
// test 속성의 값이 true면 c:if 태그의 body 내용을 수행한다.
<c:if test="${not empty flag}">
flag가 존재하면 이 영역을 수행한다.
</c:if>
(5) c:choose, c:when, c:otherwise
복합 조건문을 제어한다.
// c:choose 태그는 1개 이상의 c:when 태그와 0 또는 1개의 c:otherwise 태그로 구성
<c:choose>
<c:when test="${flag == 1}">
flag가 1이면 이 영역을 수행한다.
</c:when>
<c:when test="${flag == 2}">
flag가 2이면 이 영역을 수행한다.
</c:when>
<c:otherwise>
flag가 1도 2도 아니면 이 영역을 수행한다.
</c:otherwise>
</c:choose>
(6) c:forEach
반복문을 수행한다.
<%
for (int i = 0; i < 10; i++) {
out.println(i);
}
%>
// 0 1 2 3 4 5 6 7 8 9를 출력한다.
<c:forEach begin="0" end="9" var="i">
<c:out value="${i}"/>
</c:forEach>
step 속성으로 간격을 조정한다.
<%
for (int i = 0; i < 10; i += 2) {
out.println(i);
}
%>
// 0 2 4 6 8을 출력한다.
<c:forEach begin="0" end="9" step="2" var="i">
<c:out value="${i}"/>
</c:forEach>
java.util.Collection 객체나 배열에 대해서는 아래처럼 한다.
<%
Collection books = (Collection) request.getAttribute("books");
for (Iterator all = books.iterator(); all.hasNext();) {
Book each = (Book) all.next();
out.println(each.getIsbn());
}
%>
<c:forEach items="${books}" var="book">
<c:out value="${book.isbn}"/>
</c:forEach>
items 속성 값으로 기본 타입의 배열, java.util.Collection, java.util.Map, java.util.Iterator, java.util.Enumeration, java.lang.Object 배열, 콤마로 이루어진 java.lang.String 등의 객체를 사용할 수 있다.
java.util.Map 객체는 아래처럼 사용한다.
<%
Map books = new HashMap();
books.put("one", new Book("100"));
books.put("two", new Book("200"));
request.setAttribute("books", books);
%>
// one 100 two 200을 출력한다. (순서는 정확하지 않다.)
<c:forEach items="${books}" var="book">
<c:out value="${book.key}"/>
<c:out value="${book.value.isbn}"/>
</c:forEach>
(7) c:forTokens
구분자로 반복문을 수행한다.
//1 2 3 4를 출력한다.
<c:forTokens delims="," items="1,2,3,4" var="i">
<c:out value="${i}"/>
</c:forTokens>
begin, end, step 속성으로 시작 위치, 종료 위치, 간격을 조정한다.
(8) c:url, c:param
URL를 처리한다.
// UserForm.jsp를 출력한다.
<c:url value="UserForm.jsp"/>
// value 속성 값이 /로 시작하면 컨텍스트를 포함한다.
// 컨텍스트를 web으로 가정하면 /web/UserForm.jsp를 출력한다.
<c:url value="/UserForm.jsp"/>
// 다른 컨텍스트를 사용하려면 context 속성을 사용한다.
// 이 때는 value와 context 속성의 값이 모두 /로 시작해야 한다.
// /other/UserForm.jsp를 출력한다.
<c:url value="/UserForm.jsp" context="/other"/>
scope과 var 속성을 이용해서 URL을 화면에 출력하지 않고 JSP 영역에 저장할 수 있다.
c:param 태그를 이용해서 Query String을 URL에 추가한다.
// 파라미터 값을 escape한다. 따라서
// UserForm.jsp?name=%EC%A0%95%EB%8C%80%EB%A7%8C을 출력한다.
<c:url value="UserForm.jsp">
<c:param name="name" value="성선임"/>
</c:url>
c:param 태그는 c:import!와 c:redirect 태그에서도 동일한 방법으로 사용한다.
(9) c:import!
특정 JSP의 내용을 화면에 포함해서 출력한다.
// UserForm.jsp의 내용을 화면에 포함하여 출력한다.
<c:import! url="UserForm.jsp"/>
데이터 인코딩에 문제가 있으면 charEncoding 속성을 사용한다.
<c:import! url="UserForm.jsp" charEncoding="UTF-8"/>
// context 속성을 이용하면 다른 어플리케이션의 JSP도 포함할 수 있다.
<c:import! url="/UserForm.jsp" charEncoding="UTF-8" context="/other"/>
var와 varReader 속성을 이용하면 내용을 화면에 출력하지 않고 변수에 저장할 수 있다.
(10) c:redirect
다른 경로로 이동한다.
// 앞에 데이터를 웹 브라우저에 전송하는 코드가 없어야 한다.
<c:redirect url="http://www.naver.com"/>
(11) c:catch
예외를 처리한다.
// var 속성 값으로 발생한 예외 객체를 page 영역에 저장한다.
<c:catch var="e">
<%
if (true) throw new RuntimeException();
%>
</c:catch>
<c:out value="${e}"/>
6. 참고 자료
The
J2EE 1.3 Tutorial
http://java.sun.com/j2ee/1.3/docs/tutorial/doc/index.html
The
J2EE 1.4 Tutorial
http://java.sun.com/j2ee/1.4/docs/tutorial/doc/index.html
JSTL in Action
JSTL 1.0 Specification
http://jcp.org/aboutJava/communityprocess/final/jsr052
'공부 > JSTL' 카테고리의 다른 글
JSTL_[ forEach, forTokens 에서 varStatus 사용법 ] (0) | 2014.04.08 |
---|---|
JSTL_[ Function(fn) 기초문법 ] (0) | 2013.03.26 |
JSTL_[ Web.xml에 taglib element 추가하기 ] (0) | 2013.03.26 |