JSTL(JavaServer Pages Standard Tag Library)는 JSP에서 자주 쓰이는 기능을 표준 태그로 묶어둔 라이브러리이다.
원래 JSP는 <% ... %>
같은 스크립틀릿(Java 코드)을 직접 HTML에 넣어서 쓰곤 했는데 이 방식은 코드가 지저분하고 유지보수가 어려웠다
그래서 JSTL은 JSP화면에서 자바 코드를 직접 쓰지 않고 태그 문법(XML/HTML 비슷한 형태)으로 표현할 수 있게 해주는 표준 라이브러리이다.
jar
파일을 다운로드한다jar
파일을 추가한다.프로젝트 루트
└─ src
└─ web
└─ WEB-INF
└─ lib
└─ jstl-1.2.jar ← 여기에 복사
- File → Project Structure (Ctrl+Alt+Shift+S
- Modules → Dependencies 탭 이동
- + 클릭 → JARs or directories... 선택
- WEB-INF/lib/jstl-1.2.jar 선택 → 추가
💡 - 원래 Maven 프로젝트에서는 pom.xml에 dependency 등록하는 게 표준이다.
WEB-INF/lib
에 넣으면 Maven이 관리하지 않아서pom.xml
에 JSTL의 의존성을 추가한다...
...
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
IntelliJ
에서 pom.xml
을 저장하고 Maven
탭 → Reload All Maven Projects
버튼을 클릭 (이 과정을 통해 jstl-1.2.jar
가 자동으로 받아지고 External Libraries
에 추가된다)아래와 같이 JSP
파일 최상단에 한 번 선언하면 해당 JSP 안에서 JSTL 태그를 사용할 수 있다.
<%@ 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" %>
스크립틀릿으로 표현한 반복문 템플릿
<%
List<Notice> list = (List<Notice>)request.getAttribute("list");
for (Notice n : list) {
pageContext.setAttribute("n", n);
%>
<tr>
<td>${n.id}</td>
<td class="title indent text-align-left"><a href="detail?id=${n.id}">${n.title}</a></td>
<td>${n.writerId}</td>
<td>${n.regDate}</td>
<td>${n.hit}</td>
</tr>
<% } %>
JSTL 반복문 템플릿
<c:forEach var="n" items="${list}">
<tr>
<td>${n.id}</td>
<td class="title indent text-align-left"><a href="detail?id=${n.id}">${n.title}</a></td>
<td>${n.writerId}</td>
<td>${n.regDate}</td>
<td>${n.hit}</td>
</tr>
</c:forEach>
Java코드 없이 가독성 좋은 형태로 변환되었다.
JSTL은 크게 다섯 가지 기능 그룹으로 나뉜다.
변수 선언/출력, 조건문/반복문
태그 | 기능 | 보강 설명 / 예시 |
---|---|---|
<c:out> | 출력 | ${변수} 를 출력할 때 사용. HTML 이스케이프 처리 가능 (escapeXml="true" 기본값).👉 <c:out value="${msg}" default="값 없음" /> |
<c:set> | 사용할 변수를 설정 | JSP 스코프(page, request, session, application)에 값 저장 가능.👉 <c:set var="name" value="홍길동" scope="session"/> |
<c:remove> | 설정한 변수 제거 | 지정한 스코프에서 변수를 삭제.👉 <c:remove var="name" scope="session"/> |
<c:catch> | 예외 처리 | JSP 태그 실행 중 발생하는 예외를 잡아 변수에 저장.👉 <c:catch var="error"><% int a = 10/0; %></c:catch>에러: ${error} |
<c:if> | 조건문 처리 | 단일 조건만 평가. test 속성은 반드시 Boolean 값이어야 함.👉 <c:if test="${age >= 20}">성인입니다</c:if> |
<c:choose> | 다중 조건문 처리 | switch-case 와 유사. <c:when> 과 <c:otherwise> 와 함께 사용. |
<c:when> | <c:choose> 의 서브태그 | 조건이 true 이면 실행. 여러 개 가능. 위에서부터 순차적으로 평가됨. |
<c:otherwise> | <c:choose> 의 서브태그 | 모든 <c:when> 이 거짓일 때 실행되는 블록. |
<c:import> | 다른 리소스의 결과 삽입 | JSP/Servlet/외부 URL의 결과를 현재 JSP에 포함.👉 <c:import url="/header.jsp" /> 또는 <c:import url="http://example.com" /> |
<c:forEach> | 반복문 처리 | 배열, List, Map 등 컬렉션을 순회. 인덱스(varStatus ) 제공.👉 <c:forEach var="item" items="${list}" varStatus="s">${s.index}: ${item}<br/></c:forEach> |
<c:forTokens> | 문자열 토큰화 반복 | items 문자열을 delims 구분자로 나눠서 반복.👉 <c:forTokens items="A,B,C" delims="," var="x">${x}</c:forTokens> |
<c:param> | URL 파라미터 설정 | <c:import> 또는 <c:url> 내부에서 사용하여 query string 추가.👉 <c:url var="go" value="search.jsp"><c:param name="q" value="JSTL"/></c:url> |
<c:redirect> | 페이지 리다이렉트 | 클라이언트를 지정한 URL로 이동시킴. 주로 로그인 후 페이지 이동 등에서 활용.👉 <c:redirect url="/login.jsp" /> |
<c:url> | URL 재작성 | 세션 트래킹을 위해 JSESSIONID를 자동으로 추가해주기도 함. 보통 링크 생성에 사용.👉 <a href="<c:url value='/mypage'/>">마이페이지</a> |
숫자, 날짜, 통화 포맷
태그 | 기능 | 예시 |
---|---|---|
<fmt:formatNumber> | 숫자/통화/퍼센트 형식 변환 | type="number" , currency , percent 옵션 가능. 소수점 자리수도 지정 가능. 👉 <fmt:formatNumber value="12345.678" type="number" maxFractionDigits="2"/> → 12,345.68 |
<fmt:parseNumber> | 문자열 → 숫자 변환 | 문자열을 Number 객체(Integer/Double 등)로 변환. 👉 <fmt:parseNumber var="num" type="number" value="1234.56"/> (${num} → 1234.56) |
<fmt:formatDate> | 날짜/시간 포맷팅 | type="date" , time , both 옵션 가능. pattern 으로 커스텀 포맷도 가능. 👉 <fmt:formatDate value="${now}" pattern="yyyy-MM-dd HH:mm"/> |
<fmt:parseDate> | 문자열 → 날짜 변환 | 문자열을 java.util.Date 객체로 변환. 👉 <fmt:parseDate value="2025-08-26" pattern="yyyy-MM-dd" var="d"/> |
<fmt:setLocale> | 로케일(locale) 설정 | 날짜, 숫자 포맷에 적용할 지역/언어 지정. 👉 <fmt:setLocale value="en_US"/> |
<fmt:setTimeZone> | 타임존 설정 | 날짜/시간 태그(formatDate ) 등에 적용할 타임존 지정. 👉 <fmt:setTimeZone value="GMT+9"/> |
<fmt:timeZone> | 특정 블록에 타임존 적용 | 블록 안에서만 지정한 타임존을 적용. 👉 <fmt:timeZone value="GMT"><fmt:formatDate value="${now}" type="both"/></fmt:timeZone> |
<fmt:bundle> | 리소스 번들 지정 | 다국어 리소스(properties 파일) 사용 시 묶음 지정. 👉 <fmt:bundle basename="messages"> ... </fmt:bundle> |
<fmt:message> | 리소스 번들 메시지 출력 | key 에 해당하는 다국어 문자열 출력. <fmt:param> 과 함께 사용 가능. 👉 <fmt:message key="welcome"><fmt:param value="홍길동"/></fmt:message> |
<fmt:param> | 메시지 치환 파라미터 | <fmt:message> 안에서 동적 값 삽입. 👉 messages.properties → welcome=안녕하세요 {0}님 JSP → <fmt:message key="welcome"><fmt:param value="홍길동"/></fmt:message> |
DB 쿼리 실행 (실무에서는 보안 문제 때문에 거의 안 씀) PreparedStatement 미지원 → SQL Injection 위험
태그 | 기능 | 예시 |
---|---|---|
<sql:setDataSource> | DB 연결 설정 | DB 드라이버, URL, 사용자, 비밀번호를 지정. 이후 SQL 태그들이 이 DataSource를 사용.👉 <sql:setDataSource var="db" driver="org.postgresql.Driver" url="jdbc:postgresql://localhost:5432/test" user="postgres" password="1234"/> |
<sql:query> | SELECT 실행 | DB 조회. 결과는 Result 객체로 저장됨.👉 <sql:query var="rs" dataSource="${db}">SELECT * FROM notice</sql:query> |
<sql:update> | INSERT / UPDATE / DELETE 실행 | 변경 쿼리 실행. 반영된 row 수 반환.👉 <sql:update dataSource="${db}">INSERT INTO notice(title) VALUES('테스트')</sql:update> |
<sql:param> | SQL 파라미터 바인딩 | <sql:query> 또는 <sql:update> 내부에서 ? 자리에 값 바인딩.👉 <sql:query var="rs" dataSource="${db}">SELECT * FROM notice WHERE id=?<sql:param value="1"/></sql:query> |
<sql:dateParam> | SQL 파라미터 중 날짜 타입 지정 | DB에 날짜 값 바인딩할 때 사용. |
XML 데이터를 다루기 위한 태그 DOM/SAX 파싱 없이 JSP에서 XML 처리 가능
태그 | 기능 | 보강 설명 / 예시 |
---|---|---|
<x:parse> | XML 문서 파싱 | XML 문자열이나 외부 파일을 XML DOM 객체로 변환.👉 <x:parse var="doc" xml="${xmlString}"/> |
<x:out> | XPath 결과 출력 | XPath로 찾은 노드/값 출력.👉 <x:out select="$doc/root/name"/> |
<x:set> | XPath 결과 변수에 저장 | XML 노드/값을 변수로 설정.👉 <x:set var="username" select="$doc/root/user/name"/> |
<x:if> | XPath 조건 검사 | XPath 조건이 true일 때 실행.👉 <x:if select="$doc/root/user[@role='admin']">관리자</x:if> |
<x:forEach> | XPath 결과 반복 | XPath로 찾은 여러 노드를 순회.👉 <x:forEach select="$doc/root/item" var="i"><x:out select="$i/name"/></x:forEach> |
JSTL 함수 라이브러리. 주로 문자열 처리와 컬렉션 처리에 사용.
반드시 선언 필요
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
함수 | 기능 | 예시 |
---|---|---|
fn:length(obj) | 길이 반환 | 문자열/컬렉션/배열의 길이. 👉 ${fn:length("Hello")} → 5 |
fn:contains(str, substr) | 부분 문자열 포함 여부 | 👉 ${fn:contains("abcdef","cd")} → true |
fn:containsIgnoreCase(str, substr) | 대소문자 무시 포함 여부 | 👉 ${fn:containsIgnoreCase("Hello","HEL")} → true |
fn:startsWith(str, prefix) | 접두사 검사 | 👉 ${fn:startsWith("Hello","He")} → true |
fn:endsWith(str, suffix) | 접미사 검사 | 👉 ${fn:endsWith("Hello","lo")} → true |
fn:indexOf(str, substr) | 부분 문자열 위치 | 👉 ${fn:indexOf("Hello","l")} → 2 |
fn:substring(str, begin, end) | 부분 문자열 추출 | 👉 ${fn:substring("Hello",1,3)} → el |
fn:substringAfter(str, substr) | 지정 문자열 이후 반환 | 👉 ${fn:substringAfter("abc-def","-")} → def |
fn:substringBefore(str, substr) | 지정 문자열 이전 반환 | 👉 ${fn:substringBefore("abc-def","-")} → abc |
fn:replace(str, before, after) | 문자열 치환 | 👉 ${fn:replace("a-b-c","-","/")} → a/b/c |
fn:trim(str) | 앞뒤 공백 제거 | 👉 ${fn:trim(" Hello ")} → Hello |
fn:toLowerCase(str) | 소문자로 변환 | 👉 ${fn:toLowerCase("HELLO")} → hello |
fn:toUpperCase(str) | 대문자로 변환 | 👉 ${fn:toUpperCase("hello")} → HELLO |
fn:split(str, delimiter) | 문자열 분할 (배열 반환) | 👉 ${fn:split("a,b,c",",")[1]} → b |
fn:join(array, delimiter) | 배열을 문자열로 합치기 | 👉 ${fn:join(fn:split("a,b,c",","), "-")} → a-b-c |
fn:escapeXml(str) | XML/HTML 이스케이프 | 👉 ${fn:escapeXml("<h1>Hi</h1>")} → <h1>Hi</h1> |