학습(구)/JSP

커스텀 태그

잉아당 2020. 9. 17. 22:10
728x90

문서 작성의 효율성과 문서 가독성을 높이기 위해 액션 태그 및 JSTL 태그만으로는 한계가 있으므로 자신의 애플리케이션에 적합한 커스텀 태그를 정의하고 이를 사용하여 페이지를 작성합니다.

 

태그 파일을 이용한 커스텀 태그 구현

커스텀 태그 구현 태그 파일 작성(.tag) -> JSP 페이지에서 <taglib>로 태그 파일을 끌어온 후 커스텀 태그 사용

 

태그 파일은 WEB-INF/tags에 위치 시키며 확장자는 .tag 혹은 .tagx를 사용하빈다. 

태그 파일의 이름은 커스텀 태그의 이름이 되며 이를 사용하는 JSP페이지의 taglib디렉티브 tagdir속성으로 등록해야합니다.

 

태그 파일의 주요 디렉티브

디렉티브 기능
tag 태그파일의 설정 정보를 지정합니다. JSP 페이지의 page디렉티브와 동일합니다.
attribute 태그 파일이 입력받을 속성을 명시합니다.
variable EL변수로 사용할 변수 정보를 지정합니다.
taglib 태그 파일에서 사용할 태그 라이브러리를 명시합니다.
include 태그 파일에 특정 파일을 포함시킵니다.

=> 몸통을 위한 디렉티브는 없습니다.

 

tag 디렉티브의 주요 속성

주요 속성 기능
body-content 전달 받는 몸체의 종류를 명시합니다. empty,scriptless,tagindependent 등 3종류 중 1개를 명시하명 default값은 scriptless 입니다.
dynamic-attributes 동적 속성을 사용할 때 속성의 <이름,값>을 저장할 Map 객체를 지정합니다. 이러한 Map 객체는 EL에서 변수 이름으로 사용합니다.
import page 디렉티브의 import 속성과 동일합니다.
pageEncoding page 디렉티브의 pageEncoding 속성과 동일합니다.
isELIgnored page 디렉티브의 isELIgnored 속성과 동일합니다. default 값은 true이며 이때 EL표현을 무시합니다.

 

태그 파일

<%-- 전달받은 몸체의 종류를 empty로 지정한다. 즉 몸체를 전달받지 않는다. --%>
<%@ tag body-content="empty" pageEncoding="utf-8" %>
<%@ tag import = "java.util.Calendar" %> 
<%
Calendar time = Calendar.getInstance();
%>
<%= time.get(Calendar.YEAR) %>년 
<%= time.get(Calendar.MONTH)+1 %>월 
<%= time.get(Calendar.DATE) %>일

태그 파일 사용

<%@ page contentType = "text/html; charset=utf-8" %>
<%-- 태그 파일이 위치하는 폴더는 tagdir 속성으로 지정하고 태그 접두어는 prefix 속성으로 지정한다. --%>
<%@ taglib prefix="pf" tagdir="/WEB-INF/tags" %>
<html>
<head><title>현재 시각</title></head>
<body>
<%-- tagdir 속성으로 지정하는 폴더의 커스텀 태그 파일을 --%> 
<%-- prefix로 지정하는 태그 접두어를 사용하여 호출한다. --%> 
<%-- 이때 <pf:time/>이 요소는 동적 요소이다. --%> 
오늘은 <b><pf:time /></b> 입니다.
</body>
</html>

 

attribute 디렉티브의 주요속성

속성 기능
name 태그파일에서 사용할 속성 이름을 설정합니다. 속성 이름에 대응하는 속성의 값은 태그 파일을 사용하는 JSP 페이지에 제공합니다.
required 필수 여부를 지정하며 default값은 false입니다.
rtexpvalue 속성 값으로 표현식을 사용할 수 있는지 여부를 지정하며 default값은 true입니다.
type 속성 값의 타입으로 클래스 이름을 지정합니다.
fragment 속성 값을 <jsp:attribute>액션 태그로 전달할 때에는 true를 지정합니다.

attribute 디렉티브 사용 태그 파일

<%@ tag body-content="empty" pageEncoding="utf-8" %>
<%@ tag trimDirectiveWhitespaces="true" %>
<%-- attribute 디렉티브를 사용하여 전달받는 속성을 content 변수에 저장하며 필수이다. --%> 
<%@ attribute name="content" required="true" %>
<%-- attribute 디렉티브를 사용하여 전달받는 속성을 size 변수에 저장한다. --%> 
<%@ attribute name="size" type="java.lang.Integer" %>
<%
String StartTag = null; 
String EndTag = null; 
if (size == null) {
 StartTag = "<h1>";
 EndTag = "</h1>";
} else if (size == 1) {
 StartTag = "<h1>";
 EndTag = "</h1>";
} else if (size == 2) {
 StartTag = "<h2>";
 EndTag = "</h2>";
} else if (size == 3) {
 StartTag = "<h3>"; 
 EndTag = "</h3>";
} %>
<%= StartTag %>
${content}
<%= EndTag %>

