Java/Servlet & JSP

사용자 정의 태그 개발 (1)

체리필터 2009. 3. 23. 15:26
728x90
반응형
<jsp:include> 표준 액션 또는 <c:import> JSTl과 같은 기능을 하는 태그 파일을 만들어 보자.

<img src="http://wstatic.naver.com/w9/lg_naver_v3.gif"><br>

위와 같이 코딩 한 후 WEB-INF 아래 tags란 디렉토리를 만들어 Header.tag 파일로 저장한다.
그리고 난 후 우리가 url에 호출할 파일을 만들어 보자.

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib prefix="myTags" tagdir="/WEB-INF/tags" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<myTags:Header></myTags:Header>
Welcome to our site.
</body>
</html>

위와 같이 만든 다음 DocumentRoot 아래 customTag란 디렉토리 안에 customTag.jsp란 파일로 만들었다.
브라우져에 http://localhost:8080/customTag/customTag.jsp를 호출하면 아래와 같은 모습이 보여진다.


위에서 <myTags:Header></myTags:Header> 라고 사용한 부분을 보면 파일명이 바로 Tag 명이 된 것을 알 수 있다.
또한 <jsp:include> 표준액션에서 param을 사용한 것처럼 사용할 수 있다.

customTag.jsp

<jsp:include page="Header.jsp">
    <jsp:param name="subTitle" value="We take the sting out of SOAP"/>
</jsp:include>

Header.jsp

<img src="http://wstatic.naver.com/w9/lg_naver_v3.gif"><br>
<em><strong>${param.subTitle}</strong></em>

표준 액션을 사용하면 위와 같이 할 수 있다. 태그를 사용하면 아래와 같이 사용하면 된다.

customTag.jsp

<myTags:Header subTitle="We take the sting out of SOAP" />
Welcome to our site.

Header.tag

<%@ attribute name="subTitle" required="true" rtexprvalue="true" %>
<img src="http://wstatic.naver.com/w9/lg_naver_v3.gif"><br>
<em><strong>${subTitle}</strong></em>

attribute로 넘어온 값은 param 이라는 이름 없이 ${subTitle} 과 같이 바로 사용하면 된다. 또한 사용하기 위해서는 상단에 "<%@ attribute name="subTitle" required="true" rtexprvalue="true" %>" 와 같이 attribute 정의를 해 놔야 한다.
tld에 정의한 바와 같이 required는 필수 여부, rtexprvalue는 표현식 사용 여부를 나타내는 것이다.

속성으로 넘겨야 할 내용이 길다면 다음과 같이 사용할 수 있다.

customTag.jsp

<myTags:Header fontColor="#660099" subTitle="We take the sting out of SOAP">
Welcome to our site.
Welcome to our site.
Welcome to our site.
Welcome to our site.
Welcome to our site.
Welcome to our site.
Welcome to our site.
Welcome to our site.
Welcome to our site.
</myTags:Header>

Header.tag

<%@ attribute name="fontColor" required="true" %>
<%@ tag body-content="tagdependent" %>

<em><strong><font color="${fontColor}"><jsp:doBody></jsp:doBody></font></strong></em>

body-content에 들어가는 내용은 tld 정의에서 배운 내용 그대로이다.

컨테이너가 태그 파일을 찾는 위치는 4군데이다.

1. WEB-INF/tags 바로 밑
2. WEB-INF/tags의 하위 디렉토리
3. WEB-INF/lib에 JAR 파일로 배포되었다면, JAR파일 META-INF/tags 밑에
4. WEB-INF/lib에 JAR 파일로 배포되었다면, JAR파일 META-INF/tags의 하위 디렉토리

태그 파일이 JAR 파일로 배포 되었다면, 반드시 TLD 파일이 있어야 한다.

태그 파일만으로 부족할 경우에는 자바 클래스를 이용한 사용자 정의 태그를 만들 수 있다. http://www.4te.co.kr/566에서 이미 만들어 본 내용이지만 다시 한번 정리하면 아래와 같다.

package com.example;

import java.io.IOException;

import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.SimpleTagSupport;

public class simpleTagTest1 extends SimpleTagSupport {
    public void doTag() throws JspException, IOException {
        getJspContext().getOut().print("This is the lamest use of a custom tag");
    }
}

/WEB-INF/simpleTag.tld

<?xml version="1.0" encoding="UTF-8"?>

<taglib xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee/web-jsptaglibrary_2_0.xsd" version="2.0">

<tlib-version>1.2</tlib-version>
<uri>simpleTags</uri>
<tag>
    <description>worst use of a custom tag</description>
    <name>simple1</name>
    <tag-class>com.example.simpleTagTest1</tag-class>
    <body-content>empty</body-content>
</tag>

</taglib>

/customTag/customTag2.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib prefix="myTags" uri="simpleTags" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<myTags:simple1/>
</body>
</html>

설명은 http://www.4te.co.kr/566 에서 설명한 내용을 참고하면 된다.
몸체가 있는 태그일 경우에는 아래와 같이 하면 된다.

package com.example;

import java.io.IOException;

import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.SimpleTagSupport;

public class simpleTagTest1 extends SimpleTagSupport {
    public void doTag() throws JspException, IOException {
        //getJspContext().getOut().print("This is the lamest use of a custom tag");
        getJspBody().invoke(null);    //태그 몸체를 읽은 후 응답에 출력하라는 의미, 인자가 null이므로 Response로 출력하라는 의미
    }
}

<?xml version="1.0" encoding="UTF-8"?>

