개발입문/Servlet&JSP

[헤드퍼스트 SERVLET&JSP] 10-1. 사용자정의 태그 개발

haloaround 2017. 3. 5. 13:05



학습목표

태그 파일
심플 태그
클래식 태그

JspTag 인터페이스 에는 SimpleTag 인터페이스와 (그냥) Tag 인터페이스가 있습니다.
SimpleTag 인터페이스는 말그대로 심플 태그 핸들러를 생성할 때,
Tag 인터페이스는 클래식 태그 핸들러를 생성할 때 사용하니다.



태그 파일

(태그 핸들러 라이트)


가벼워서 light-


.tag : .jsp 의 파일 확장자만 다르게 한 것


- taglib 지시자 잘성: tagdir 로 자원 위치 정하고-

- 웹 컨테이너는 WEB-INF/tags 디렉토리에서 .tag 파일을 찾습니다.


- 단, 태그 속성은 생존범위가 태그입니다. 즉, 웹 어플리케이션의 다른 컴포넌트에서 이 값을 참조할 수는 없습니다.(요청을 포워딩할 때 포워딩되는 JSP나 서블릿도 모두 안됩니다.)


// JSP 태그 호출

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

...

<myTags:Header />


// Header.tag  태그 자체

<img src="images/Web-Services.jpg" >



// 태그 파일

// 태그속성 정의 (범위: 태그)

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


// 태그 몸체 형식 정의 (default = scriptless)

<%@ tag body-content="tagdependent" %>


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



컨테이너가 태그 파일을 찾는 곳

- WEB-INF/tags 밑 또는 하위 디렉토리에

- WEB-INF/lib 에 jar 파일로 배포되었다면 jar 파일 밑 META-INF/tags 밑 또는 하위 디렉토리에


단, 태그 파일이 jar 로 배포되었다면 반드시 이에 대응하는 TLD 파일이 있어야 합니다. 태그 파일에 대한 TLD 를 만든다면, 태그 파일과 커스텀 태그를 동일 라이브러리에 속한 녀석으로 간주합니다.

- <tag> 대신 <tag-file>를 입력할 뿐

<tag-file>

<name> <path>

</tag-file>



심플 커스텀 태그 핸들러

사용방법


1. 태그 핸들러

- javax.servlet.jsp.tagext.SimpleTagSupport 임포트 / 상속

- doTag() 메소드 구현


import javax.servlet.jsp.tagext.SimpleTagSupport;

...

public class SimpleTagTest1 extends SimpleTagSupport {

doTag() throws JspException, IOException {

getJspBody().invoke(null);

}


2. TLD 작성

<taglib ...>

<tlib-version>1.2</tlib-version>

<uri>simpleTags</uri>

<tag>

<description>simple custom tag</description>

<name>simple1</name>

<tag-class>foo.SimpleTagTest1</tag-class>

<body-content>scriptless</body-content>

</tag>

</taglib>


3. 태그 사용

<@% taglib prefix="myTags" uri="simpleTags" %>

<html><body>

<myTags:simple1>

This is the body.

<myTags:simple1/>

</html></body>




심플 태그 핸들러

라이프 사이클

1. 클래스 로드/인스턴스화

2. JspContext, 내장태그, 속성, 몸체 차례로 설정

3. doTag() 에 실제 실행할 코드를 항상 재정의




// 태그 사용 (사용하는 곳에서 출력)

<myTags:simple4>

<tr><td>${movie}</tr></td> 

</myTags:simple4>


//태그: 한번에 하나씩 attribute 설정

String [] movies = {"Monsoon Wedding", "Saved!", "Fahrenheight 9/11"};

public void doTag() throws JspException, IOException {

for (int i=0; i<movies.length; i++) {

getJspContext().setAttribute("movie",movies[i]);

getJspBody().invoke(null);

}

}




// 몸체 루핑

<myTags:simple5 movieList=${movieCollection}>

<tr><td>${movie.name}</tr></td> 

<tr><td>${movie.genre}</tr></td>

</myTags:simple4>




// 태그 핸들러 클래스

public ArrayList<Movie> movieList;

public void setMovieList(ArrayList<Movie> movieList) {

this.movieList =movieList;

}


public void doTag() throws JspException, IOException {

Iterator i = movieList.iterator();

while(i.hasNext()) {

Movie movie = (Movie) i.next();

getJspContext().setAttribute("movie", movie);

getJspBody().invoke(null);

}

}



// TLD 파일

<tag>

...

<attribute>

<name>movieList</name>

<required>true</required>

<rtexprvalue>true</rtexprvalue>

</attribute>

</tag>







음... 흔들리고 있다.

- 어떤 것은 출력한 값을 넘기고,

- 어떤 것은 attribute 로 지정한 후, 호출한 JSP 에서 출력하도록 한다. 

- 그런데 body-content 와 attribute 만 알면 되는건가?? 


복습이 필요한 시점이야...