attribute 디렉티브 사용 태그 파일 사용

<%@ page contentType = "text/html; charset=utf-8" %>
<%@ taglib prefix="pf" tagdir="/WEB-INF/tags" %> 
<html>
<head><title>속성 전달하기</title></head>
<body>
<%-- 커스텀 태그를 호출하면서 title과 level의 값을 태그 파일에 전달한다. --%> 
<pf:attribute content="attribute 디렉티브 사용하기" size="1"/>
<%-- 커스텀 태그를 호출하면서 title과 level의 값을 태그 파일에 전달한다. --%> 
<pf:attribute content="${'attribute 디렉티브를 사용하여'}" size="3"/>
<%-- 커스텀 태그를 호출하면서 title 값을 태그 파일에 전달한다. --%> 
<pf:attribute content='<%= "속성 값을 전달받는다." %>' />
</body>
</html>

attribute의 fragment속성을 true로 지정하면 JSP페이지에서는 <jsp:attribute>액션 태그를 사용하여 속성을 전달해야 하며 태그 파일은 <jsp:invoke>액션 태그를 사용하여 전달 받은 속성을 사용해야 합니다.  

 

fragment속성 태그파일

<%@ tag body-content="empty" pageEncoding="utf-8" %>
<%@ tag trimDirectiveWhitespaces="true" %>
<%-- attribute 디렉티브의 fragment 속성을 true로 지정한다. --%> 
<%@ attribute name="content" fragment="true" required="true" %>
<h1>
<jsp:invoke fragment="content" />
<!-- cf. ${content} -->
</h1>

fragment속성 태그파일 사용 JSP 페이지

<%@ page contentType = "text/html; charset=utf-8" %> 
<%@ taglib prefix="pf" tagdir="/WEB-INF/tags" %> 
<html>
<head><title>fragment 속성 전달하기</title></head> 
<body>
<%-- 속성을 전달하려면 <jsp:attribute> 액션 태그를 사용해야 한다. --%>
<%-- 태그 파일의 body-content 속성이 empty 이어서 --%>
<%-- 커스텀 태그의 몸체에는 이러한 JSP 주석도 포함되면 오류가 발생한다. --%> 
<pf:attributefragment>
<jsp:attribute name="content"> ${'fragment attribute 사용하기'} 
</jsp:attribute>
</pf:attributefragment>
</body>
</html>

<pf:fragment속성태그파일이름> 으로 <jsp:attribute>액션태그를 감싸는데 해당 액션태그로 태그파일에 속성을 전달합니다.그러면 태그파일에서는 해당 속성을 받은 값을 사용용하여 출력합니다.

 

동적 속성을 사용할때는 tag디렉티브의 dynamic-attribute 속성에 동적 속성을 저장할 병수를 지정하고 JSP 페이지가 전달하는 속성들을 동적으로 사용하면 이러한 속성들은 Map 타입의 EL변수로 변환되어 태그 파일이 지정한 동적변수에 전달되어 사용된다.

 

dynamic-attribute속성을 사용하는 태그파일

<%@ tag body-content="empty" pageEncoding="utf-8" %> 
<%@ tag trimDirectiveWhitespaces="true" %>
<%-- 속성이 동적으로 전달될 때에는 동적 속성 변수를 dynamic-attributes 속성으로 지정한다. --%>
<%-- 이때 dynamic-attributes 속성 변수는 java.util.map 객체로 지정된다. --%>
<%@ tag dynamic-attributes="dynamicVar" %>
<%@ attribute name="name" required="true" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> 
<select name="${name}">
<%-- 동적 속성들을 forEach로 처리하고 있다. --%>
<c:forEach items="${dynamicVar}" var="dVar"> 
<option value="${dVar.key}">${dVar.value}</option> 
</c:forEach>
</select>

dynamic-attribute속성을 사용하는 태그파일을 사용한 JSP페이지

<%@ page contentType = "text/html; charset=utf-8" %>
<%@ taglib prefix="pf" tagdir="/WEB-INF/tags" %> 
<html>
<head><title>속성을 동적으로 전달하기</title></head> 
<body>
교과목 선택 :
<pf:dynamic name="subject" java="자바" jsp="JSP" spring="스프링" />
<br/><br/><br/><br/>
동아리 선택 :
<pf:dynamic name="club" spring="iCloser" iot="IoT 동아리" smartfactory="club SF" />
</body> 
</html>

 

