IBM Korea Skip to main content
       IBM 홈    |  제품 & 서비스  |  고객지원 & 다운로드  |  회원가입  

IBM developerWorks > 자바
developerWorks

JSP best practices : JSP 태그용 커스텀 애트리뷰트 만들기
태그 기능을 사용자 정의 애트리뷰트로 확장하기

Level: Introductory

Brett McLaughlin
Author, O'Reilly and Associates
2003년 8월 5일

Column icon커스텀 타임-스탬프를 확장하여 페이지 작성자가 자신의 타임-스탬프 포맷을 선택할 수 있도록 하는 방법을 설명한다.

지난 시간에는 JSP 페이지에서 커스텀 태그 라이브러리의 기본적인 사용 방법을 설명했다. 간단한 태그를 정의하고 태그 라이브러리 디스크립터(TLD)를 통해 다른 JSP 작성자까지 사용 할 수 있도록 만들었다. 이번 주에는 커스텀 태그에 대해 알고 있는 지식에 기반하여 구현을 할 것이다. 여기에서 사용할 예제 태그는 매우 간단하다. 따라서 커스텀 애트리뷰트를 결합하여 기능을 확장할 것이다.

예제에 대하여: 이 글에 사용된 모든 예제 코드는 지난 번 우리가 개발한 lastModified 태그에 기반하여 구현된다.

"Hello, world" 커스터마이징
JSP 태그의 가장 일반적인 요구사항은 페이지로부터 오는 데이터를 받아들이고 그 데이터에 응답할 수 있어야 한다는 것이다. 태그 애트리뷰트로 이 기능을 우리의 커스텀 태그에 결합할 수 있다.

간단한 예제로 "Hello, world" 애플리케이션을 들어보겠다. 이 스크립틀릿의 기능을 구현하는 커스텀 태그를 상상하는 것은 쉽지만 이를 어떻게 확장할 것인가?

Listing 1은 전형적인 "Hello, world!"를 결합한 JSP 페이지이다. name이라고 하는 애트리뷰트를 포함하고 있는 태그이다:

Listing 1. "Hello, world!" 태그

<p>
    <examples:hello name="Reader" />
</p>

name 애트리뷰트는 페이지 작성자가 hello 태그에 데이터를 공급할 수 있는 곳에 공간을 만든다. 이 경우 사람의 이름은 애플리케이션이 보내는 메시지를 받을 사람이다. Listing 2는 hello 태그를 구현하는 자바 코드이다:

Listing 2. hello 태그용 코드

package com.ibm.examples;

import java.io.IOException;
import javax.servlet.jsp.*;
import javax.servlet.jsp.tagext.*;

public class HelloTag extends TagSupport {

    // The "person" to say hello to
    private String name;

    // Accept the attribute data
    public void setName(String name) {
      this.name = name;
    }

    public int doEndTag() {
      try {
	  StringBuffer message = new StringBuffer("Hello, ");
	  message.append(name)
	         .append("!");
	  pageContext.getOut().println(message.toString());
	} catch (IOException ignored) { }
	return EVAL_PAGE;
    }

Listing 2의 코드는 매우 단순하다. setXXX() 메소드를 추가했다. XXX에는 애트리뷰트 이름이 들어간다. 보기에는 간단하지만 태그의 기능을 크게 확장한 것이다. 페이지 작성자는 특정 목적을 위해 커스텀 데이터를 설정할 수 있고 그 데이터는 저장, 조작, 활성화 될 수 있다. doEndTag() 메소드로는 필요한 어떤 방식으로든 태그 데이터를 사용할 수 있도록 한다.

lastModified 태그에 애트리뷰트를 추가할 때 어떻게 되는지 검토해보자.

lastModified 확장하기
페이지 작성자에게 단지 하나의 디스플레이 옵션을 주는 대신 원하는 대로 아웃풋 포맷팅을 설정할 수 있도록 하고 싶다. lastModifiedTag 클래스가 아웃풋 포맷팅을 위해 java.text.SimpleDateFormat을 포함하도록 확장시켜서 백엔드에서 시작하겠다. (Listing 3):

Listing 3. LastModifiedTag 클래스에서 SimpleDateFormat 사용하기

package com.newInstance.site.tags;

import java.io.File;
import java.io.IOException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.jsp.tagext.TagSupport;

public class LastModifiedTag extends TagSupport {

    private String format = "MMM d, yyyy";

    public int doEndTag() {
      try {
        HttpServletRequest request =
          (HttpServletRequest)pageContext.getRequest();
        String path = pageContext.getServletContext().getRealPath(
          request.getServletPath());
        File file = new File(path);

        DateFormat formatter = new SimpleDateFormat(format);

        pageContext.getOut().println(
          formatter.format(new Date(file.lastModified())));
      } catch (IOException ignored) { }
      return EVAL_PAGE;
    }
}

Listing 4에서는 새로운 포맷팅 기능을 태그로 가져왔다. format 애트리뷰트 값은 Listing 3에 적용된 새로운 format 메소드 변수에 어태치된다.

Listing 4. 새로운 애트리뷰트 핸들링하기

package com.newInstance.site.tags;

import java.io.File;
import java.io.IOException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.jsp.tagext.TagSupport;

public class LastModifiedTag extends TagSupport {

