커스텀 태그

JSP 2016. 3. 17. 12:33

1. 커스텀 태그(Custom Tag)

JSP 액션 태그와 같은 태그를 추가할 수 있는 기능

원하는 목적에 맞게 작성된 태그


커스텀 태그의 장점

- 재사용성 향상

- 쉽고 단순한 JSP 제작

- 가독성 향상


커스텀 태그의 종류

JSP 1.2 스타일 커스텀 태그

JSP 2.0 이상의 SimpleTag

JSP 2.0 이상의 태그 파일 (구현이 쉬움)



2. 태그 파일(tag file)

- JSP 문법을 사용해서 커스텀 태그로 동작할 수 있도록 만들어진 소스 코드

- 서블릿보다 JSP가 작성하기 쉽듯이, 클래식 태그나 SimpleTag보다 태그 파일이 작성하기 쉬움

- JSP와 동일한 방식으로 태그 파일 작성



1) 태그 파일의 위치 및 참조

위치 및 확장자 : WEB-INF/tags 디렉터리 및 하위 디렉터리 (확장자는 .tag 또는 .tagx)




2) JSP에서 태그 파일 참조

<%@ taglib prefix="tf" tagdir="/WEB-INF/tags/util" %>

 ...

<tf:removeHtml ...>...</tf:removeHtml>


/WEB-INF/tags/util 디렉터리의 removeHtml.tag 파일을<tf:removeHtml> 태그의 구현 코드로 사용



3) 태그 파일에서 사용할 수 있는 디렉티브

tag : JSP 페이지의 page 디렉티브와 동일하다. tag 디렉티브는 태그 파일의 정보를 명시한다.

taglib : JSP 페이지와 마찬가지로 태그 파일에서 사용할 태그 라이브러리를 명시할 때 사용한다.

include : JSP 페이지와 마찬가지로 태그 파일에 특정한 파일을 포함시킬 때 사용한다. 태그 파일에 포함되는 파일은 태그 파일에 알맞은 문법으로 작성되어야 한다.

attribute : 태그 파일이 커스텀 태그로 사용될 때 입력 받을 속성을 명시한다.

variable : EL 변수로 사용될 변수에 대한 정보를 지정한다.


예제) JSP 2.0 이상의 태그 파일 방식으로 커스텀 태그 구현

1) now.tag (WEB-INF/tags 폴더 아래 생성)

<%@ tag body-content="empty" pageEncoding="UTF-8" %>

<%@ tag import ="java.util.Calendar" %>

<% 

Calendar cal = Calendar.getInstance(); // 캘린터 클래스의 객체를 그 때 그 때 반환해주는 메서드

%>

<%= cal.get(Calendar.YEAR)%>년

<%= cal.get(Calendar.MONTH)+1%>월

<%= cal.get(Calendar.DATE)%>일


2) now.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"   pageEncoding="UTF-8"%>

<%@ taglib prefix="t" tagdir="/WEB-INF/tags/" %>

<!DOCTYPE html>

<html>

<head>

<meta charset="UTF-8">

<title>Insert title here</title>

</head>

<body>

오늘은 <strong><t:now /></strong>입니다.

</body>

</html>

※ prefix에서 지정하는 태그명은 자유롭게 지어줄 수 있다.




4) tag 디렉티브의 주요 속성

body-content : 몸체 내용의 종류를 지정. 기본값은 scriptless. 빈 내용일 때엔 empty, 전달되는 body의 내용을 문자열로 인식시킬 때에는 tagdependent를 사용한다. 

dynamic-attributes : 동적 속성을 사용할 때, 속성의 <이름, 값>이 저장될 Map 객체를 page 범위의 속성에 저장할 때 사용할 이름을 명시

import : page 디렉티브의 import 속성과 동일 (선택)

pageEncoding : page 디렉티브의 pageEncoding 속성과 동일 (선택)

isELIgnored : page 디렉티브의 isELIgnored 속성과 동일 (선택)

deferredSyntaxAllowedAsLiteral : page 디렉티브의 deferredSyntaxAllowedAsLiteral 속성과 동일 (선택)

trimDirectiveWhitespaces : page 디렉티브의 trimDirectiveWhitespaces 속성과 동일 (선택)




5) 태그 파일의 기본 객체

jspContext : pageContext가 제공하는 setAttribute(), getAttribute() 메서드를 그대로 제공하며, 각 속성과 관련된 작업을 처리한다.

