본문 바로가기
다양한 기술들/Web 관련

[07] JSP 응용 : JSTL 커스텀액션태그

by 예스p 2023. 2. 10.

커스액션태그(JSTL)

이전장에서 배웠던 표준액션태그에 이어서

커스텀 액션태그에 대해서 알아보자.


JSTL이란?

  • JSP Standard Tag Library의 약자로 JSP에서 사용되는 커스텀 액션태그
  • 공통적이고 자주 사용되는 코드들을 쉽게 사용할 수 있도록 태그화 한 후
    표준으로 제공하고 있는 라이브러리

 

 

사용준비하기

  1. 라이브러리 다운로드
    아파치 톰캣 사이트 들어가기
    >>왼쪽 메뉴바 다운로드 하단 Taglibs 클릭
    >>4개의 라이브러리 (.jar파일) 다운로드
    >>WEB-INF/lib/ 에 추가
  2. JSTL 선언하기
    - JSTL을 사용하고자하는 jsp 페이지 상단에 taglib 지시어를 사용해서 선언
     : <%@ taglib prefix="접두어" uri="라이브러리 파일상의 uri주소" %>

 

 

JSTL 라이브러리 종류

  • JSTL Core Library
    - 변수선언, 조건문, 반복문 등 자바로직과 관련된 문법을 제공한다.
    - 스크립틀릿 안에 쓰던 자바문법을 대체할 수 있다.
  • JSTL Formatting Library
    - [숫자/날짜/시간] 데이터의 출력형식을 지정할 때 사용한다.
  • JSTL Function Library
    - EL안에서 사용할 수 있는 함수들을 제공한다.
    - 단, 자바문법을 모르는 사용자를 위해 개발되었기때문에 자바문법으로 대체가 가능하다.

 

 


JSTL Core Library

변수선언, 조건문, 반복문 등의 자바로직과 관련된 문법을 제공하는

Core Library 액션태그에 대해서 알아보자


taglib 입력하기

  • prefix 값은 일반적으로 "c"를 사용한다.
  • uri값 = "http://java.sun.com/jsp/jstl/core"
    (이때 빨간줄이 뜬다면 보통 jar파일이 없는 것이다.)
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

 

 

변수의 역할을 하는 <c:set />

  • [표현법] <c:set var="변수명" value="담을값" [scope="저장할내장객체"] />
  • 변수를 선언하고 초기값을 대입해두는 기능을 제공한다.
    선언시 초기화는 필수이다.
  • 내부적으로 해당 scope에 setAttribute()로 데이터를 담는다.
    scope생략시 기본적으로 pageScope에 저장한다.
  • 자바의 변수와 비슷하게 활용하나 정확하게는 attribute의 속성과 속성값에 해당한다.
    때문에 변수타입을 별도로 지정하지 않는다.
  • <c:set>으로 선언된 변수는 EL로 접근해서 사용 가능하다.
    (단, 출력식/스크립틀릿과 같은 스크립팅 원소로는 접근 불가하다)
  • 태그내에서 EL을 활용할 수 있다.
  • value 속성 대신 시작태그와 종료태그 사이에 사이에 초기값 지정 가능하다.