<taglib xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee/web-jsptaglibrary_2_0.xsd" version="2.0">

<tlib-version>1.2</tlib-version>
<uri>simpleTags</uri>
<tag>
    <description>worst use of a custom tag</description>
    <name>simple1</name>
    <tag-class>com.example.simpleTagTest1</tag-class>
    <body-content>scriptless</body-content>
</tag>

</taglib>

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib prefix="myTags" uri="simpleTags" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<myTags:simple1>
    This is the body
</myTags:simple1>
</body>
</html>

태그 몸체에 표현식이 있을 경우에는 다음과 같이 할 수 있다.

<myTags:simple1>
    This is the body ${message}
</myTags:simple1>

public class simpleTagTest1 extends SimpleTagSupport {
    public void doTag() throws JspException, IOException {
        //getJspContext().getOut().print("This is the lamest use of a custom tag");
        getJspContext().setAttribute("message", "Wear sunscreen");
        getJspBody().invoke(null);
    }
}

동적으로 테이블 행을 출력하는 태그를 만들어 보면 아래와 같이 하면 된다.

public class simpleTagTest1 extends SimpleTagSupport {
    String[] movies = {"Monsoon Wedding", "Saved!", "Fahrenheit 9/11"};
    public void doTag() throws JspException, IOException {
        //getJspContext().getOut().print("This is the lamest use of a custom tag");
        //getJspContext().setAttribute("message", "Wear sunscreen");
       
        for(int i=0 ; i<movies.length ; i++) {
            getJspContext().setAttribute("movie", movies[i]);
            getJspBody().invoke(null);
        }
    }
}

<table>
<myTags:simple1>
    <tr><td>${movie}</td></tr>
</myTags:simple1>
</table>

태그 속성이 반드시 있어야 한다고 TLD에서 설정했다면, 태그핸들러 클래스에서는 Bean 스타일의 Setter가 있어야 한다.

<%@ taglib prefix="myTags" uri="simpleTags5" %>
<myTags:simple1 movieList="${movieCollection}">
    <tr>
        <td>${movie.name}</td>
        <td>${movie.gener}</td>
    </tr>
</myTags:simple1>

package com.example;

import java.io.IOException;
import java.util.Iterator;
import java.util.List;

import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.SimpleTagSupport;

public class simpleTagTest5 extends SimpleTagSupport {
    private List<String> movieList;

    public void setMovieList(List<String> movieList) {
        this.movieList = movieList;
    }
   
    public void doTag() throws JspException, IOException {
        Iterator<String> i = movieList.iterator();
       
        while(i.hasNext()) {
            Movie movie = (Movie) i.next();
            getJspContext().setAttribute("movie", movie);
            getJspBody().invoke(null);
        }
    }
}

<?xml version="1.0" encoding="UTF-8"?>

<taglib xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee/web-jsptaglibrary_2_0.xsd" version="2.0">

<tlib-version>1.2</tlib-version>
<uri>simpleTags5</uri>
<tag>
    <description>worst use of a custom tag</description>
    <name>simple1</name>
    <tag-class>com.example.simpleTagTest5</tag-class>
    <body-content>scriptless</body-content>
    <attribute>
        <name>movieList</name>
        <required>true</required>
        <rtexprvalue>true</rtexprvalue>
    </attribute>
</tag>

</taglib>


어떤 태그를 호출 했을 경우, 오류가 떨어지더라도 지금까지 출력 된 내용은 화면에 나와야 한다면 SkipPageException을 사용할 수 있다.

getJspContext().getOut().print("Message from within doTag()<br>");
getJspContext().getOut().print("About to throw a SkipPageException");

if(thingsDontWork) {
    throw new SkipPageException();
}

<myTags:simple/>
Back in the page after invoking the tag.

위 클래스에서 thingsDontWork가 참이라서 SkipPageException이 던져지게 되면, 그 이전에 출력하려 했던 "Message from within doTag()<br>About to throw a SkipPageException은 나오지만, "Back in the page after invoking the tag."은 출력되지 않는다.

다음과 같이 하게 됬을 경우 나오게 되는 내용에 주의해야 한다.

pageA.jsp

aaaa<br>
<jsp:include page="pageB.jsp"></jsp:include>
after aaaa<br>

pageB.jsp

<%@ taglib prefix="myTags" uri="simpleTags" %>
bbbb<br>
<myTags:simple1></myTags:simple1>
after bbbb<br>

doTag() 메소드

    public void doTag() throws JspException, IOException {
        getJspContext().getOut().print("in doTag()<br>");
        throw new SkipPageException();
    }

pageB 안에 있는 myTags.simple1 태그는 doTag() 메소드를 호출 할 것이며 doTag 메소드에서는 SkipPageException을 throw 할 것이다.
이럴 경우에는 pageB.jsp에서만 처리가 중지 되며, pageA.jsp에서는 그대로 나머지 내용이 출력된다.
즉 다음과 같이 내용이 나오게 될 것이다.

aaaa
bbbb
in doTag()
after aaaa

즉, after bbbb 라는 내용은 나오지 않게 된다.


728x90
반응형

'Java > Servlet & JSP' 카테고리의 다른 글

부모 자식 태그간의 통신  (0) 2009.03.26
클래식 커스텀 태그  (0) 2009.03.26
커스텀 태그 사용하기  (0) 2009.03.17
JSTL 사용하기 (2)  (0) 2009.03.16
JSTL 사용하기 (1)  (5) 2009.03.12