request : JSP 페이지의 request 기본 객체와 동일하다.

response : JSP 페이지의 response 기본 객체와 동일하다.

session : JSP 페이지의 session 기본 객체와 동일하다.

application : JSP 페이지의 application 기본 객체와 동일하다.

out : JSP 페이지의 out 기본 객체와 동일하다.




3. attribute 디렉티브 - 기본


attribute 디렉티브의 기본 사용법

- name : 속성 이름. 태그 파일에서 변수명으로 사용가능

- required : 필수 여부

- type : 타입 지정 (미지정시 java.lang.String)


<%-- header.tag --%>

<%@ tag ... %>

<%@ attribute name="title" required="true" %>

...

<%= title %> 또는 ${title}



JSP에서의 사용법

<tf:header title="<%= article.getTitle() %>" />

<tf:header title="${article.title}" />

<tf:header title="이 글의 제목" />




예제) header 속성 지정하는 태그 파일

1) header.tag

<%@ tag body-content="empty" pageEncoding="UTF-8" %>

<%@ tag trimDirectiveWhitespaces="true"%>

<%@ attribute name="title" required="true" %>

<%@ attribute name="level" required="false" type="java.lang.Integer" %>

<%

String headStartTag = null;

String headEndTag = 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>";

} else if(level == 4) {

headStartTag = "<h4>";

headEndTag = "</h4>";

}else {

headStartTag = "<h3>";

headEndTag = "</h3>";

}

%>


2) header.jsp

<%= headStartTag %>${title}<%= headEndTag %>

<%@ page language="java" contentType="text/html; charset=UTF-8"  pageEncoding="UTF-8"%>

<%@ taglib prefix="h" tagdir="/WEB-INF/tags/" %>

<!DOCTYPE html>

<html>

<head>

<meta charset="UTF-8">

<title>제목 출력</title>

</head>

<body>

<h:header title="텍스트 제목" />

<h:header title="텍스트 제목" level="3" />

</body>

</html>

텍스트 제목

텍스트 제목




<jsp:attribute>액션 태그 이용 속성 값 전달


태그 파일의 attribute 디렉티브의 fragment 속성 값이 true일 경우 JSP에서는 속성에 값을 전달할 때

<jsp:attribute> 액션 태그를 사용해야 함. 


<%-- header.tag --%>

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

// 첫번째, <jsp:attribute>의 몸체 내용을 그대로 처리하여 출력

<jsp:invoke fragment=“title” />


// 두번째, <jsp:attribute>의 몸체 내용을 처리한 결과를 지정한 영역의 속성에 저장

<jsp:invoke fragment=“title” var=“rs” scope=“page” />

${pageScope.rs}


<%-- JSP --%>

<@ taglib prefix=“tf” tagdir=“/WEB-INF/tags” %>

<tf:header>

    <jsp:attribute name=“title”>${article.title}</jsp:attribute>

</tf:header>


몸체 내용에 텍스트, EL, <jsp:include> 액션 태그 사용 가능.

단, 스크립트 코드(표현식과 스크립트릿)는 사용 불가.




동적 속성

attribute 디렉티브로 지정하지 않은 속성을 Map에 저장

tag 디렉티브의 dynamic-attributes 속성에 동적 속성을 저장할 변수명 지정 (변수 타입은 Map)


<%@ tag dynamic-attributes="dynamicMap" %>

...

${dynamicMap.attrName} .. <!-- attrName 속성값 -->




예제) 상황에 따라 동적으로 속성을 추가하는 dynamic-attributes로 나만의 태그 속성 창조

1) select.tag

<%@ tag body-content="empty" pageEncoding="UTF-8"%>

<%@ tag trimDirectiveWhitespaces="true"%>

<%@ tag dynamic-attributes="optionMap"%>

<%@ attribute name="name" required="true"%>

<%@ taglib prefix="c" uri="http://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>


2) select.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>

<%@ taglib prefix="tf" tagdir="/WEB-INF/tags" %>    

<!DOCTYPE html>

<html>

<head>

<meta charset="UTF-8">

<title>DynamicAttribute</title>

</head>

<body>

<tf:select name="code" rgb="RGB모드" wb="흑백모드" />

<tf:select name="genre" rock="락" blues="블루스" jazz="재즈"  />

</body>

</html>

