목요일, 3월 28
Shadow

#016 커스텀 태그 만들기

때에 따라서 JSP 액션 태그나 JSTL 태그만으로는 뭔가 아쉬울 때가 있다. 예를 들어 로그인에 성공헀을때 세션의 member 속성에 Member 자바빈 객체를 저장한다고 해보자 이때 로그인 여부를 판단할때에는 다음과 같은 JSTL 태그를 사용할수 있다.
<c:if test=”${! empty sessionScope.member}”>
로그인한상태
</c:if>
<c:if test=”${empty sessionScope.member}”>
로그인 하지 않은 상태
</c:if>

하지만 다음과 같이 원하는 기능에 알맞은 태그를 사용할수 있다면 어떨가?
<ct:login>
로그인한 상태
</ct:login>

<ct:login value=”false”>
로그인하지 않은 상태
</ct:login>

위와 같은 특정한 상황에 알맞은 태그가 존재한다면 코드를 더욱 간결하게 작성할수 있을 것이다. 또한 더 중요한 것은 코드의 의미가 명확해 진다는 것이다.
JSP는 이처럼 JSTL이나 기본적인 JSP 액션 태그로 표현할수 없는 경우 스크립트 코드와 EL 코드를 혼합해서 사용하는 대신 또 다른 태그를 만들어서 사용할수 있도록 지원하고 있는데 이렇게 원하는 목적에 맞게 작성된 태그를 커스텀 태그라고 부른다. 그리고 커스텀 태그를 모아 놓은 것이 커스텀 태그 라이브러리라 한다.

1.1 커스텀 태그의 장점
ㅇ 재사용성 향상 : 한번 작성한 커스텀 태그는 어떤 JSP 컨테이너에서든지 사용이 가능하다.
ㅇ 쉽고 단순한 JSP 제작 : 자바 코드에 익슥하지 않은 개발자들도 커스텀 태그를 통해 쉽게 JSP 페이지를 작성할수 있게 된다. 예를 들어 JSTL과 EL을 사용하는 경우 스크립트 코드만을 사용하는 경우보다 훨씬 쉽다.
ㅇ 코드의 가독성 향상 : 앞에서 설명했듯이 커스텀 태그는 뚜렷한 목적을 갖고 있고 커스텀 태그를 사용함으로써 스크릅트 코드를 줄일수 있기 때문에 JSP 코드의 가독성을 높일수 있다.

02. 태그 파일을 이용한 커스텀 태그 구현
태그 파일이 출현하기 전까지 커스텀 태그를 구현하려면 정해진 규책대로 자바 코드를 작성하고, 컴파일해서 클래스파일을 만들고 TLD 파일을 작성하고 web.xml 파일에 TLD관련 정보를 기술해 주어야 했다. 이런 어려움을 없애기 위해 추가된것이 태그 팡리이다. 마치 서블릿의 복잡한 구현과정을 JSP가 쉽게 처리하듯이 커스텀태그클래스를 만들기 위한 복잡한 과정을 커스텀태그파일이 쉽게 처리할수 있도록 하였다.

2.1 태그파일의 기본
태그파일은 JSP 페이지와 동일한 문법을 사용한다. JSP페이지를 작성하듯이 태그파일을 작성할수있다. 또한 웹 컨테이너가 JSP소스코드를 서블릿클래스로 변환해 주듯이 태그파일도 커스텀 태그 클래스로 변환해 준다.

tag : JSP페이지의 page 디렉티브와 동일하다. page 디렉티브가 JSP 페이제에 대한 설정 정보등을 명시하는 것처럼 tag 디렉티브는 태그 파일의 정보를 명시한다.
taglib : JSP 페이지와 마찬가지로 태그 파일에 사용할 태그 라이브러리를 명시할때 사용한다.
include: JSP페이지와 마찬가지로 태그 파일에 특정한 파일을 포함시킬때 사용한다.
attribute : 태그 파일이 커스텀 태그로 사용될때 입력 받을 속성을 명시한다.
variable : EL 변수로 사용될 변수에 대한 정보를 지정한다.

태그 파일의 ㅇ튀치 및 태그 파일 참조
태그 파일은 \WEB-INF\tags 디렉터리 또는 그 하위 디렉터리에 위치한다. 이 디렉터리에 위치한 파일중에서 .tag 확장자나 .tagx 확장자를 갖는 파일만 태그 파일로 인식된다. 태그 파일의 이름은 커스텀 태그 이름이 된다. 예를 들어 \WEB-INF\tags\util 디렉터리에 removeHtml.tag 태그파일이 위치했다고 가정해 보자 이경우 JSP 페이지에서는 다음과 같이 이 태그 파일을 커스텀 태그로 사용할수 있다.
<%@ taglib prefix =”tf” tagdir=”\WEB-INF\tags\util” %>
<tf:removeHtml…>..</tf:removeHtml>
taglib 디렉티브의 uri 속성 대신 tagdir 속성을 사용해서 태그 파일이 위치한 디렉터리의 경로를 입력하고, 해당 디렉터리에 있는 태그 파일의 이름은 각각 하나의 커스텀 태그 이름이 된다.

