[JSP] JSTL-Core
기능: 변수지원, 흐름제어, URL처리
directive: <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
기능별 구분
- EL 지원 기능: catch, out, remove, set
- 흐름 제어 기능: choose, forEach, forTokens, if
- URL 관리기능: import, param, redirect, param, url
catch
body 위치에서 실행되는 코드의 예외를 잡아내는 역할을 담당한다.
<c:catch var="name">
body content
</c:catch>
<%@ page contentType = "text/html; charset=utf-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<h3>코어</h3>
<h4><c:out></h4>
<pre>
${1+2} <c:out value="${1+2}"/>
${1>3} <c:out value="${1>3}"/>
${1 gt 3} <c:out value="${1 gt 3}"/>
\$표시 <c:out value="${'${'}test}"/>
escapeXml 속성 기본 값은 false
false: <c:out value="<b>bold</b> <,>,&,',\" " escapeXml="false"/>
true: <c:out value="<b>bold</b> <,>,&,',\" " escapeXml="true"/>
" 큰따옴표 사용주의 ' 작은따옴표로 대치
<c:out value='<font color="blue">파랑</font>'/>
<c:out value='<font color="blue">파랑</font>' escapeXml="false"/>
<hr><h4><c:set></h4>
set session scope var "name": <c:set var="name" value="하늘" scope="session"/>
c:out name: <c:out value="${name}"/>
expression name: <%=session.getAttribute("name")%>
set page scope var "name": <c:set var="name">
hello
</c:set>
c:out name: <c:out value="${pageScope.name}"/>
c:out sessionScope.name: <c:out value="${sessionScope.name}"/>
expression name: <%=session.getAttribute("name")%>
<hr><h4><c:remove></h4>
remove session scope var "name": <c:remove var="name" scope="session"/>
expression name: <%=session.getAttribute("name")%>
c:out sessionScope.name: <c:out value="${sessionScope.name}"/>
<hr><h4><c:catch></h4>
<c:catch var="errmsg">
line1
<%=1/0%>
line2
</c:catch>
<c:out value="${errmsg}"/>
</pre>
choose-when-otherwise
<c:choose/>
태그는 java의 switch
문과 같지만, 조건에 문자열 비교도 가능하고 쓰임의 범위가 넓다. 또한 <c:if/>
태그에 else가 없기 때문에 이의 대체 기능도 수행한다.
<c:choose>
body content
(하나 이상의 <when>과 하나 이하의 <otherwise> 서브태그)
<c:when test="조건_1">
body content
</c:when>
<c:when test="조건_2">
body content
</c:when>
<c:otherwise>
conditional block
</c:otherwise>
</c:choose>
<%@ page contentType = "text/html; charset=utf-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<h3>조건</h3>
파라미터 없음:<c:out value="${empty param.name}" />
<h4><c:if test=""></h4>
<c:if test="${empty param.name}">
<form>
이름을 적어주세요.<br/>
<input type="text" name="name"/> <input type="submit" value="확인"/>
</form>
</c:if>
<c:if test="${!empty param.name}">
안녕하세요. <c:out value="${param.name}"/>님.
</c:if>
<h4><c:choose> <c:when test=""> <c:otherwise></h4>
<c:choose>
<c:when test="${empty param.name}">
<form>
이름을 적어주세요.<br/>
<input type="text" name="name"/> <input type="submit" value="확인"/>
</form>
</c:when>
<c:when test="${param.name=='admin'}">
안녕하세요. 관리자님.
</c:when>
<c:otherwise>
안녕하세요. <c:out value="${param.name}"/>님.
</c:otherwise>
</c:choose>
<c:choose>
<c:when test="${param.num1%12==0}">
${param.num1 }은 3과 4의 배수<br/>
</c:when>
<c:when test="${param.num1%3==0}">
${param.num1 }은 3의 배수<br/>
</c:when>
<c:when test="${param.num1%4==0}">
${param.num1 }은 4의 배수<br/>
</c:when>
<c:otherwise>
${param.num1 }은 3또는 4의 배수가 아님<br/>
</c:otherwise>
</c:choose>
forEach
반복실행 태그.
Syntax 1: 객체 전체에 걸쳐서 반복
<c:forEach [var="varName"] items="collection" [varStatus="varStatusName"]
[begin="begin"] [end="end"] [step="step"]>
body content
</c:forEach>
Syntax 2: 지정한 횟수만큼 반복
<c:forEach [var="varName"] [varStatus="varStatusName"]
begin="begin" end="end" [step="step"]>
body content
</c:forEach>
<c:forEach/>
태그는 여러 가지로 활용이 가능하다. 원하는 구간만큼 반복할 수도 있고, 객체를 받아와서 그 객체의 길이만큼 반복할 수도 있다. begin
, end
속성은 시작번호와 끝 번호를 지정하고, step
속성을 이용해서 증가 구간을 정할 수 있다. var
속성에서 정한 변수로 반복되는 내부 구간에서 사용할 수 있다.
<table>
<tr><td>Value</td>
<td>Square</td></tr>
<c:forEach var="x" begin="0" end="10" step="2">
<tr><td><c:out value="${x}"/></td>
<td><c:out value="${x * x}"/></td></tr>
</c:forEach>
</table>
컬렉션의 요소를 반복할 때 <c:forEach>
태그의 추가 속성인 items
속성이 사용된다.
<c:forEach var="dto" items="${list}">
이름:${dto.name}, 제목:${dto.subject}<br/>
</c:forEach>
varStatus
는 반복 회차 각각의 메타정보를 담고 있다:
- current: 현재 아이템
- index: 0부터의 순서
- count: 1부터의 순서
- first: 첫 회차인지
- last: 마지막 회차인지
- begin: 시작값
- end: 끝값
- step: 증가값
<c:forEach items="${RESULT}" var="RESULT" varStatus="status">
forEach의 현재 아이템은 : ${status.current}
</c:forEach>
<c:forEach var="n" begin="1" end="9">
${param.num}*${n}=${param.num*n}<br/>
</c:forEach>
<c:forEach var="dto" items="${list}">
이름:${dto.name},
제목:${dto.subject}<br/>
</c:forEach>
<c:forEach var="dto" items="${list}" varStatus="s">
이름:${dto.name},
제목:${dto.subject}<br/>
현재아이템:${s.current}<br/>
0부터의순서:${s.index}<br/>
1부터의순서:${s.count}<br/>
처음이냐?:${s.first}<br/>
마지막이냐?:${s.last}<br/>
</c:forEach>
<c:forEach var="dto" items="${lists}">
<dl>
<dd class="num">${dto.num}</dd>
<dd class="subject"><a href="">${dto.subject}</a></dd>
<dd class="name">${dto.name}</dd>
<dd class="created">${dto.created}</dd>
<dd class="hitCount">${dto.hitCount}</dd>
</dl>
</c:forEach>
forTokens
<c:forTokens/>
는 java.util.StringTokenizer
의 기능을 태그로 구현한 것이다.
<c:forTokens items="stringOfTokens" delims="delimiters"
[var="varName"] [varStatus="varStatusName"] [begin="begin"] [end="end"] [step="step"]>
body content
</c:forEach>
<%@ page contentType = "text/html; charset=utf-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<h3>반복</h3>
<h4><c:forEach></h4>
<c:forEach var="one" begin="1" end="10">
<c:out value="${one}"/>
</c:forEach>
<p><b>header</b></p>
<c:forEach var="h" items="${header}">
<c:out value="${h.key}:${h.value}"/><br/>
</c:forEach>
<h4><c:forTokens></h4>
<c:forTokens var="one" items="서울|인천,대전,대구,부산,광주,평양"
delims="," varStatus="sts">
<c:out value="${sts.count}:${one}"/>,
</c:forTokens>
<hr/>
<c:forTokens var="one"
items="서울|인천,대전,대구,부산,광주,평양"
delims=",|" varStatus="sts">
<c:out value="${sts.count}:${one}"/>,
</c:forTokens>
import
<c:import/>
는 웹 애플리케이션 내부의 자원이나, http, ftp 같은 외부에 있는 자원을 가져와서 페이지 내에 귀속시킨다. 자유롭게 가공할 수도 있고, 편집도 가능하다.
Syntax 1: 해당 주소를 바로 출력하거나 String 에 담아놓는다.
<c:import url="url" [context="context"]
[var="varName"] [scope="{page|request|session|application}"]
[charEncoding="charEncoding"]>
<c:param> 서브 태그 위치
</c:import>
Syntax 2: 해당 주소의 콘텐츠를 Reader 객체로
<c:import url="url" [context="context"]
varReader="varReaderName"
[charEncoding="charEncoding"]>
varReader 를 사용하는 액션
</c:import>
<%@ page contentType = "text/html; charset=utf-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<c:set var="url" value="http://www.daum.net/"/>
<c:import url="${url}" var="u"/>
<c:out value="${url}"/> 가져옵니다.
<hr/>
-- 홈페이지 결과 출력<br/>
<c:out value="${u}" escapeXml="false"/>
<hr/>
<c:set var="url" value="http://www.naver.com"/>
<c:import url="${url}" var="u"/>
<c:out value="${url}"/> 가져옵니다.
<hr/>
-- 소스 출력<br/>
<pre><c:out value="${u}"/></pre>
<hr/>
<c:set var="url" value="gugu.jsp"/>
<c:import url="${url}" var="u">
<c:param name="su" value="5"/>
</c:import>
<c:out value="${url}"/> 가져옵니다.
<hr/>
<c:out value="${u}" escapeXml="false"/>
<hr/>
if
조건문으로 사용한다.
Syntax 1: Body 없는 경우
<c:if test="testCondition" var="varName" [scope="{page|request|session|application}"]/>
Syntax 2: Body 있는 경우
<c:if test="testCondition" [var="varName"] [scope="{page|request|session|application}"]>
body content
</c:if>
<form method="post">
수: <input type="text" name="num">
<input type="submit" value="결과">
</form>
//액션이 없어서 자기 자신에게 parameter를 전송하는 폼
<c:if test="${not empty param.num }">
<c:if test="${param.num % 2 == 0}">
${param.num}은 짝수<br/>
</c:if>
<c:if test="${param.num % 2 != 0 }">
${param.num}은 홀수<br/>
</c:if>
</c:if>
<c:if test="${dataCount==0}">
등록된게시물이음슴
</c:if>
<c:if test="${dataCount!=0}">
${pageIndexList}
</c:if>
<c:if/>
에서 나온 결과를 var
속성으로 지정하고 나중에 활용이 가능하다. scope
속성은 생략할 경우 기본 값은 page
이다. 참고로 <c:else>
태그는 없다.
자바스크립트 제어
<c:if test="${sessionScope.session.userId == dto.userId}">
function updateBoard(boardNum) {
var url = "/board/update.action";
location.href = url;
}
</c:if>
이렇게들 많이 쓰지만 사실 자바스크립트 쪽은 JSTL 없이 별도의 js 파일로 분리하는게 좋다. (캐시와 난독화 적용하려면…)
out
JSP expression1을 대체하는 태그로 가장 많이 사용된다… 는 옛말이고 지금은 XML을 escape 처리할 때나 사용되는 태그.
Syntax 1: body 없는 경우
<c:out value="value" [escapeXml="{true|false}"] [default="value가 없을 때 표시될 문자"] />
Syntax 2: body 있는 경우
<c:out value="value" [escapeXml="{true|false}"] />
value가 없을 때 표시될 문자
</c:out>
Hello <c:out value="${user.username}" default="Guest"/>!
<c:out value="${user.company}" escapeXml="false"/>
<c:set var="timezone" scope="session">
<c:out value="${cookie['tzPref'].value}" default="CST"/>
</c:set>
<c:out value="< >" escapeXml="true"/> <!-- &lt;&gt; -->
<c:out value="< >" escapeXml="false"/> <!-- <> -->
escapeXml
속성은 XML Entities의 치환여부를 의미한다. 생략 혹은 true
로 설정할 경우 value
에 XML entities로 치환가능한 특수문자가 있을 경우 치환하여 표시한다. 반대로 false
는 value
를 있는 그대로 표시한다.
가령 :
라는 값을 출력할 때 escapeXml="false"
일 땐 :
문자 그대로 내보내고 브라우저가 이를 :
으로 치환한다. 반면 escapeXml="true"
면 :
를 그대로 출력하기 전에 한 번 더 escape 해서 &#58;
라는 문자를 응답한다. 브라우저가 보기에 &#58;
에서 치환해야 하는 문자는 &
뿐이므로 최종적으로는 &;#58;
가 페이지에 표시되는 것이다.
param
보통 import
, redirect
, url
태그와 같이 쓰이는 태그. 파라미터=값
형식을 표현한다.
<c:param 속성="값".../>
<c:import url="/exec/doIt">
<c:param name="action" value="register"/>
</c:import>
<!-- 이 방법은 아래 태그와 같은 효과가 있다 -->
<c:import url="/exec/doIt?action=register"/>
redirect
response.sendRedirect()
를 대체하는 태그. 컨텍스트를 지정해서 다른 컨텍스트로 이동이 가능하다.
Syntax 1: Body 없는 경우
<c:redirect url="value" [context="context"]/>
Syntax 2: Body 있는 경우 쿼리 스트링 파라미터 지정
<c:redirect url="value" [context="context"]/>
<c:param> 서브태그
</c:redirect>
<% response.setContentType("text/html");%>
<%@ taglib uri="http://java.sun.com/jstl/core" prefix="c"%>
<c:redirect url="/test.jsp"/>
set, remove
set은 HttpServletRequest.setAttribute()
와 역할이 같다. scope
속성으로 page
, request
, session
, application
중 하나의 유효범위를 설정할 수 있다.
remove는 JSP의 removeAttribute()
와 같은 역할을 한다. page
, request
, session
, application
범위의 변수를 제거한다.
Syntax 1: scope 에 해당하는 변수에 속성 값을 정한다.
<c:set value="value" var="varName" [scope="{page|request|session|application}"]/>
Syntax 2: scope 에 해당하는 변수에 body 값을 정한다.
<c:set var="varName" [scope="{page|request|session|application}"]>
body content
</c:set>
Syntax 3: 속성으로 target 객체의 프로퍼티 값을 정한다.
<c:set value="value" target="target" property="propertyName"/>
Syntax 4: body에서 target 객체의 프로퍼티 값을 정한다.
<c:set target="target" property="propertyName">
body content
</c:set>
scope
속성이 생략될 경우 기본 값은 page다
. 그리고 var
속성과 target
속성은 동시에 사용할 수 없다.
<c:set var="testObject" value="hello world!"/> // request.setAttribute("testObject", "hello world!")
<c:out value="${testObject}"/> // request.getAttribute("testObject")
var
속성의 경우는 비교적 간단하다:
<jsp:useBean id="map" class="java.util.HashMap"/>
<c:set target="${map}" property="hi" value="hello world!"/> // map.put("hi", "hello world!")
<c:out value="${map.hi}"/> // map.get("hi")
<jsp:useBean id="vo" class="com.test.TestVO"/>
<c:set target="${vo}" property="name" value="who?"/> // vo.setName("who?")
<c:out value="${vo.name}"/> // vo.getName()
<c:forEach items="${sampleList}" var="list">
<c:set target="${list}" property="col1" value="1234"/> // sampleList.get(loop).setCol1("1234")
<tr>
<td>${list.col1}</td> // sampleList.get(loop).getCol1()
<td>${list.col2}</td>
<td>${list.col3}</td>
<td>${list.col4}</td>
<td>${list.col5}</td>
<td>${list.col6}</td>
</tr>
</c:forEach>
target
속성은 jsp에서 객체 생성 후 사용하거나 기존 객체의 getter/setter를 이용하는 방식이다.
리스트 만들기
<!-- attr에서 선언 -->
<c:set var="arr" value="A1,A2,A3,A4,A5,A6,B1,B2"/>
<!-- body에서 선언 -->
<c:set var="arr2">A1,A2,A3,A4,A5,A6,B1,B2</c:set>
각 요소를 구분하는 쉼표 뒤에 빈 칸이 있으면 안된다. 빈 칸을 포함한 문자열로 생성되기 때문.
url
<c:url/>
태그는 컨텍스트를 자동으로 추가해서 주소를 자동으로 생성해준다. context
속성이 지정되었을 경우 value
와 context
의 값은 /
로 시작을 해야 된다. context
속성이 생략되면 당연히 현재의 컨텍스트가 적용된다.
Syntax 1: Body 없는 경우
<c:url value="value" [context="context"] [var="varName"] [scope="{page|request|session|application}"]/>
Syntax 2: Body 있는 경우 파라미터 지정
<c:url value="value" [context="context"] [var="varName"] [scope="{page|request|session|application}"]>
<c:param> 서브태그
</c:url>
<% response.setContentType("text/html");%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<c:url value="/images/tomcat.gif"/>
<img src='<c:url value="/images/tomcat.gif"/>
-
<%= %> [본문으로] ↩