※ 다이나믹 어트리뷰트를 이용하여 원래는 존재하지 않는 rgb, wb, rock...등 자신만의 속성을 태그에 추가해줄 수 있다.


 






태그 파일 이용 커스텀 태그에 몸체 내용 전달하기

방법1.  태그 몸체
<tf:someTagFile attr1="속성값">
여기에 몸체 내용을 입력한다.
</tf:someTagFile>

방법2. <jsp:body> 액션 태그 사용
<tf:someTagFile attr1="속성값">
    <jsp:attribute name="attr2">value</jsp:attribute>
    <jsp:body>
    여기에 몸체 내용을 입력한다.
    </jsp:body>
</tf:someTagFile>

태그 파일 이용 커스텀 태그의 몸체에는 표현식 사용 불가



태그 파일에서 몸체 내용 사용하기

EL 및 태그가 처리된 몸체 내용 사용하기
<%@ tag body-content="scriptless" %>
<!-- 몸체로 전달 받은 내용을 사용 -->
<jsp:doBody />

몸체 내용을 데이터로 사용하기
<%@ tag body-content="tagdependent" pageEncoding="euc-kr" %>
<jsp:doBody var="bodyText" />


예제) jsp:doBody 액션태그를 이용하여 HTML 태그를 제거해주는 기능 구현

1) removehtml.tag
<%@ tag body-content="scriptless" pageEncoding="utf-8" %>
<%@ attribute name="length" type="java.lang.Integer" %>
<%@ attribute name="trail" %>
<%@ attribute name="trim" %>

<jsp:doBody var="content" scope="page" />
<%
String content = (String)jspContext.getAttribute("content");
if (trim != null && trim.equals("true")) {
content = content.trim();
}
content = content.replaceAll(
"<(/)?([a-zA-Z]*)(\\s[a-zA-Z]*=[^>]*)?>", ""); 

/*
<font size="10"> 태그를 검색하기 위한 정규식
/가 올 수도 있고 안올 수도 있다는 () 표시.
[] 알파벳 a부터 z까지, A-Z까지 오는 모든(*) 알파벳 대상. (font 검색)
\s 공백과 속성 알파벳 a부터 z까지, A-Z까지 오는 모든(*) 알파벳 대상.(size 검색)
=가 있는지 체크
>를 제외한 모든 것들 ("" 체크)
*/
if (length != null && length.intValue() > 0 &&
content.length() > length.intValue()) {
content = content.substring(0, length.intValue()); 
if (trail != null) {
content = content + trail;
}
}
%>
<%= content %>

2) removehtml.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="tf" tagdir="/WEB-INF/tags" %>

<html>
<head><title>removeHtml</title></head>
<body>
<c:set var="dateEL" value="<%= new Date() %>" />
<tf:removehtml trim="true">
  <font size="10"> 현재 <style>시간</style>은 ${dateEL} 입니다. </font>
</tf:removehtml>
<br>
<tf:removehtml length="15" trail="..." trim="true">
  <u>현재 시간</u>은 <b>${dateEL}</b> 입니다.
</tf:removehtml>
<br>
<tf:removehtml length="15">
  <jsp:body><u>현재 시간</u>은 <b>${dateEL}</b> 입니다.</jsp:body>
</tf:removehtml>

</body>
</html>

현재 시간은 Thu Mar 17 17:03:25 KST 2016 입니다. 
현재 시간은 Thu Mar ... 
현재 시간은 Thu Mar




예제) 표현언어와 태그를 그냥 문자열로 인식하여 출력하는 예제

1) out.tag
<%@ tag body-content="tagdependent" pageEncoding="utf-8" %>
<%@ tag trimDirectiveWhitespaces="true" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<jsp:doBody var="bodyText" />
<c:out value="${bodyText}" escapeXml="true" />
<!--
tagdependent는 전달되어지는 jsp body의 표현언어를 그냥 문자열로 인식
escapeXml은 브라우저 상에서 태그의 <>를 문자열로 인식시켜주는 속성. 
-->

2) out.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="tf" tagdir="/WEB-INF/tags" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>JSTL out</title>
</head>
<body>
<tf:out>
<jsp:body><u>현재시간</u>은 <Strong>${dateEL}</Strong>입니다.</jsp:body>
</tf:out>
</body>
</html>

<u>현재시간</u>은 <Strong>${dateEL}</Strong>입니다.






variable 디렉티브와 name-given을 이용한 변수 추가

