JSTL (JSP Standard Tag Library) 시작하기 - 이해 및 실습 :: 소림사의 홍반장!

STL의 이해 및 활용

1. JSTL의 이해

  • http://tomcat.apache.org/taglibs/
  • JSTL이란 JSP 표준라이브러리(JSP Standard Tag Library) 이다.
  • JSP에서 사주 사용하는 기능(반복과 조건, 데이타 관리 포맷, XML 조작, 데이타베이스 액세스)을 구현하는 커스텀 태그 라이브러리 모음이다.
  • 시간, 날짜, 숫자의 포맷이나 문자열 가공등의 처리에서 비즈니스로직과 프리젠테이션 로직을 분리할 수 있게 해준다.
  • JSTL은 EL(Expression Language)를 사용하여 표현한다.

2. JSTL 라이브러리

2.1 JSTL 라이브러리

  • 아래와 같이 다섯가지의 라이브러리가 있다.
라이브러리기능URI 식별자접두어
코어일반 프로그램 언어에서 제공하는 변수선언, 
조건/제어/반복문등의 기능을 제공한다.
http://java.sun.com/jsp/jstl/corec
포맷팅숫자,날짜,시간을 포맷팅 하는 기능과 국제화, 다국어 지원 기능을 제공한다.http://java.sun.com/jsp/jstl/fmtfmt
함수문자열을 처리하는 함수를 제공한다.http://java.sun.com/jsp/jstl/functionsfn
데이터베이스데이터베이스의 데이터를 입력/수정/삭제/조회하는 기능을 제공한다.http://java.sun.com/jsp/jstl/sqlsql
XML처리XML 문서를 처리할 때 필요한 기능을 제공한다.http://java.sun.com/jsp/jstl/xmlx

2.2 JSTL 설정

  • pom.xml 파일에서 JSTL관련 설정을 확인 한다.
pom.xml
 ...
  <dependencies>
 ...
    <!-- taglibs -->
    <dependency>
        <groupId>taglibs</groupId>
        <artifactId>datetime</artifactId>
        <version>1.0.1</version>
    </dependency>        
    <dependency>
        <groupId>taglibs</groupId>
        <artifactId>string</artifactId>
        <version>1.1.0</version>
    </dependency>        
    <dependency>
        <groupId>taglibs</groupId>
        <artifactId>standard</artifactId>
        <version>1.1.2</version>
    </dependency>
    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>jstl</artifactId>
        <version>1.1.2</version>
    </dependency>
  </dependencies>    

 

2.3 JSTL 사용

  • 아래와 같이 taglib 지시문을 이용하여 선언하고 접두어를 이용하여 사용한다.
.jsp
 <!-- 선언부 -->
<%@ taglib prefix="c"   uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<%@ taglib prefix="fn"  uri="http://java.sun.com/jsp/jstl/functions" %>

<!-- 사용-->
<c:set var="hello" value="Hello" />
${hello}
 

3. Core Tag의 이해

  • JSTL 태그 라이브러리 중에 가장 많이 사용하는 태그이다.
  • <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>로 선언을 해줘야 사용할 수 있다.

3.1 <c:set/>, <c:remove/>

  • 변수의 선언 및 제거 역할을 한다.
  • set : JSP의 setAttribute()와 같은 역할.
  • remove : JSP의 removeAttribute()와 같은 역활
<c:set/>, <c:remove/> Syntax 및 예
<!-- scope 속성은 선택적이며 page로 기본 설정되어 있다. -->
<c:set  var="변수명"  value="할당된 값"
        scope="변수의 유효 범위 page|request|session|application" />

<!-- 간단 사용 예 -->
<c:set var="country" value="Korea" />
<c:set var="intArray" value="<%=new int[] {1,2,3,4,5} %>" />
<c:remove var="country" />

 