    private String format = "MMM d, yyyy";

    public void setFormat(String format) {
      this.format = format;
    }

    public int doEndTag() {
      try {
        HttpServletRequest request = 
          (HttpServletRequest)pageContext.getRequest();
        String path = pageContext.getServletContext().getRealPath(
          request.getServletPath());
        File file = new File(path);

        DateFormat formatter = new SimpleDateFormat(format);

        pageContext.getOut().println(
          formatter.format(new Date(file.lastModified())));
      } catch (IOException ignored) { }
      return EVAL_PAGE;
    }
}

구현 상세
format 애트리뷰트로 페이지 작성자는 날짜/시간 아웃풋 포맷을 원하는 대로 설정할 수 있다. 하지만 이 새로운 애트리뷰트를 사용하기 전에 TLD 파일을 약간 변경해야한다. (Listing 5):

Listing 5. TLD 수정하기

<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE taglib
    PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.2/EN"
           "http://java.sun.com/dtd/web-jsptaglibrary_1_2.dtd" >

<taglib>
    <tlib-version>1.0</tlib-version>
    <jsp-version>1.2</jsp-version>
    <short-name>site-utils</short-name>
    <uri>http://www.newInstance.com/taglibs/site-utils</uri>

    <tag>
      <name>lastModified</name>
      <tag-class>com.newInstance.site.tags.LastModifiedTag</tag-class>
      <body-content>empty</body-content>
      <attribute>
        <name>format</name>
      </attribute>
    </tag>
</taglib>

디폴트 값
TLD를 업데이트 할 때, 새로운 애트리뷰트를 사용해야만 한다. 테스트도 필수이다. 서블릿 컨테이너를 재시작하여 이것이 새로운 태그와 TLD 변화를 감지했는지를 확인하고 여기에 lastModified 태그로 페이지를 작동시킨다.

당연히 타임 스탬프가 나타난다. 만일 여러분이 내가 보고있는 것을 보고있다면 아웃풋의 포맷팅은 전과 같다. 문제는 어떤 새로운 format 값도 추가되지 않았다는 점이다. 따라서 예전과 같은 것을 보고있는 것이 된다. 이 작은 테스트 실행으로 format 애트리뷰트에 디폴트 값을 추가하는 것이 얼마나 중요한일인지 알게된다.

커스텀 애트리뷰트에 디폴트 값을 주는 것은 좋은 생각이다. 왜냐하면 페이지 작성자가 고유의 값을 제공하고 싶지 않을 때 곤경에 처하지 않기 때문이다. 때로는 새로운 애트리뷰트와 포맷을 배우는데 시간이 필요하고 그 사이 디폴트는 훌륭한 대리인이 되는 것이다.

맺음말
Listing 6 은 타임 스탬프 예제("JSP best practices : 타임 스탬프의 힘" 참조)의 footer.jsp 이다. format 애트리뷰트에 값이 제공되었다:

Listing 6. 포맷 애트리뷰트 사용하기

<%@ taglib prefix="site-utils"
             uri="http://www.newInstance.com/taglibs/site-utils"%>

          </td>
          <td width="16" align="left" valign="top"> </td>
    </tr>
    <!-- End main content -->

<!-- Begin footer section -->
    <tr>
      <td width="91" align="left" valign="top" bgcolor="#330066"> </td>
      <td align="left" valign="top"> </td>
      <td class="footer" align="left" valign="top"><div align="center"><br>
          &copy; 2003 
          <a href="mailto:webmaster@newInstance.com">Brett McLaughlin</a><br>
          Last Updated: <site-utils:lastModified 
            format="HH:mm a zz :: MM/dd/yyyy"/>
        </div></td>
          <td align="left" valign="top"> </td>
      <td width="141" align="right" valign="top" bgcolor="#330066"> </td>
    </tr>
</table>
<!-- End footer section -->

참고자료

목 차:
"Hello, world" 커스터마이징
lastModified 확장하기
구현 상세
디폴트 값
맺음말
참고 자료
필자 소개
기사에 대한 평가
관련 dW 링크:
JSP best practices series
커스텀 태그로 JSP 페이지 제어하기
JSP taglibs: Better usability by design
Subscribe to the developerWorks newsletter
US 원문 읽기
Also in the Java zone:
Tutorials
Tools and products
Code and components
Articles
필자소개
Photo of Brett McLaughlinBrett McLaughlin은 현재 자바 및 관련 기술을 이용하여 애플리케이션 기반구조 구현을 전문적으로 수행하고 있다. Brett은 Java Apache 프로젝트인 Turbine의 공동 창립자이다.
이 기사에 대하여 어떻게 생각하십니까?

정말 좋다 (5) 좋다 (4) 그저그렇다 (3) 수정보완이 필요하다(2) 형편없다 (1)

  회사소개  |  개인정보 보호정책  |  법률  |  문의