태그 파일에서 EL 변수를 추가할 때 사용한다.


<%@ variable name-given="EL변수이름" variable-class="변수타입" scope="변수범위" />



name-given 속성 및 scope 속성에 따른 EL 변수 특징






예제) variable 디렉티브를 이용하여 태그 몸체 내에서 사용할 수 있는 EL변수를 추가하는 태그 파일 예제


1) sum.tag

<%@ tag pageEncoding="utf-8" %>

<%@ tag trimDirectiveWhitespaces="true" %>

<%@ attribute name="begin" required="true" type="java.lang.Integer" %>

<%@ attribute name="end" required="true" type="java.lang.Integer" %>

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

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

<c:set var="sum" value="${0}" />

<c:forEach var="num" begin="${begin}" end="${end}">

<c:set var="sum" value="${sum+num}" />

</c:forEach>

<jsp:doBody />


※ scope="NESTED"는 태그 몸체(태그 파일의 시작 태그와 끝 태그 사이)에서 변수를 사용

즉 예제에서는 <tf:sum>부터 </tf:sum>까지 해당 EL변수를 사용하겠다는 것.


2) sum.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>

<%@ taglib prefix="tf" tagdir="/WEB-INF/tags" %>

<!DOCTYPE html>

<html>

<head>

<meta charset="UTF-8">

<title>sum</title>

</head>

<body>

<tf:sum begin="1" end="10">

1~10까지의 합: ${sum}

</tf:sum>

</body>

</html>


1~10까지의 합: 55







name-from-attribute 속성을 이용한 변수 생성

- 특정 속성의 값을 생성할 변수명으로 사용


name-from-attribute 속성의 사용법


<%@ attribute name="var" rtexprvalue="false" required="true" type="java.lang.String" %>

<%@ variable alias="localName" name-from-attribute="var" scope="영역" %>

...

<c:set var="localName" value="..." />


name-from-attribute 속성에 명시한 속성의 제약 조건

rtexprvalue 속성의 값이 false

required 속성이 true (앞의 name값이 반드시 넣어야만 하는 필수속성이 된다.)

type 속성의 값은 java.lang.String

alias 속성 : 태그 파일에서 생성할 변수에 접근할 때 사용할 EL 변수명


예제) name-from-attribute 속성 이용한 변수 생성


1) removehtmlVar.tag

<%@ tag body-content="scriptless" pageEncoding="utf-8" %>

<%@ attribute name="length" type="java.lang.Integer" %>

<%@ attribute name="trail" %>

<%@ attribute name="trim" %>

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>


<%@ attribute name="var" required="true" rtexprvalue="false"%>

<%@ variable name-from-attribute="var" alias="result" scope="AT_END" %>

<!-- 

AT_END는 태그가 끝나는 순간부터 업데이트되며 그 값을 유지 

AT_BEGIN은 <jsp:doBody>로 호출되는 순간 변수값 들어가며 업데이트

NESTED는 태그는 시작부터 끝 사이에만 변수 작동 후 이후 원상복귀

-->


<jsp:doBody var="content" scope="page" />

<%

String content = (String)jspContext.getAttribute("content");

if (trim != null && trim.equals("true")) {

content = content.trim();

}

content = content.replaceAll(

"<(/)?([a-zA-Z]*)(\\s[a-zA-Z]*=[^>]*)?>", ""); 


if (length != null && length.intValue() > 0 &&

content.length() > length.intValue()) {

content = content.substring(0, length.intValue()); 

if (trail != null) {

content = content + trail;

}

}

%>

<c:set var="result" value="<%=content%>"/>


2) removehtmlVar.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="tf" tagdir="/WEB-INF/tags" %>


<html>

<head><title>removeHtml variable 디렉티브</title></head>

<body>

<c:set var="dateEL" value="<%= new Date() %>" />

<tf:removehtml trim="true">

  <font size="10"> 현재 <style>시간</style>은 ${dateEL} 입니다. </font>

</tf:removehtml>

<br />

처리결과 : ${removed}

</body>

</html>





'JSP' 카테고리의 다른 글

실습:필터 (web.xml 이용)  (0) 2016.03.18
필터  (0) 2016.03.18
실습: 자바빈을 코어태그로 불러오기  (0) 2016.03.16
JSTL (JSP Standard Tag Library)  (0) 2016.03.15
표현 언어 (Expression Language)  (0) 2016.03.14
Posted by netyhobby
,