12 ███████████ 12
Powered by http://www.jabook.org 이 명 진, 최 영 관 Powered by http://www.jabook.org 2nd Edition 소설같은 JSP 12장 부록 : 커스텀 태그
12.1 커스텀 태그 소개
12.1.1 커스텀 태그 커스텀 태그(Custom Tag)란? 태그 라이브러리(Tag Library) 커스텀 태그의 장점 사용자가 직접 정의해서 사용하는 태그 태그 라이브러리(Tag Library) 사용자가 정의한 커스텀 태그들을 모아 라이브러리 형태로 만든 것 커스텀 태그의 장점 한번 작성한 커스텀 태그는 어디서든 사용 가능하다. JSP 페이지 내에 스크립트 코드를 줄임으로써 가독력을 높일 수 있다. 태그 라이브러리를 잘 정의함으로써 JSP를 모르는 디자이너도 쉽게 동적인 페이지를 만들 수 있다. JSP 차원에서 지원하는 커스텀 태그가 바로 액션 태그이다.
12.1.2 태그 라이브러리의 구성 태그 핸들러 클래스(Tag Handler Class) 커스텀 태그의 기능을 정의한 클래스 태그 라이브러리 서술파일(Tag Library Descriptor, TLD) XML 표준을 따르는 XML 형식의 문서 커스텀 태그를 정의하고 태그 핸들러 클래스와 연결하여 처리를 실행 태그를 사용하는 JSP 파일 사용할 TLD를 정의하고 커스텀 태그를 사용 2 TDL에 등록 TLD(Tag Library Descriptor) 태그 라이브러리 URI 지정 및 커스텀 태그 사용 3 접두어와 name으로 해당 클래스 호출 4 JSP Tag Handler Class 1 태그 핸들러 클래스 작성 5 해당 태그 처리 및 결과 반환
12.2 간단한 커스텀 태그의 구현
12.2.1 태그 핸들러 클래스 태그 핸들러 클래스(Tag Handler Class) 커스텀 태그 구현 절차 태그 핸들러 클래스 작성 TLD 작성 태그 핸들러 클래스(Tag Handler Class) 커스텀 태그의 동작을 정의한 클래스 태그 핸들러 클래스 구현을 위한 자바 클래스 태그 라이브러리 등록 커스텀 태그 사용 JspTag Interface Body 내용을 처리하지 않는 간단한 태그를 만들 때 extends extends Tag Interface SimpleTag Interface implements extends implements TagSupport Class IterationTag Interface SimpleTagSupport Class implements extends BodyTagSupport Class BodyTag Interface Body 내용을 처리하는 태그를 만들 때
12.2.2 Tag 인터페이스를 이용한 구현 Tag 인터페이스 Tag 인터페이스를 이용한 구현 커스텀 태그의 기능을 정의하기 위한 기본적인 프로토콜과 메소드를 제공하는 인터페이스 Tag 인터페이스를 이용한 구현 Tag 인터페이스에 정의되어 있는 모든 메소드를 정의해서 구현 JSP 페이지에서 커스텀 태그를 만나면 doStartTag()와 doEndTag() 메소드가 자동으로 호출된다. public class HelloTagUseInterface implements Tag { public int doStartTag() throws JspException { ... } public int doEndTag() throws JspException { ... } public void release() { ... } public void setPageContext(PageContext pg) { ... } public void setParent(Tag p) { ... } public Tag getParent() { ... } } public int doStartTag() throws JspException { ... } 시작 태그를 만났을 때 호출되는 메소드 public int doEndTag() throws JspException { ... } 종료 태그를 만났을 때 호출되는 메소드
12.2.3 TagSupport 클래스를 이용한 구현 TagSupport 클래스 TagSupport 클래스를 이용한 구현 Tag 인터페이스와 IteratorTag 인터페이스가 구현된 클래스 커스텀 태그를 이용하는데 기본이 되는 클래스 TagSupport 클래스를 이용한 구현 필요한 메소드만 정의해서 사용하면 된다. TagSupport 클래스를 이용하면 필요한 메소드만 정의해서 구현하면 되기 때문에 인터페이스를 이용하는 것보다 편하다. public class HelloTag extends TagSupport { public int doStartTag() throws JspException { ... } public int doEndTag() throws JspException { ... } }
12.2.4 태그 라이브러리 서술파일 태그 라이브러리 서술파일 (Tag Library Descriptor, TLD) 커스텀 태그 구현 절차 태그 핸들러 클래스 작성 TLD 작성 태그 라이브러리 서술파일 (Tag Library Descriptor, TLD) XML 문서 형태로 작성 커스텀 태그의 이름과 태그의 기능이 구현된 태그 핸들러를 연결하는 역할 TLD의 작성 TDL 파일의 <tag> 태그를 이용해서 하나의 커스텀 태그를 정의 TLD의 저장 어디에 저장해도 상관없지만 일반적으로 WEB-INF 디렉터리 하위에 저장한다. 태그 라이브러리 등록 커스텀 태그 사용 필자는 /WEB-INF 하위에 tlds라는 폴더를 만들어서 그곳에 저장하였다.
12.2.5 태그 라이브러리의 정보 설정 커스텀 태그 구현 절차 태그 핸들러 클래스 작성 TLD 작성 web.xml 태그 라이브러리 사용을 위한 정보를 web.xml 파일의 루트 엘리먼트인 <web-app> 엘리먼트 하위에 추가한다. 태그 라이브러리 등록 커스텀 태그 사용 <web-app> ... <taglib> <taglib-uri> 태그 라이브러리 구분을 위한 식별자 </taglib-uri> <taglib-location> TLD 파일의 위치 </taglib-location> </taglib> </web-app> <web-app> ... <taglib> <taglib-uri>http://localhost/hellotag</taglib-uri> <taglib-location>/WEB-INF/tlds/HelloTag.tld</taglib-location> </taglib> </web-app>
12.2.6 커스텀 태그의 사용 커스텀 태그의 지시문 선언 커스텀 태그의 사용 커스텀 태그 구현 절차 태그 핸들러 클래스 작성 TLD 작성 커스텀 태그의 지시문 선언 커스텀 태그의 사용 태그 라이브러리 등록 커스텀 태그 사용 <%@taglib uri="http://localhost/hellotag" prefix="novel"%> web.xml에 정의된 태그 라이브러리 식별자 커스텀 태그의 접두어 정의 < : /> novel hello TLD에 정의된 태그 이름 휴~
12.3 다양한 형태의 커스텀 태그
12.3.1 어트리뷰트를 갖는 커스텀 태그 (1) 태그 핸들러 클래스 작성 TLD 작성 어트리뷰트 이름으로 된 setter 메소드를 작성 TLD 작성 커스텀 태그를 정의하는 <tag> 엘리먼트 하위에 어트리뷰트를 선언 <novel:welcome name="Grace" /> public class WelcomeTag extends TagSupport { private String name = ""; public void setName(String name) { this.name = name; } 커스텀 태그의 어트리뷰트 이름에 맞는 setter 메소드를 작성함으로써 어트리뷰트를 갖는 커스텀 태그를 지원할 수 있다. <tag> ... <attribute> <name> name </name> <required> true </required> <type> java.lang.String </type> </attribute> </tag> <type> 엘리먼트를 생략할 경우 기본 값은 String이다. 어트리뷰트의 이름 어트리뷰트의 사용 여부 어트리뷰트의 데이터 타입
12.3.2 어트리뷰트를 갖는 커스텀 태그 (2) 태그 라이브러리의 정보 설정 - web.xml 커스텀 태그의 사용 커스텀 태그의 지시문 선언 <taglib> <taglib-uri>http://localhost/welcometag</taglib-uri> <taglib-location>/WEB-INF/tlds/WelcomeTag.tld</taglib-location> </taglib> 커스텀 태그의 어트리뷰트를 만나면 태그 핸들러 클래스의 setter 메소드가 호출된다. <%@taglib uri="http://localhost/welcometag" prefix="novel"%> web.xml에 정의된 태그 라이브러리 식별자 커스텀 태그의 접두어 정의 <novel:welcome /> name="Grace" nation="America" 커스텀 태그의 어트리뷰트
<novel:fontMagic>기본 값 글자</novel:fontMagic> 12.3.3 내용을 갖는 커스텀 태그 태그 핸들러 클래스 작성 doStartTag() 메소드의 리턴 값 SKIP_BODY : 커스텀 태그의 내용을 무시하고 doEndTag() 메소드를 호출 EVAL_BODY_INCLUDE : 커스텀 태그의 내용을 포함하여 처리 doEndTag() 메소드의 리턴 값 EVAL_PAGE : 종료 태그 이후의 나머지 코드를 실행 커스텀 태그의 사용 doStartTag() 메소드의 리턴 값을 EVAL_BODY_INCLUDE로 지정하면 커스텀 태그의 내용을 포함하여 처리한다. <novel:fontMagic>기본 값 글자</novel:fontMagic> <novel:fontMagic color="blue" size="5">파란색 글자 5</novel:fontMagic> <novel:fontMagic color="red" size="7">빨강색 글자 7</novel:fontMagic> <novel:fontMagic>기본 값 글자</novel:fontMagic> <tag> <name>fontMagic</name> <tag-class>customtags.FontMagicTag</tag-class> <attribute> <name>color</name> <required>false</required> </attribute> <name>size</name> </tag> TLD에서 어트리뷰트 정의 시 <required>의 값을 false로 선언했기 때문에 어트리뷰트를 사용하지 않아도 된다.
12.3.4 내용을 반복하는 커스텀 태그 태그 핸들러 클래스 작성 doAfterBody() 메소드 커스텀 태그의 내용을 처리한 후 호출되는 메소드 doAfterBody() 메소드의 리턴 값 EVAL_BODY_AGAIN 다시 커스텀 태그의 내용을 처리하기 위한 상수 <novel:repeatBody repeat="5"> 반복되는 커스텀 태그 작성 </novel:repeatBody> public class RepeatTag extends TagSupport { public int doStartTag() { return EVAL_BODY_INCLUDE; } public int doAfterBody() { if(반복 조건) return EVAL_BODY_AGAIN ; else return SKIP_BODY; 커스텀 태그의 내용이 처리된 후 doAfterBody() 메소드 호출 doAfterBody() 내용을 다시 처리 EVAL_BODY_AGAIN EVAL_BODY_AGAIN은 커스텀 태그의 내용을 다시 처리하라는 의미이다. 따라서 커스텀 태그의 내용이 처리된 후 다시 doAfterBody() 메소드가 호출된다. 태그의 내용이 처리된 후 호출되는 메소드이다. 내용 처리 종료
12.3.5 BodyTagSupport 클래스 BodyTagSupport 클래스 커스텀 태그의 내용을 수정해서 출력해야 할 경우에 사용 내용을 처리하기 위한 BodyTagSupport 클래스의 메소드 getBodyContent() 메소드 BodyContent getBodyContent() 커스텀 태그의 내용을 리턴한다. BodyContent 클래스 JspWriter를 상속 받은 클래스 커스텀 태그의 내용을 처리할 수 있는 다양한 형태의 메소드를 제공
12.3.6 BodyTagSupport 클래스의 활용 doStartTag() 메소드의 리턴 값 EVAL_BODY_BUFFERED 커스텀 태그의 내용을 담은 버퍼를 생성한다. 내용을 처리하기 위한 이벤트 메소드 구현 doAfterBody()나 doEndTag() 메소드를 이용해서 구현 public class UseContentsTag extends BodyTagSupport { } BodyTagSupport 클래스는 커스텀 태그의 내용을 가져와서 수정을 가한 후 출력하고자 할 경우 이용한다. public int doStartTag() throws JspException { return EVAL_BODY_BUFFERED; } <novel:editBody> 123456789 </novel:editBody> public int doEndTag() throws JspException { // doAfterBody() BodyContent body = getBodyContent(); String content = body.getString(); ... } String content = body.getString();
End ███████████ End