2.2 내용을 출력하는 단순 태그 파일 구현
<%@ taglib prefix=”tf” tagdir=”\WEB-INF\tags” %>

2.3 태그 파일의 속성 설정 방법
‘JSTL의 <c:if> 태그나 <c:forEach> 태그를 보면 test, var, items등의 속성을 이용해서 태그를 실행하는데 필요한 값을 전달 받았다. 태그파일도 속성을 이용해서 태그 파일을 실행하는데 필요한 값을 전달받게 된다.

attribute 디렉티브의 속성
description : 속성에 대한 설명
name : 속성의 이름, 태그 파일내에서 스크립트 변수나 EL 변수의 이름으로 사용된다.
required : 속성의 필수 여부를 지정한다.
rtexprvalue : 속성값으로 표현식을 사용할수 있는지의 여부를 지정한다.
type : 속성값의 타입을 명시한다.
fragment : <jsp:attribute> 액션 태그로 속성값을 전달할때 이 값을 true 로 지정한다.

(1) 속성값을 전달하는 기본 방식
<%@ attribute name = “title” required=”ture” %>
<%= title %> 또는 ${title}

<%@ attribute name title required=”ture” %>
<%@ attribute name = “levle” type=”java.lang.Integer”%>

<%
String headStartTag = null;
String headEndtTag = null;
if(level == null){
headStartTag = “<h1>”;
headEndTag=”<h1>”;
}else if(level == 1){
headStartTag = “<h1>”;
headEndTag=”<h1>”;
}else if(level == 2){
headStartTag = “<h2>”;
headEndTag=”<h2>”;
}else if(level == 3){
headStartTag = “<h3>”;
headEndTag=”<h3>”;
}
<%= headStartTag%>
${title}
<%=headEndTag%>

———————————–<tf:header>——————–

<%@ taglib prefix=”tf” tagdir=”\WEB-INF\tags” %>
<html>
<body>
<tf:header title =”텍스트 제목” level=”2″/>
<tf:header title =”EL 제목” level=”3″/>
<tf:header title =”표현식 제목” />
</body>
</html>

(2)<jsp:attribute> 액션 태그를 이용한 속성값 전달
attribute 디렉티브의 fragment 속성값이 true 일 경우, JSP에서는 속성에 값을 전달할때 <jsp:attribute> 액션 태그를 사용해야 한다.

<%– header.tag–%>
<%@ attribute name = “title” fragment=”true” %><%– JSP –%>
<%@ taglib prefix=”tf” tagdir =”\WEB-INF\tags”%>
<tf:header>
<jsp:attribute name=”title”>${article.title}</jsp:attribute>
</tf:header>

<jsp:attribute> 태그는 두개의 속성을 갖는데 두 속성은 다음과 같다.
ㅇ name : 속성의 이름
ㅇ trim : 속성의 값 좌우의 공백들 문자들을 제거할지의 여부, 기본값은 true이다.
<jsp:attribute> 의 몸체에서는 일반 템플릿 텍스트, EL 그리고 <jsp:include> 액션 태그를 사용할수있으며 스크립트 코드는 사용할수 없다.

<jsp:attribute> 액션 태그를 이요해서 커스텀그의 속성값을 지정한 경우, 태그 파일에서는 <jsp:invoke>액션태그를 이용해서 설정한 속성값을 사용할수 있다. <jsp:invoke> 액션 태그의 사용방법은 두기지가 있다.

<%@ attribute name=”title” fragment=”true”%>

//첫번째 <jsp:attribute>의 몸체 내용을 그대로 처리하여 출력
<jsp:invoke fragment=”title”/>
//두번째 <jsp:attribute>의 몸체 내용을 처리한 결과를 지정 영역의 속성에 저장
<jsp:invoke fragment=”title” var=”rs” scope=”page”/>
${pageScope.rs}

<jsp:invoke> 액션 태그의 fragment 속성값은 attribute 디렉티브의 anme 속성과 같은 값을 갖는다. 첫번째 경우처럼 <jsp:invoke>의 fragment 속성값만 사용한 경우에는 <jsp:attrivute>액션 태그의 몸체 내용을 처리한 결과가 그대로 출력된다.

