-
[Camel][JSP] JSTL(표준 태그 라이브러리) 1부 - Core Tag(코어 태그)JSP 2020. 3. 21. 21:21
1. JSTL이란?
JSTL은 'JSP Standard Tag Library'의 약자입니다. JSP는 개발자가 직접 태그를 작성할 수 있는 기능을 제공하는데, 이를 커스텀 태그라고 합니다. 커스텀 태그 중에서 많이 사용되는 것을 모아서 JSTL이라는 규약을 만든 것입니다.
JSTL이 제공하는 커스텀 태그는 스크립트 코드를 대체할 수 있으며, JSTL을 사용함으로써 코드를 보다 간결하고 이해하기 쉽게 작성할 수 있습니다.
JSP 페이지를 작성하다보면 스크립트 코드와 HTML 코드가 섞여서 사용됩니다. 그로인해 JSP 코드는 다소 복잡하게 표현될 수 있습니다. 즉, 코드 작성에 있어서 실수를 하기 쉽다는 것입니다. 이러한 단점을 보완하기 위해 사용되는 것이 JSTL(커스텀 태그)입니다.
JSTL은 JSP페이지에서 자주 사용되는 논리 판단, 반복문, 데이터베이스 등의 처리를 위해 사용됩니다. JSTL이 제공하는 태그의 종류는 크게 5가지로 구분할 수 있으며, 그 내용은 아래의 표로 확인하겠습니다.
라이브러리 하위 기능 접두어 관련 URI 코어 변수 지원
흐름 제어
URL 처리
c http://java.sun.com/jsp/jstl/core XML XML 코어
흐름 제어
XML 변환
x http://java.sun.com/jsp/jstl/xml 국제화 지역
메시지 형식
숫자 및 날짜 형식
fmt http://java.sun.com/jsp/jstl/fmt 데이터베이스 SQL sql http://java.sun.com/jsp/jstl/sql 함수 Collection 처리
String 처리
fn http://java.sun.com/jsp/jstl/functions 2. JSTL 라이브러리 사용 준비
JSTL을 사용하기 위해서는 JSTL 라이브러리는 다운 받아야합니다. JSTL을 필요로 하는 웹 어플리케이션을 실행하기 위해서는 JSTL을 구현한 jar 파일을 WEB-INF/lib 디렉터리에 복사해 주어야합니다. JSTL을 구현한 jar 파일은 여기에서 받으시면됩니다.
다운 받은 압축파일을 풀어보면 lib 폴더 내에 standard, jstl 총 2개의 jar 파일이 있는 것을 확인할 수 있습니다. 이 둘을 복사한 뒤 WEB-INF/lib 디렉터리에 넣어주시면 됩니다.
3. JSTL의 코어(Core) 태그
코어 태그 라이브러리는 논리적인 처리를 위해 사용되는 스크립트 코드를 대체하기 위한 태그를 제공합니다. 코어 태그 라이브러리의 목록은 아래와 같습니다.
기능 태그 설명 변수지원 set JSP 에서 사용될 변수를 설정 remove 설정한 변수를 제거 흐름제어 if 조건에 따라 내부 코드를 수행 choose 다중 조건을 처리 forEach Collection이나 Map의 각 항목을 처리 forTokens 구분자로 분리된 각각의 토큰을 처리 URL 처리 import URL을 사용해 다른 자원의 결과를 삽입 redirect 지정한 경로로 redirect url URL 재작성 기타 태그 catch 예외 처리에 사용 out JspWriter에 내용을 알맞게 처리한 후 출력 위의 코어 태그 라이브러리를 사용하기 위해서는 JSP 페이지에 taglib 디렉티브를 추가해 주어야합니다. 추가 방법은 아래와 같습니다.
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
prefix 속성에 넣어주는 값은 코어 태그 라이브러리를 호출할 때 사용할 접두어를 의미하는데, 이 접두어를 c로 지정한 이유는 일반적으로 코어 태그 라이브러리의 접두어로 c를 사용하기 때문입니다. 즉, 반드시 c가 아니어도 된다는 것입니다.
4. 코어 태그 라이브러리 - 변수 지원 태그
변수 지원 태그는 JSTL이 지원하는 태그에서 사용할 수 있는 변수를 설정하기 위해서 사용됩니다. 변수 지원 태그의 종류로는 set과 remove 태그가 있습니다.
4-1. <c:set> 태그
<c:set> 태그는 표현언어 변수의 값이나 표현언어 변수의 프로퍼티 값을 지정할 때 사용됩니다. 이러한 <c:set>태그는 JSTL의 태그에서 사용될 변수의 값을 처리할 때 사용됩니다.
4-1-1. 표현언어 생성을 위한 <c:set> 사용 방법
<c:set var="이름" value="값" [scope="영역"]/> <c:set var="이름" [scope="영역"]>값</c:set>
<c:set var="name" value="Camel"/> <c:set var="name" value="<%= m.getFirstName() %>" scope="request"/> <c:set var="name" value="${m.lastName} ${m.firstName}"/> <c:set var="name">Camel</c:set> <c:set var="name"><%= m.getFirstName() %></c:set> <c:set var="name">${m.firstName} ${m.lastName}</c:set>
var 속성에 지정되는 이름은 표현언어 변수의 이름입니다. value 속성에 지정되는 값은 표현식, 표현언어, 정적 텍스트를 사용해 지정할 수 있으며, scope 속성은 변수를 저장할 영역을 지정합니다. scope 속성의 디폴트 값은 page 영역입니다.
4-1-2. 객체 프로퍼티 값 설정을 위한 <c:set> 사용 방법
<c:set> 태그의 또 다른 사용방법은 객체 프로퍼티 값 설정을 통한 방법이 있습니다. 프로퍼티 값을 설정할 때 사용되는 속성은 아래와 같습니다.
- target - 프로퍼티 값을 설정할 대상 객체. 표현식이나 표현언어 변수를 지정할 수 있다. 이때 대상 객체는 JavaBrean 객체이거나 Map 객체여야 한다.
- property - 설정할 프로퍼티의 이름. target이 JavaBean 객체인 경우 프로퍼티의 이름에 해당하는 set 메소드를 제공해 줘야한다. Map 객체인 경우 Map.put(이름, 값)을 사용해서 값을 추가한다.
- value - 설정할 프로퍼티 값.
객체 프로퍼티 값 설정을 위한<c:set> 사용 방법은 아래와 같습니다.
<% Animal animal = new Animal(); %> <c:set target="<%=animal%>" property="name" value="Camel" /> <%= animal.getName() %> <c:set var="a" value="<%=animal%>" /> <c:set target="${a}" property="name" value="Pig" /> ${a.name} <% Map<String, String> prpt = new HashMap<String, String>(); %> <c:set target="<%=prpt%>" property="host" value="localhost" /> <%= prpt.get("host") %>
4-1-3. #{expression} 형식의 Deferred Expression을 값으로 설정한 <c:set> 사용 방법
<c:set> 태그의 또 다른 사용방법으로는 #{expression} 형식의 Deferred Expression을 값으로 설정하는 방법입니다. Deferred Expression을 사용하는 경우에는 scope 속성을 사용하지 않습니다.
<c:set var="이름" value="#{expression}"/>
4-2. <c:remove> 태그
remove 태그는 set 태그로 지정한 변수를 삭제할 때 사용합니다. 그 사용방법은 아래와 같습니다.
<c:remove var="이름" [scope="영역"]/>
remove 태그를 사용할 때 한가지 주의해야할 점은 삭제할 변수의 scope를 지정해주지 않으면 동일한 이름으로 저장된 모든 영역의 변수를 모두 삭제한다는 것입니다. 만약 서로 다른 영역에 동일한 이름을 갖는 변수를 설정했는데 지정한 영역에 속한 변수만 제거하고 싶다면 scope 속성으로 제거할 영역을 지정해 주어야한다는 것입니다.
5. 코어 태그 라이브러리 - 흐름 제어 태그
JSP 코드에서 스크립트 코드를 사용할 경우 if-else 구문이나 for 구문이 조금이라도 사용되면 코드가 다소 복잡해질 가능성이 높습니다. 이러한 점은 개발 과정에 있어서 실수를 유발하기 쉽기 때문에, 우리는 JSTL의 태그를 사용해 흐름 제어를 처리함으로써 간결한 코드를 구성할 수 있습니다.
JSTL에서 제공하는 흐름 제어 태그는 if, choose, forEach, forTokens 총 네 가지가 있습니다.
5-1. <c:if> 태그
<c:if>태그는 Java에서의 if구문과 유사한 기능을 제공합니다 단순한 if 문을 대체함으로써 코드를 간결하고 쉽게 작성할 수 있습니다. 사용 방법은 아래와 같습니다.
<c:if test="조건"> . . . </c:if> <c:if test="${param.name == 'Camel'}"> parameter name is ${param.name}
test 속성에는 true와 false를 반환하는 조건이 지정됩니다. 이 조건의 결과값이 true이면 <c:if> 내부의 코드를 수행하고, 결과값이 false이면 <c:if>내부의 코드를 수행하지 않습니다. test 속성에는 표현식이나 표현언어 또는 정적 문자열을 값으로 지정할 수 있습니다. 하지만 Deferred Expression을 값으로 지정할 수는 없습니다.
5-2. <c:choose> 태그
<c:choose> 태그는 Java의 switch 문과 if-else 문의 특징을 모두 가지고 있는 태그입니다. 다수의 조건문을 하나의 블록에서 수행하고자 할 때 사용되며, 그 사용방법은 아래와 같습니다.
<c:choose> <c:when test="${animal.name == 'Camel'}"> . . . </c:when> <c:when test="${animal.name == 'Pig'}"> . . . </c:when> <c:when test="${animal.name == 'Lion'}"> . . . </c:when> <c:otherwise . . . </c:otherwise> </c:choose>
<c:when> 태그와 <c:otherwise>태그는 if-else 구문과 유사한 기능을 합니다.
<c:when> 태그의 test 속성의 결과 값이 true일 경우 <c:when>태그 내부의 코드를 수행하며, 한 번 <c:when>태그가 수행되면 이후의 <c:when>태그는 수행되지 않습니다.
<c:otherwise> 태그는 모든 <c:when>태그 test 속성의 결과 값이 false일 경우 수행됩니다. <c:otherwise> 태그는 무조건 사용해야하는 것은 아닙니다.
5-3. <c:forEach> 태그
<c:forEach> 태그는 배열, Collection, Map에 저장되어 있는 값들을 순차적으로 처리할 때 사용하는 태그입니다. Java에서의 for 구문과 do-while 구문을 대신해서 사용할 수 있습니다. <c:forEach> 태그의 사용 방법은 아래와 같습니다.
<c:forEach var="변수명" items="아이템"> . . . </c:forEach>
items 속성으로 지정될 수 있는 것은 Map, 배열, Collection이 있으며, 배열의 경우에는 객체의 배열뿐만 아니라 기본 자료형의 배열에 대해서도 적절하게 처리가 가능합니다. 단, 기본 자료형을 사용할 때에는 Wrapper 클래스의 사용이 필요시 됩니다.
<c:forEach> 태그의 경우는 Java의 for 구문과 유사한 기능을 수행할 수 있습니다. begin과 end 속성을 사용함으로써 범위를 지정해서 <c:forEach> 태그를 사용할 수 있습니다. 사용방법은 아래와 같습니다.
<c:forEach var="i" begin="1" end="10" step="2"> ${i} 출력 </c:forEach>
step 속성을 사용하면 개발자는 <c:forEach> 태그가 반복될 때의 증가분을 설정할 수 있습니다. 위 처럼 step 속성의 값이 2로 지정되어 있다면, 변수 i는 1,3,5,7,9 의 값을 순서로 가지게 되는 것입니다. step 속성은 필수적으로 사용해야 되는 것은 아니며, step 속성을 사용하지 않을 때 디폴트 값은 1입니다.
이처럼 범위를 지정할 수 있는 특징을 items 속성과 함께 활용하면 참조할 변수의 개수를 제한할 수도 있습니다.
<c:forEach var="i" items="${arr}" begin="4" end="10" step="2"> ${i} 출력 </c:forEach>
5-4. <c:forTokens> 태그
<c:forTokens> 태그는 java.util.StringTokenizer 클래스와 같은 기능을 제공하는 태그입니다. 사용 방법은 아래와 같습니다.
<c:forTokens var="token" items="문자열"delims="구분자"> ${token} 출력 </c:forTokens>
<c:forTokens> 태그는 items 속성에 지정한 문자열을 구분자를 사용해서 나누게 되고, 나누어진 각 문자열을 var 속성에서 지정한 변수에 저장합니다.
<c:forTokens> 태그의 items 속성값이 문자열이라는 것을 제외하면 <c:forTokens>태그의 속성은 <c:forEach> 태그와 동일합니다.
6. 코어 태그 라이브러리 - URL 처리 태그
URL 처리 태그는 내부 및 외부 자원의 삽입을 위한 <c:import> 태그, URL 생성을 위한 <c:url> 태그, 리다이렉트 처리를 위한 <c:redirect> 태그 총 3가지가 있습니다. 이 태그들을 사용함으로써 우리는 스크립트릿이나 표현식을 사용하지 않고 간결한 코드로 URL 관련 기능을 수행할 수 있게됩니다.
6-1. <c:import>태그
<c:import> 태그는 특정 URL의 결과를 읽어와 현재 위치에 삽입하거나 표현언어 변수에 저장할 때 사용합니다. <c:import>태그는 동일한 웹 어플리케이션 내에 위치한 자원을 포함하게 해주는 <jsp:include>의 기능뿐만아니라 외부의 다른 자원을 읽어와 포함시키는 것도 가능하게 합니다. <c:import> 태그의 사용방법은 아래와 같습니다.
<c:import url="URL" [var="변수명"] [scope="영역"] [charEncoding="Character Set"]> </c:import>
var 속성을 사용하면 url 속성에 지정된 URL로부터 읽어온 데이터를 var 속성에 지정한 표현언어의 변수에 저장합니다. 그리고 scope 속성에 표현언어 변수를 생성할 영역을 입력해 줍니다.
만약 var 속성을 통해 저장할 변수를 지정하지 않는다면 현재 위치에 URL로부터 읽어온 결과를 출력합니다.
url 속성에는 절대 URL과 상대 URL의 두 가지 종류의 값을 입력할 수 있습니다.
절대 URL을 사용하는 경우 <c:import> 태그는 java.net.URL과 java.net.URLConnection을 이용해서 데이터를 읽어오게 됩니다. 이때 charEncoding 속성의 값을 지정해줬다면, 데이터를 읽어올 때 charEncoding 속성에 지정된 Character Set으로 인코딩을 진행합니다. 반대로 charEncoding 속성의 값을 지정하지 않았다면, URLConnection.getContentType 메소드가 반환한 값이 응답 캐릭터 인토딩을 포함하고 있는 경우에는 해당 캐릭터 인코딩을 이용해서 응답 텍스트를 읽어오며, 응답 캐릭터 인토킹을 포함하고 있지 않다면 Default 값인 ISO-8859-1을 사용합니다.
상대 URL을 사용하는 경우 <c:import> 태그는 <jsp:include> 태그와 동일한 방식으로 동작하게됩니다. 이는 동일한 웹 어플리케이션에 속한 자원의 실행 결과를 읽어오게 된다는 것입니다. 하지만 여기서 <c:import>태그와 <jsp:include> 태그의 차이점이 있다면, <jsp:include> 태그의 경우에는 현재 위치에 무조건 결과를 출력하지만 <c:import>태그의 경우에는 표현언어 변수에 보관함으로써 필요에 따라 적절한 처리가 가능하다는 점입니다.
요청 파라미터를 추가하는 방법은 URL에 직접 입력하는 방식이 있고, <c:param> 태그를 사용하는 방법이 있습니다.
URL에 직접 입력할 때는 GET 방식으로 파라미터를 전송할 때 사용되는 URL을 사용합니다.
<c:param> 태그를 사용하는 방법은 <c:import> 태그의 내부에 <c:param> 태그를 입력합니다. <c:param>태그를 사용함으로써 얻을 수 있는 이점은 파라미터 이름과 값에 대한 URL 인코딩 처리를 직접하지 않아도 된다는 것입니다.
<c:import> 태그와 <c:param> 태그를 사용한 예제 코드는 아래와 같습니다.
<%@ page contentType = "text/html; charset=utf-8" %> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <% request.setCharacterEncoding("utf-8"); %> <c:choose> <c:when test="${param.type == 'naver'}"> <c:import url="http://search.naver.com/"> <c:param name="c" value="camel" /> <c:param name="p" value="pig" /> </c:import> </c:when> <c:when test="${param.type == 'youtube'}"> <c:import url="http://www.youtube.com/results"> <c:param name="search_query" value="Camel JSP" /> </c:import> </c:when> <c:otherwise> <c:import url="use_import_tag_help.jsp"> <c:param name="message" value="선택해주세요" /> </c:import> </c:otherwise> </c:choose>
6-2. <c:url>태그
<c:url> 태그는 URL을 생성해주는 기능을 제공합니다. 사용방법은 아래와 같습니다.
<c:url value="URL" [var="변수명"] [scope="영역"] > <c:param name="이름" value="값" /> </c:url>
<c:url> 태그는 <c:import>태그와 마찬가지로 <c:param> 태그를 사용해서 파라미터를 URL에 추가할 수 있습니다. var 속성을 지정하지 않은 경우에는 현재 위치에 생성한 URL을 출력하며, var 속성을 지정한 경우에는 해당 변수에 생성한 URL을 저장합니다.
value 속성에 올수 있는 URL의 타입은 절대 URL과 상대 URL이 있습니다. 그리고 상대 URL을 입력하는 경우 '/'로 시작하여 웹 어필리케이션 내에서의 절대경로를 지정할 수 있고, '/'로 시작하지 않는다면 현재 JSP에 대한 상태 경로를 나타냅니다.
<c:url value="/camel/name.jsp" />
웹 어플리케이션 내에서의 절대경로를 사용할 경우 실제로 생성되는 URL은 컨텍스트 경로를 포함합니다. 컨텍스트 경로가 /animal 일때 위의 태그가 생성하는 URL은 /animal/camel/name.jsp가 됩니다.
<c:param> 태그를 사용해 파라미터를 설정하는 경우 파라미터 이름과 값의 URL인코딩처리는 <c:import> 태그와 마찬가지로 contentType에 명시된 Character Set을 사용해서 처리합니다.
<c:url> 태그와 <c:param> 태그를 사용한 예제 코드는 아래와 같습니다.
<%@ page contentType="text/html; charset=utf-8" session="false" %> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <html> <body> <c:url value="http://search.naver.com/" var="searchUrl"> <c:param name="c" value="camel" /> <c:param name="p" value="pig" /> </c:url> <ul> <li>${searchUrl}</li> <li><c:url value="/use_if_tag.jsp" /></li> <li><c:url value="./use_if_tag.jsp" /></li> </ul> </body> </html>
6-3. <c:redirect>태그
<c:redirect> 태그는 지정한 페이지로 리다이렉트를 시켜주는 기능을 제공합니다. 사용방법은 아래와 같습니다.
<c:redirect url="URL" [context="Context 경로"]> <c:param name="name" value="value"/> </c:redirect>
url 속성에 지정되는 값이 '/'로 시작될 경우 리다이렉트되는 URL에는 컨텍스트 경로가 추가됩니다. 만약 다른 컨텍스트 경로에 포함된 URL로 리다이렉트를 하고 싶다면 context 속성에 다른 컨텍스트의 경로를 지정해주면 됩니다.
한 가지 특이점이 있다면, <c:redirect> 태그가 실행되면 이후의 코드는 실행되지 않는다는 점입니다.
6. 코어 태그 라이브러리 - 기타 코어 태그
기타 코어 태그로는 <c:out> 태그와 <c:catch> 태그가 있습니다.
6-1. <c:out> 태그
<c:out> 태그는 JspWriter에 데이터를 출력할 때 사용하는 태그입니다. 사용방법은 아래의 두 가지 방법이 있습니다.
<c:out value="value" [escapeXml="true or false"] [default="defaultValue"] /> <c:out value="value" [escapeXml="true or false"]> default defaultValue </.c:out>
value 속성은 JspWriter에 출력할 값을 나타내며, 일반적으로 value 속성의 값은 String과 같은 문자열입니다. 하지만 만약 value의 값이 Reader의 한 종류라면 <c:out> 태그는 Reader로부터 데이터를 읽어와 JspWriter에 값을 출력합니다.
escapeXml 속성은 true일 경우 특정 문자를 변경합니다. 생략할 경우 Defalut 값은 true입니다. escapeXml 속성의 값이 true일 경우 변경되는 문자는 아래와 같습니다.
변경 전 문자 변경 후 < < > > & & ' ' " " default 속성은 value 속성에서 지정한 값이 존재하지 않을 경우 사용될 값을 지정합니다.
<c:out> 태그와 <c:param> 태그를 사용한 예제 코드는 아래와 같습니다.
<%@ page contentType = "text/html; charset=utf-8" %> <%@ page import = "java.io.IOException, java.io.FileReader" %> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <html> <head><title>c:out Tag</title></head> <body> <% FileReader reader = null; try { String path = request.getParameter("path"); reader = new FileReader(getServletContext().getRealPath(path)); %> <pre> Source Code = <%= path %> <c:out value="<%= reader %>" escapeXml="true" /> </pre> <% } catch(IOException ex) { %> ERROR: <%= ex.getMessage() %> <% } finally { if (reader != null) try { reader.close(); } catch(IOException ex) {} } %> </body> </html>
6-2. <c:catch> 태그
<c:catch> 태그는 발생된 예외를 표현언어 변수에 저장할 때 사용합니다. 사용방법은 아래와 같습니다.
<c:catch var="예외종류"> . . . </c:catch> . . . ${예외종류}
<c:catch> 태그 내에서 예외가 발생하게되면, 예외 객체는 var 속성의 값으로 지정한 '예외종류'에 할당되게 됩니다. 그러므로 <c:catch> 태그 외부에서 '예외종류' 변수를 사용해서 예외 처리를 해주면 됩니다.
<c:catch> 태그를 사용한 예제코드는 아래와 같습니다. 아래 예제는 name 파라미터를 전달하지 않을 시 예외를 처리하는 코드입니다.
<%@ page contentType = "text/html; charset=utf-8" %> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <html> <head><title>catch Tag</title></head> <body> <c:catch var="ex"> name Parameter Value = <%= request.getParameter("name") %><br> <% if (request.getParameter("name").equals("test")) { %> ${param.name}is test. <% } %> </c:catch> <p> <c:if test="${ex != null}"> Exception!:<br> ${ex} </c:if> </body> </html>
이상으로 코어 태그에 관한 내용을 마무리하겠습니다. 다음 포스팅에서는 JSTL의 국제화 태그에 관한 포스팅을 하겠습니다.
'JSP' 카테고리의 다른 글
[Camel][JSP] JSTL(표준 태그 라이브러리) 2부 - fmt Tag (국제화 태그) (0) 2020.03.22 [Camel][JSP] 표현 언어 ( Expression Language) (0) 2020.03.20 [Camel][JSP] Connection Pool (커넥션 풀) with DBCP (0) 2020.03.16 [Camel][JSP] JDBC 프로그래밍 2부 in JSP (0) 2020.03.15 [Camel][JSP] JDBC 프로그래밍 1부 in JSP (0) 2020.03.14