3.2 <c:out/>

  • 변수의 출력 기능을 한다. JSP의 표현식(<%= %>)을 대체하는 기능이다.
  • escapeXML값이 true일 경우 값 중에 포함된 <,>,&,'," 문자들을 각각 <, >, &, ', "로 변환하여 출력 한다.
  • default 속성과 excapeXML 속성을 사용하지 않는 경우 EL형식으로 많이 사용한다.
<c:out/> Syntax 및 예
<!-- Syntax -->
<c:out var="변수명" default="기본값" escapeXML="true|false" />

<!-- 간단 사용 예 -->
<p><c:out value="${country}" default="Korea" escapeXml="true"/></p>
<p>${country}</p>
<p>${intArray[0]}</p>

 

3.3 <c:if/>

  • 조건문으로 if문과 동일하지만 else 구문이 없다.
  • 테스트의 결과를 var와 scope 속성을 통해 범위 변수로 할당할 수 있다.
  • 이 기능은 테스트 비용이 비쌀 경우 유용하다.
<c:if/> Syntax 및 예
<!-- Syntax -->
<c:if test="expression"  var="name"  scope="scope">
body content
</c:if>

<!-- 간단 사용 예 -->
<c:set var="login" value="true" />

<c:if test="${!login}"> <p><a href="/login.ok">로그인</a></p></c:if>
<c:if test="${login}"> <p><a href="/logout.ok">로그아웃</a></p></c:if>

<!-- 아래 예제와 같이 null 비교를 하지 않고 empty 비교를 하면 null과 ""를 동시에 체크할 수 있다. -->
<c:if test="${!empty country}"><p><b>${country}</b></p></c:if>
 
 

3.4 <c:choose/>, <c:when/>, <c:otherwise/>

  • java의 swith문과 비슷하지만 문자열 비교도 가능하다.
  • <c:if/>문에 else 구문이 없기 때문에 else의 대체 기능으로 많이 사용한다
<c:choose/>, <c:when/>, <c:otherwise/> Syntax 및 예
<!-- Syntax -->
<c:choose>
<c:when test="expression">
body content
</c:when>
...
<c:otherwise>
body content
</c:otherwise>
</c:choose>

<!-- 간단 사용 예 -->
<c:choose>
  <c:when test="${login}">
    <p><a href="/logout.ok">로그아웃</a></p>
  </c:when>
  <c:otherwise>
    <p><a href="/login.ok">로그인</a></p>
  </c:otherwise>
</c:choose>
 
 

3.5 <c:forEach/>

  • 반복문을 실행할 때 사용 한다.
  • 정수 범위내의 반복(이를 테면, 자바의 for 문)과 컬렉션내의 반복(자바의 Iterator와 Enumeration 클래스)을 지원한다.
  • begin : 시작값 , end : 마지막값 , step : 증가값, var 변수, items:컬렉션 객체, varStatus : 추가속성값
<c:forEach/> Syntax 및 예
<!-- 정수 범위내의 반복 Syntax -->
<c:forEach var="name" varStatus="name"
            begin="expression" end="expression" step="expression">
  body content
</c:forEach>

<!-- 컬렉션 범위내의 반복 Syntax -->
<c:forEach var="name" items="expression" varStatus="name"
           begin="expression" end="expression " step="expression">
  body content
</c:forEach>

<!-- forEach 정수 범위내의 반복 -->
<c:forEach var="i" begin="0" end="10" step="2" varStatus="x">
  <p> i = ${i}, i*i = ${i * i} <c:if test="${x.last}">, last = ${i}</c:if> </p>
</c:forEach> 

<!-- forEach 컬렉션 범위내의 반복 -->
<%
  java.util.List list = new java.util.ArrayList(); 

  java.util.Map map = new java.util.HashMap();
  map.put("color","red");
  list.add(map);
  
  map = new java.util.HashMap();
  map.put("color","blue");
  list.add(map);
  
  map = new java.util.HashMap();
  map.put("color","green");
  list.add(map);
  
  request.setAttribute("list", list);