<c:set var="num1" value="10" /> 
<!--내부적으로 실행되는 코드: pageContext.setAttribute("num1", "10") -->
<c:set var="num2" value="20" scope="request" /> 
<!--내부적으로 실행되는 코드: request.setAttribute(""num2", "20") -->
<c:set var="result" value="${ num1+num2 }" scope="session" />
<!--태그 내에서 EL을 쓸 수 있다. -->
<c:set var="result" scope="request">9999</c:set>
<!--value속성 대신 태그 사이에 값 입력하기-->

<!-- 출력할때는? -->
num1값 : ${ num1 }
num2값 : ${ num2 }
result값 : ${ result } <!-- 저장범위가 작은 request의 9999 값이 출력된다 -->

 

 

변수를 삭제하는 <c:remove />

  • [표현법] <c:remove var="제거하고자하는변수명" [scope="저장된내장객체"] />
  • 해당 scope 영역에서 해당 변수명을 찾아서 제거하는 태그
  • scope 지정 생략시 모든 scope에서 다 찾아서 제거한다.
  • 내부적으로 해당내장객체.removeAttribute() 메소드가 실행된다.

 

 

화면에 출력하는 <c:out />

  • [표현법] <c:out value="출력하고자하는값" [default="기본값"] [escapeXml="true/false"] />
  • 변수 또는 데이터를 출력한다.
    단, 변수를 넣는다면 value에 EL을 사용해야 한다.
  • 그냥 사용시 일반 EL문법과 차별성이 없지만 default속성과 escapeXml속성을 통해 차별성을 갖는다. 
  • default 속성 : value에 담긴 값이 비어있을 경우 출력할 값을 지정한다.
  • escapeXml속성 : 출력값에 html태그가 있을 경우 해석할지 여부를 결정한다.
    생략시 기본값은 true이며, 태그를 해석하지 않고 그대로 출력한다.
<c:out value="${ result }" default="없음" />
<!-- result값이 없을 경우 '없음'을 출력 -->

<c:set var="outTest" value="<b>테스트</b>" /> 
<c:out value="${ outTest }" /> <br> <!-- '<b>테스트</b>' 출력됨--->
<c:out value="${ outTest }" escapeXml="false" /> <!-- 굵은글씨로 '테스트' 출력됨 -->

 

  • 실전예제 : 로그인유저의 프로필 이미지가 없는 경우 디폴트 이미지를 띄우기
<img src="<c:out value='${ loginUser.profileImg }' default='resources/profile_images/defaultProfile.png' />">

 

 

 

if문의 역할을 하는  <c:if >

  • [표현법] <c:if test="조건식" >수행할내용</c:if>
  • 자바에서의 단일 if문과 비슷한 역할을 한다.
    true일시 수행할 내용은 시작태그와 종료태그 사이에 기술한다.
  • test 속성 : 
    조건식을 작성하되 반드시 ""안의 EL 구문 형태로 기술해야한다.
    이때, el구문 이후에 공백 등을 포함하면 수행되지 않으므로 주의한다
<c:set var="str" value="안녕하세요" />
<c:if test="${ str == '안녕하세요' }"> <!-- true로 아래 내용이 수행된다 -->
	<h4>Hello World</h4> 
</c:if>
<c:if test="${ str ne '안녕하세요' }"> <!-- false로 아래 내용이 수행되지 않는다 -->
	<h4>Bye World</h4>
</c:if>

 

 

if else문을 묶는 역할을 하는 <c:choose >
if의 역할을 하는 <c:when>
else의 역할을 하는 <c:otherwise>

  • [표현법] <c:choose >
                <c:when test="조건식">true일시 수행할내용</c:when>
                <c:otherwise>false일시 수행할내용</c:otherwise>
            </c:choose>
  • 조건문은 <c:choose>태그의 하위로 <c:when>태그를 작성한 후 test속성에 작성한다.
    <c:when>을 여러개 작성하면 else if와 동일한 로직이 구성된다.
    마지막에 기재된 <c:otherwise>가 else의 역할을 한다.
<!-- 기존방식 -->
	<% if(num1>20) { %>
		수행할내용1
	<% } else if(num1>10) { %>
		수행할내용2
	<% } else { %>
		수행할내용3
	<% } %>
	
<!-- 액션태그방식 -->
	<c:choose>
		<c:when test="${ num1 gt 20 }">
			수행할내용1
		</c:when>
		<c:when test="${ num1 gt 10 }">
			수행할내용2
		</c:when>
		<c:otherwise>
			수행할내용3
		</c:otherwise>
	</c:choose>

 

 

반복문의 역할을 하는 <c:forEach >

  • for loop 반복문
    [표현법] <c:forEach var="변수명" begin="초기값" end="끝값" [step="증가값"]>
                 변수가 한단계 증가할동안 수행할 내용(끝값일때도 수행)
            </c:forEach>

    - step : 증가값을 지정한다. 생략시 +1씩 증가
  • for each 반복문
    [표현법]<c:forEach var="변수명" items="순차적으로접근할객체" [varStatus="변수명"]>
               순차적으로 접근할 때 수행할 내용
           </c:forEach>

    - varStatus : 현재 접근된 요소의 상태값을 갖고있는 객체를 보관할 변수명을 지정.
      0부터 시작하는 인덱스가 궁금하다면 '변수명.index'로 접근
      1부터 시작하는 순번이 궁금하다면 '변수명.count'로 접근
  • 공통 적용 사항 : 
    var로 선언된 변수에 접근하고자 할때는 EL구문을 사용해야한다.
<!-- for each 기존방식 -->
	<% for(int i=1; i<=10; i+=2) { %>
		반복수행할 내용 : <%= i %>
	<% } %>
<!-- for each 액션태그방식 -->
	<c:forEach var="i" begin="1" end="10" step="2">
		반복수행할 내용 : ${ i }
	</c:forEach>
    
<!-- for loop 기존방식 -->
	<% for(String c : color) { %>
		<li><%= c %></li>
	<% } %>
<!-- for loop 액션태그방식 -->	
	<c:forEach var="c" items="${ colors }">
		<li style="color:${ c }">${ c }</li><!-- 태그 안에서도 EL출력 가능하다 -->
	</c:forEach>

<!-- ArrayList 접근 기존방식 -->
	<% if(list.isEmpty()) { %>
		리스트가 비어있을경우 수행할 내용
	<% }else { %>
		<%for(Person p : list) { %>
			반복수행할 내용
		<% } %>
	<% } %>
<!-- 액션태그방식 -->
	<c:chose>
		<c:when test="${ empty pList }">
			<td colspan="4">조회된 사람이 없습니다.</td>
		</c:when>
		<c:otherwise>
			<c:forEach var="p" items="${ pList }" varStatus="status">
				${ status.count }
				${ p.name }
				${ p.age }
				${ p.gender }
			</c:forEach>		
		</c:otherwise>
	</c:chose>

 

 

반복문의 역할을 하는 <c:forTokens >

  • [표현법] <c:forTokens var="변수명" items="문자열" delims="구분자" >
              반복수행할내용
          </c:forTokens>
  • 자바에서의 split 또는 StringTokenizer와 비슷한 기능을 처리한다.
  • items : 분리시키고자하는 문자열을 담는다
  • delims : 구분자를 담는다. 여러개일경우 나열하면 된다.
  • var : 분리된 문자열을 담을 변수명을 담는다.
<!-- 다양한 구분자를 포함한 문자열 생성 -->
	<c:set var="device" value="컴퓨터,핸드폰,TV.에어컨/세탁기" />
<ol>
	<c:forTokens var="d" items="${ device }" delims=",./">
		<li>${ d }</li>	
	</c:forTokens>
</ol>

 

 

url의 역할을 하는 <c:url />
쿼리스트링의 역할을 하는 <c:param />

  • [표현법] <c:url var="변수명" value="요청할url">
              <c:param name="키값" value="전달할값" />
              <c:param name="키값" value="전달할값" />
              ...
          </c:url>
  • var : 만들어진 쿼리스트링이 포함된 url이 담긴다
    사용시에는 EL구문으로 꺼내쓴다.
<!-- 기존방식 -->
	<a href="list.do?cpage=1&num=2">기존방식</a>
<!-- 액션태그방식 -->
	<c:url var="ttt" value="list.do">
		<c:param name="cpage" value="1" />
		<c:param name="cpage" value="2" />	
	</c:url>
	<a href="${ ttt }">액션태그 방식</a>

 

 

 


JSTL Formattiong Library

숫자, 날짜, 시간을 출력할 때 유용한 액션태그를 알아보자.


taglib 입력하기

  • prefix 값은 일반적으로 "fmt"를 사용한다.
  • uri값 = "http://java.sun.com/jsp/jstl/fmt"
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>

 

 

숫자의 포멧을 지정하는 <fmt:formatNumber />

  • 통화기호, % 등 숫자를 쓰임에 맞게 출력한다.
  • [표현법] <fmt:formatNumber value="출력할값" [groupUsed="..." type="..." currencySymbol="..."]/>
  • groupingUsed :
    boolean으로 세자리마다 구분자(,) 표시 여부 지정
    생략시 기본값은 true
  • type :
    "percent" 입력시 value에 대입된 값에 100을 곱한 후 %를 붙여서 출력한다.
    "currency" 입력시 로컬가격표시가 앞에 붙는다.
  • currencySymbol :
    type이 currency일때 사용할 통화기호문자를 직접 입력한다.

 

 

날짜 및 시간의 포멧을 지정하는 <fmt:formatDate />

  • java.util.Date 객체를 변수에 담은 후 사용한다.
  • type
    date/time/both 셋중 하나가 들어올 수 있으며, 생략시 기본값은 date이다.
  • dateStyle
    날짜의 표현값을 지정한다.
    full/long/medium/short 이 올 수 있으며, 생략시 기본값은 medium이다.
  • timeStyle
    시간의 포멧을 지정한다.
    full/long/medium/short 이 올 수 있으며, 생략시 기본값은 medium
  •  pattern
    나만의 패턴을 지정한다.
    yy- 연도
    MM - 월
    dd - 일
    E - 요일
    HH - 시
    mm - 분
    ss - 초
    a - 오전/오후

<c:set var="current" value="<%=new java.util.Date() %>" />
그냥출력시 : ${ current } 
	<!-- Fri Feb 10 14:26:55 KST 2023 -->
날짜만출력 : <fmt:formatDate value="${ current }" />
	<!-- 2023. 2. 10. -->
시간만출력 : <fmt:formatDate value="${ current }" type="time" />
	<!-- 오후 2:31:20 -->
날짜 및 시간 : <fmt:formatDate value="${ current }" type="both" />
	<!-- 2023. 2. 10. 오후 2:32:39 -->
Medium : <fmt:formatDate value="${ current }" type="both" dateStyle="medium" timeStyle="medium"/>
	<!-- 2023. 2. 10. 오후 2:35:47 -->
long : <fmt:formatDate value="${ current }" type="both" dateStyle="long" timeStyle="long"/>
	<!-- 2023년 2월 10일 오후 2시 36분 21초 KST -->
full : <fmt:formatDate value="${ current }" type="both" dateStyle="full" timeStyle="full" />
	<!-- 2023년 2월 10일 금요일 오후 2시 38분 10초 대한민국 표준시 -->
short : <fmt:formatDate value="${ current }" type="both" dateStyle="short" timeStyle="short" />
	<!-- 23. 2. 10. 오후 2:38 -->
나만의 패턴 지정 : <fmt:formatDate value="${ current }" type="both" pattern="yyyy-MM-dd(E)"/>
	<!-- 2023-02-10(금) -->

 

 


JSTL Function Library

EL안에서 사용할 수 있는 함수들을 제공한다.


taglib 입력하기

  • prefix 값은 일반적으로 "fn"를 사용한다.
  • uri값 = "http://java.sun.com/jsp/jstl/functions"
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>

 

 

문자열 관련 메소드

  • 자바문법을 모르는 사람을 위해 나온 라이브러리라서
    자바의 String 메소드에 대체가능한 메소드들 이 있긴함.
  • 예시용 문자열 선언하기 : <c:set var="str" value="How Are You?" />
  • ${ fn:length(str) } :
    == ${ str.length() }
    단, 자바문법과의 차이점은 문자열 뿐 아니라 ArrayList, 배열의 크기도 반환한다는 점이다
  • ${ fn:toUpperCase(str) }
    == ${ str.toUpperCase() }
    모두 대문자로 반환한다.
  • ${ fn:toLowerCase(str) }
    == ${ str.toLowerCase() }
    모두 소문자로 반환한다.
  • ${ fn:indexOf(str, 'Are') }
    == ${ str.indexOf('Are') }
    Are의 시작인덱스를 반환한다.
  • ${ fn:substring(str, 1, 5) }
    1번인덱스~5번인덱스의 문자열을 추출한다.
  • ${ fn:contains(str, 'are') }
    'are'가 포함되어있는지 여부를 boolean반환
  • ${ fn:containsIgnoreCase(str, 'are') }
    대소문자를 가리지 않고 'are'가 포함되어있는지 여부를 반환

 

 

 

 

 

 

 

댓글