몸체 다루기

scriptless 태그파일

<%-- 태그 파일을 호출하는 커스텀 태그의 몸체에 위치하는 모든 스크립트 요소들은 --%> 
<%-- 모두 처리되어 태그 파일에 전달된다. --%>
<%@ tag body-content="scriptless" pageEncoding="utf-8" %>
<%-- 전달받은 몸체를 var 변수에 저장한다. --%>
<jsp:doBody var="content" scope="page" />
<%
String content = (String)jspContext.getAttribute("content");
%>
<%-- content 변수의 내용을 출력한다. --%>
<%= content %>

scriptless JSP 페이지 

<%@ page contentType = "text/html; charset=utf-8" %>
<%@ page import = "java.util.Date" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> 
<%@ taglib prefix="pf" tagdir="/WEB-INF/tags" %>
<html>
<head><title>body-content Scriptless</title></head>
<body>
<c:set var="dateEL" value="<%= new Date() %>" />
<%-- 몸체의 스크립트를 처리한 결과를 태그 파일에 전달한다. --%>
<%-- <font>, ${dateEL} 등은 스크립트 처리되고 그 결과가 태그 파일에 전달된다. --%> 
<pf:bodyscriptless>
<font size="6"> 현재 시각은 ${dateEL} 입니다. </font>
</pf:bodyscriptless>
<br>
<%-- 몸체의 스크립트를 처리한 결과를 태그 파일에 전달한다. --%> 
<%--<u>,<b>,${dateEL}등은스크립트처리되고그결과가태그파일에전달된다. --%> 
<pf:bodyscriptless>
<u>현재 시각</u>은 <b>${dateEL}</b> 입니다. 
</pf:bodyscriptless>
<br>
</body>
</html>

=> 몸체의 스크립트를 처리한 결과를 태그로 전송하고 doBody액션태그의 var 변수에 저장하여 사용됩니다.

 

tagdependent 태그파일

<%-- 몸체의 스크립트들은 텍스트로 취급되어 태그 파일에 전달된다. --%> 
<%@ tag body-content="tagdependent" pageEncoding="utf-8" %>
<%@ tag trimDirectiveWhitespaces="true" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%-- 전달받은 몸체를 var 변수에 저장한다. --%>
<jsp:doBody var="bodyText" />
<%-- JSTL의 out 코어 태그를 사용하여 bodyText의 내용을 출력한다 --%> 
<c:out value="${bodyText}" escapeXml="true" />

tagdependent JSP페이지

<%@ page contentType = "text/html; charset=utf-8" %> 
<%@ page import = "java.util.Date" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> 
<%@ taglib prefix="pf" tagdir="/WEB-INF/tags" %>
<html>
<head><title>body-content Tagdepenedent</title></head> 
<body>
<%-- 몸체의 내용을 텍스트로 취급하여 전달한다. --%> 
<pf:bodytagdependent>
<jsp:body><u>현재 시각</u>은 <b>${dateEL}</b> 입니다.</jsp:body> 
</pf:bodytagdependent>
<br>
<%-- 몸체의 내용을 텍스트로 취급하여 전달한다. --%> 
<pf:bodytagdependent>
<%= new Date() %><u>현재 시각</u>은 <b>${dateEL}</b> 입니다.
</pf:bodytagdependent>
</body>
</html>

=> 몸체의 스크립트를 처리하지 않고 텍스트로 취급하여 그대로 전송하고 doBody액션태그의 var 변수에 저장되어 사용됩니다.

 

variable 디렉티브 사용

variable 디렉티브를 사용하면 태그 파일을 사용하는 JSP 페이지에 EL  변수를 제공할 수 있다. 디렉티브에서 name-given속성으로 변수명을 지정하면 JSP페이지에서 사용할 수 있습니다.

 

<%@ variable name-given="sumVar" variable-class="java.lang.Integer" scope="NESTED" %>

name-given속성에 변수명을 지정하고 variable-class에 클래스를 지정하며 scope로 범위를 지정할 수 있습니다. 

scope의 범위는 다음과 같습니다.

scope의 범위

AT_BEGIN : 태그 시작부터 끝

NESTED : 태그 안

AT_END : 태그 이후

 

 

'학습(구) > JSP' 카테고리의 다른 글

JDBC - 커넥션 풀  (0) 2020.09.18
DB연동-JDBC  (0) 2020.09.18
JSTL - fmt태그  (0) 2020.09.17
JSTL - core태그  (0) 2020.09.17
표현 언어(EL)  (0) 2020.09.16