%>

<c:forEach var="map" items="${list}" varStatus="x">
  <p> map(${x.index}) = ${map.color}  </p>
</c:forEach>
 
 
  • LoopTagStatus 객체의 속성
    속성메소드설명
    currentgetCurrent()현재 아이템
    indexgetIndex()제로 기반(zero-based) 인덱스 값
    countgetCount()1 기반(one-based) 인덱스 값
    firstisFirst()첫 번째 값 여부
    lastisLast()마지막 값 여부
    begingetBegin()begin 속성의 값
    endgetEnd()end 속성의 값
    stepgetStep()step 속성의 값

3.6 <c:forTokens/>

  • 문자열을 주어진 구분자(delimiter)로 분할 하여 반복문을 실행한다.
<c:forTokens/> Syntax 및 예
<!-- Syntax -->
<c:forTokens var="name" items="expression"
             delims="expression" varStatus="name"
             begin="expression" end="expression" step="expression">
  body content
</c:forTokens> 

<!-- 간단 사용 예 -->
<b>
<c:forTokens var="color" items="빨|주|노|초|파|남|보" delims="|" varStatus="i" >
     <c:if test="${i.first}">color : </c:if>
     ${color} 
     <c:if test="${!i.last}">,</c:if>
</c:forTokens>
</b> 

 
 

3.7 CoreJSTL.jsp

  • 현재까지 설명한 내용을 CoreJSTL.jsp 파일로 만들어서 실습해 보자
  • http://localhost:8080/el/CoreJSTL.jsp 로 예제를 실행시킨다.
  • 아래는 CoreJSTL.jsp 의 전체 소스이다.
/webapps/el/CoreJSTL.jsp
<%@ page language="java" isELIgnored="false" contentType="text/html; charset=UTF-8"%>
<%@ taglib prefix="c"   uri="http://java.sun.com/jsp/jstl/core" %>

<html>
<body>

<!-- set, out -->
<c:set var="country"  value="Korea" />
<c:set var="intArray" value="<%=new int[] {1,2,3,4,5}%>" />
<p><c:out value="${country}" default="Korea" escapeXml="true"/></p>
<p>${country}</p>
<p>${intArray[0]}</p>

<!--  if -->
<c:set var="login" value="true" />
<c:if test="${!login}">
 <p><a href="/login.ok">로그인</a></p>
</c:if>
<c:if test="${login}">
 <p><a href="/logout.ok">로그아웃</a></p>
</c:if>  
<c:if test="${!empty country}"><p><b>${country}</b></p></c:if>

<!-- choose, when, otherwise  -->
<c:choose>
  <c:when test="${login}">
    <p><a href="/logout.ok">로그아웃</a></p>
  </c:when>
  <c:otherwise>
    <p><a href="/login.ok">로그인</a></p>
  </c:otherwise>
</c:choose>

<!-- forEach 정수 범위내의 반복 -->
<c:forEach var="i" begin="0" end="10" step="2" varStatus="x">
  <p> i = ${i}, i*i = ${i * i} <c:if test="${x.last}">, last = ${i}</c:if> </p>
</c:forEach>

<!-- forEach 컬렉션 범위내의 반복 -->
<%
  java.util.List list = new java.util.ArrayList(); 
  java.util.Map map = new java.util.HashMap();
  map.put("color","red");
  list.add(map);
  map = new java.util.HashMap();
  map.put("color","blue");
  list.add(map);
  map = new java.util.HashMap();
  map.put("color","green");
  list.add(map);
  
  request.setAttribute("list", list);
%>

<c:forEach var="map" items="${list}" varStatus="x">
  <p> map(${x.index}) = ${map.color}  </p>
</c:forEach>