var 속성과 scope 속성을 사용한 경우 <jsp:attribute> 액션 태그의 몸체 내용을 처리한 결과를 scope 속성에서 지정한 영역의 속성으로 저장한다. 이때 var 속성을 이용해서 영역에 저장될때 사용될 이름을 지정한다. 위 예제코드는 apge 영역의 rs 라는 속성에 <jsp:attribute> 액션 태그의 몸체 처리 결과를 저장한다. 이ㅏ후 EL을 이용해서 저장된 객체의 값을 사용할수있게 된다.

(3) 동적 속성 전달
미리 속성 이름을 정의 할수는 없지만 상황에 따라서 동적으로 속성을 추가하고 싶은 경우에는, 커스터 ㅁ태그의 동적 속성기능을 사용하면 된다. 동적 속성을 사용할떄에는 다음과 같이 태그 파일의 tag 디렉티브에서 dynamic-attributes의 속성에 동적 속성을 저장할 변수 명을 입력해 주면 된다.

<%@ tag dynamic-attribute=”dynamicMap” %>
${dynamicMap.attrName}..

–예제소스–
<WEB-INF\tags\select.tag>파일
<%@ tag dynamic-attributes=”optionMap” %>
<%@attribute name = “name” required=”ture” %>
<%@ taglib prefix=”c” url=”httpL..java.sun.com/jsp/jstl/core” %>
<select name=”${name}”>
<c:forEach items=”${optionMap}” var=”option”>
<option value=”${option.key}”>${option.value}</option>
</c:forEach>
</select>
—————————–
use_select.jsp

<%@ taglib prefix=”tf” tagdir=”\WEB-IONF\tags” %>
<html>
<body>
<tf:select name=”code” rgb=”RGB 모드” wb=”흑백모드”/>
<tf:select name=”genre” rock=”락” ballad=”발라드” metal=”메탈” />
</body>
</html>

2.4 몸체 내용의 처리
<c:if> 태그는 test 속성의 값이 true일 겨웅 몸체 내용을 출력 하였다.
<c:if test=”${someCondition}”>
someCondition이 경우 몸체 내용을 출력
</c:tf>

태그 파일로 부터 구현된 태그 몸체를 전달하는 첫번째 방법은 JSTL 태그와 동일하게 시작 태그와 끝 내그 사이에 몸체 내용을 삽입하는 것이다.
<tf:someTagFile atr1=”속성값”>
여기에 몸체 내용을 입력 한다.
</tf:someTagFIle>

몸체 내용을 전달하는 두번째 방법은 <jsp:body> 태그를 이요해서 몸체 내용을 전달하는 것이다. 태그 파일이 <jsp:attribute>태그를 이용해서 속성값을 전달받는 경우에 <JSP:body>를 사용하여 몸체 내용을 전달 할수 있다.

<tf:someTagFile attr1=”속성값”>
<jsp:attribute name=”attr2″>value</jsp:attribute>
<jsp:body>
여기에 몸체 내용을 입력한다.
</jsp:body>
</tf:someTagFIle>

(1)EL 및 태그가 처리된 몸체 내용 사용하기
ㅇ tag 디렉티브의 body-content 속성의 값을 scriptless로 지정한다.
ㅇ <jsp:doBody> 액션 태그를 이용해서 몸체내용을 출력하거나 EL 변수로저장한다.

<%@ tag body-content=”scriptless”%>
<jsp:doBody/>

(2) 몸체 내용을 반복적으로 사용하기
<%@ attribute name=”count” required=”ture” type=”java.lang.Integer”%>
<%@ taglib prefix=”c” uri=”http://java.sun.com/jsp/jstl/core”%>
<c:forEach begin=”${1}” end=”${count}”>
<jsp:doBody />
</c:forEach>
————————————-

<%@ taglib prefix=”tf” tagdir=”\WEB-INF\tags”%>
<%@ taglib prefix=”c” uri=”http://java.sun.com/jsp/jstl/core”%>
<html>
<body>
<c:set var=”num value=”${1}” />
<tf:multiple count =”10″>
${num}<br/>
<c:set var=”num” value=”${num+1}” / >
</tf:multiple>
</body>
</html>

2.5 변수의 생성
JSTL 태그의 <c:forEach> 태그는 var 속성을 이용해서 태그 몸체 내부에서 사용될 EL 변수를 정의할 수있는 기능을 제공하고 있다. <c:set> 태그는 태그를 사용하년 페이지에 새로운 EL 변수를 추가해 준다.
<c:forEach var=”prod” items=”${prodList}”>
${prod.name}
</c:forEach>

<– 태그 실행 이후 사용 가능한 EL 변수 (name)  추가–>
<c:set var=”name” value=”bk”/>
${name}

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다

이 사이트는 스팸을 줄이는 아키스밋을 사용합니다. 댓글이 어떻게 처리되는지 알아보십시오.