<!-- forTokens 예 --> 
<b>
<c:forTokens var="color" items="빨|주|노|초|파|남|보" delims="|" varStatus="i" >
     <c:if test="${i.first}">color : </c:if>
     ${color} 
     <c:if test="${!i.last}">,</c:if>
</c:forTokens>
</b>

<!-- remove -->
<c:remove var="country" />
<c:remove var="intArray" />

</body>
</html>

 

4. Format Tag의 이해

  • Format 관련 태그는 국제화와 포맷팅을 지원하는 라이브러리로 구성되어 있다.
  • <%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %> 선언을 해줘야 사용할 수 있다.
  • 라이브러리가 많지만 자주 사용하는 몇 개에 대해서만 알아 보도록 하자

4.1 <fmt:formatNumber>

  • 숫자의 형식을 특정 포맷으로 표현하는 태그이다. (Number → String)
  • value : 특정 형식으로 표현 할 값
  • type : 숫자, 통화, 퍼센트 중 지정 (number|currency|percent)
  • pattern : 사용자가 지정한 형식 패턴. (ex. #,#00.0#)
<fmt:formatNumber> Syntax 및 예
<!-- Syntax -->
<fmt:formatNumber value="numericValue"
        [type="{number|currency|percent}"]
        [pattern="customPattern"]
        [var="varName"]
        [scope="{page|request|session|application}"]/>

<!-- 간단 사용 예 -->
<fmt:setLocale value="ko_KR"/>
<p>number  : <fmt:formatNumber value="1234567.89" type="number"/></p>
<p>currency : <fmt:formatNumber value="1234567.89" type="currency" currencySymbol="₩" /> </p>
<p>percent : <fmt:formatNumber type="percent">0.159</fmt:formatNumber></p>
<p>pattern=".000"    :<fmt:formatNumber value="1234567.1" pattern=".000" /></p>
<p>pattern="#,#00.0#":<fmt:formatNumber value="1234567.891" pattern="#,#00.0#"/></p>
 

4.2 <fmt:parseNumber/>

  • formatNumber와 반대로 정해진 문자열에서 숫자를 파싱한다. . (String → Number)
  • integerOnly : 주어진 값에서 Integer 부분만 파싱할지 여부
<fmt:parseNumber/> Syntax 및 예
<!-- Syntax -->
<fmt:parseNumber [type="{number|currency|percent}"]
        [pattern="customPattern"]
        [parseLocale="parseLocale"]
        [integerOnly="{true|false}"]
        [var="varName"]
        [scope="{page|request|session|application}"]> 

<!-- 간단 사용 예 -->
<p>number  : <fmt:parseNumber value="1,234,567.89" type="number"/></p>
<p>currency : <fmt:parseNumber value="12345abcdef" integerOnly="false" type="number" /></p> 
 

4.3 <fmt:formatDate/>

  • 날짜와 시간 형식을 표현하는 태그이다.
  • value : 특정 형식으로 표현 할 값
  • type : 숫자, 통화, 퍼센트 중 지정 (number|currency|percent)
  • pattern : 사용자가 지정한 형식 패턴. (ex. #,#00.0#)
<fmt:formatDate/> Syntax 및 예
<!-- Syntax -->
<fmt:formatDate value="date"
        [type="{time|date|both}"]
        [dateStyle="{default|short|medium|long|full}"]
        [timeStyle="{default|short|medium|long|full}"]
        [pattern="customPattern"]
        [timeZone="timeZone"]
        [var="varName"]
        [scope="{page|request|session|application}"]/>

<!-- 간단 사용 예 -->
<c:set var="now" value="<%= new java.util.Date() %>" />
<p> date full : <fmt:formatDate value="${now}" type="date" dateStyle="full" /></p>
<p> date short : <fmt:formatDate value="${now}" type="date" dateStyle="short" /></p>
<p> time : <fmt:formatDate value="${now}" type="time" /></p>
<p> both full : <fmt:formatDate value="${now}" type="both" dateStyle="full" timeStyle="full" /></p>
<p> pattern 1 : <fmt:formatDate value="${now}" pattern="yyyy-MM-dd aa hh:mm:ss" /></p>
<p> pattern 2 : <fmt:formatDate value="${now}" pattern="yyyy-MM-dd  hh:mm:ss" /></p> 

 

4.4 FormatJSTL.jsp

  • 현재까지 설명한 내용을 FormatJSTL.jsp 파일로 만들어서 실습해 보자
  • http://localhost:8080/el/FormatJSTL.jsp 로 예제를 실행시킨다.
  • 아래는 FormatJSTL.jsp 의 전체 소스이다.
/webapps/el/FormatJSTL.jsp
<%@ page language="java" isELIgnored="false" contentType="text/html; charset=UTF-8"%>
<%@ taglib prefix="c"   uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>

<html>
<body>

<!-- Set Locale -->
<fmt:setLocale value="ko_KR" /> 

<!-- formatNumber -->
<p>number  : <fmt:formatNumber value="1234567.89" type="number"/></p>
<p>currency : <fmt:formatNumber value="1234567.89" type="currency" currencySymbol="₩"  /> </p>
<p>percent : <fmt:formatNumber type="percent">0.159</fmt:formatNumber></p>
<p>pattern=".000"    :<fmt:formatNumber value="1234567.1" pattern=".000" /></p>
<p>pattern="#,#00.0#":<fmt:formatNumber value="1234567.891" pattern="#,#00.0#"/></p>

<!-- parseNumber  -->
<p>number  : <fmt:parseNumber value="1,234,567.89" type="number"/></p>
<p>currency : <fmt:parseNumber value="12345abcdef" integerOnly="false" type="number" /></p>

<!-- formatDate -->
<c:set var="now" value="<%= new java.util.Date() %>" />
<p> date full : <fmt:formatDate value="${now}" type="date" dateStyle="full" /></p>
<p> date short : <fmt:formatDate value="${now}" type="date" dateStyle="short" /></p>
<p> time : <fmt:formatDate value="${now}" type="time" /></p>
<p> both full : <fmt:formatDate value="${now}" type="both" dateStyle="full" timeStyle="full" /></p>
<p> pattern 1 : <fmt:formatDate value="${now}" pattern="yyyy-MM-dd aa hh:mm:ss" /></p>
<p> pattern 2 : <fmt:formatDate value="${now}" pattern="yyyy-MM-dd  hh:mm:ss" /></p>

</body>
</html> 
 

5. Function Tag의 이해

  • Functon 태그는 자주 사용하는 유틸 함수의 기능을 제공한다.
  • <%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %> 선언을 해줘야 사용할 수 있다.

5.1 Function Tag 에서 지원하는 함수들

  • 아래 표는 Function Tag 에서 지원하는 함수들이다.
속성설명
fn:contains(string, sbustring)string이 substring을 포함하면 return True
fn:containsIgnoreCase(string, sbustring)대소문자 관계없이 string이 substring을 포함하면 return True
fn:endsWith(string, suffix)string이 suffix로 끝나면 return True
fn:escapeXml(string)stting에 XML과 HTML에서 특수문자(<,>,&,',")들이 있으면, XML엔티티 코드로 바꿔준뒤 문자열 반환
fn:indexOf(string, sbustring)string에서 substring이 처음으로 나타나는 인덱스 반환
fn:join(array, separator)array요소들을 separator를 구분자로 하여 연결해서 반환
fn:length(item)item이 배열이나 컬렉션이면 요소의 객수를 문자열이면 문자의 객수를 반환
fn:replace(string, before, after)string내에 있는 before 문자열을 after 문자열로 모두 변경해서 반환
fn:split(string, separator)string내의 문자열 separetor에 따라 나누어서 배열로 구성해서 반환
fn:startsWith(string, prefix)string이 prefix로 시작하면 return True
fn:substring(string, begin, end)string에서 begin인덱스에서 시작해서 end인덱스에 끝나는 부분의 문자열 반환
fn:substringAfter(string, sbustring)string에서 substring이 나타나는 이후의 문자열 반환
fn:substringBefore(string, sbustring)string에서 substring이 나타나는 이전의 문자열 반환
fn:toLowerCase(string)string을 모두 소문자로 바꿔 리턴
fn:toUpperCase(string)string을 모두 대문자로 바꿔 리턴
fn:trim(string)string앞뒤의 공백을 모두 제거하여 반환

5.2 FunctionJSTL.jsp

/webapps/el/FunctionJSTL.jsp
<%@ page language="java" isELIgnored="false" contentType="text/html; charset=UTF-8"%>
<%@ taglib prefix="c"   uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fn"  uri="http://java.sun.com/jsp/jstl/functions" %> 

<html>
<body>

    <c:set var="name" value=" Oracle dbms 오라클클럽 "/>
    <p>name: ${fn:replace(name, ' ', '*')}</p>
    <c:set var="name" value="${fn:trim(name)}"/>
    <p>trim name: ${fn:replace(name, ' ', '*')}</p>

    <p>length(name): ${fn:length(name)}</p>
    <p>toUpperCase(name): ${fn:toUpperCase(name)}</p>
    <p>toLowerCase(name): ${fn:toLowerCase(name)}</p>
    <p>substring(name,3,6): ${fn:substring(name,3,6)}</p>
    <p>substringBefore(name,'dbms'): ${fn:substringBefore(name, 'dbms')}</p>
    <p>substringAfter(name,'dbms'): ${fn:substringAfter(name, 'dbms')}</p>
    <p>replace(name, '오라클클럽', 'OracleClub'): ${fn:replace(name, '오라클클럽', 'OracleClub')}</p>
    <p>indexOf(name, 'dbms'): ${fn:indexOf(name,'dbms')}</p>
    <p>contains(name, 'Oracle'): ${fn:contains(name, 'Oracle')}</p>
    <p>containsIgnoreCase(name, 'opracle'): ${fn:containsIgnoreCase(name, 'oracle')}</p>
    <p>startsWith(name, 'Oracle'): ${fn:startsWith(name, 'Oracle')}</p>
    <p>startsWith(name, 'dbms'): ${fn:startsWith(name, 'dbms')}</p>
    <p>endsWith(name, '오라클클럽'): ${fn:endsWith(name, '오라클클럽')}</p>
    <c:remove var="name"/>
    
    <c:set var="dbname" value="ORACLE, DB2, MSSQL, MYSQL, SYSBASE"/>
    <c:set var="db_arr" value="${fn:split(dbname,',')}"/>
    <c:forEach var="db" items="${db_arr}">
        ${db}<br/>
    </c:forEach>
    <p>join : ${fn:join(db_arr, ',')}</p>
    
</body>
</html> 
 
 

6. Locale에 따른 <fmt:formatNumber> 오동작

  • Locale에 따라 <fmt:formatNumber>가 생각하고 다르게 동작하는 경우가 있음
  • 프랑스에서는 수소점을 ','을 써서 아래 코드는 오류가 발생합니다.
  • 10이 10.00으로 바뀐다고 예상했는데 10이 10,00으로 바뀌는 현상등
  • jsp에서 Locale을 명시적으로 설정해 주거나 web.xml 에 Local을 설정해야 한다.
xxx.jsp
<fmt:setLocale value="ko"/> 
 
web.xml
 
 * web.xml에 설정하면 일일이 .jsp에 설정하지 않아도 된다.
<context-param>
     <param-name>javax.servlet.jsp.jstl.fmt.locale</param-name>
     <param-value>ko</param-value>
</context-param>  
 


다른 카테고리의 글 목록

Dev. 웹 카테고리의 포스트를 톺아봅니다