커스텀 태그
사용자 정의 태그를 만들어서 사용할 수 있다.
사용 방법은 EL에서 함수를 만드는 방법과 유사하나 조금 더 복잡한 부면이 있다.
커스텀 태그를 만들기 위해서는 tld 파일과 java class 파일이 필요하다.
예제로 유저에게 랜덤하게 조언을 해 주는 커스텀 태그 소스를 보면 이해하는데 도움이 된다.(소스는 역시 Head & First Servelet & JSP에서 사용된 것이다.)
우선 tld 파일은 EL과 마찬가지로 WEB-INF 밑에 작성한다. 이름은 myCustomTag.tld로 한다.
<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>0.9</tlib-version>
<short-name>RandomTags</short-name>
<function>
<name>rollIt</name>
<function-class>com.example.DiceRoller</function-class>
<function-signature>int rollDice()</function-signature>
</function>
<uri>randomThings</uri>
<tag>
<description>random advice</description>
<name>advice</name>
<tag-class>com.example.AdvisorTagHandler</tag-class>
<body-content>empty</body-content>
<attribute>
<name>user</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
</tag>
</taglib>
태그 이름은 <name> 태그의 내용을 사용하며 해당 태그가 호출될 경우 사용하는 java class 파일은 <tag-class> 태그에 있는 클래스를 사용한다.
<body-content>가 empty인 것은 몸체가 없이 사용한다는 뜻이며, 속성으로 사용되는 것으로 user라는 것이 있다는 의미이다.
rtexprvalue가 true인 것은 EL과 같은 표현식(스크립팅, 표준액션 포함) 값이 들어갈 수 있다는 뜻이다. 만일 rtexprvalue가 false라면 EL 표현식은 사용 불가이다.
위 내용을 jsp 페이지에서 커스텀 태그로 사용한다면 아래와 같이 사용할 수 있다.
<c:set var="userName" value="오봉근"></c:set>
<mine:advice user="${userName}" />
위와 같이 쓰게 된다면 AdvisorTagHandler 클래스에서는 user라는 변수를 사용하여 어떤 액션을 하게 될 것이다.
AdvisorTagHandler 클래스의 소스는 아래와 같다.
package com.example;
import java.io.IOException;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.SimpleTagSupport;
public class AdvisorTagHandler extends SimpleTagSupport {
private String user;
public void doTag() throws JspException, IOException {
getJspContext().getOut().write("Hello " + user + " <br>");
getJspContext().getOut().write("Your advice is : " + getAdvice());
}
public void setUser(String user) {
this.user = user;
}
String getAdvice() {
String[] adviceStrings = {"That color's not working for you", "You should call in sick", "You might want to rethink that haircut."};
int random = (int) (Math.random() * adviceStrings.length);
return adviceStrings[random];
}
}
위 클래스에서 주의 해야 할 점은 doTag 메소드이다.
JSP가 태그를 실행하게 되면 컨테이너는 자동으로 doTag 메소드를 실행하게 된다. EL에서 메소드 명을 지정할 수 있었던 것과 다르다.
또 주의해서 볼 것은 setUser 메소드이다. 이름에서 볼 수 있듯이 자바 빈 프로퍼티 명명 규칙을 따서 사용하게 된다. 즉 커스텀 태그에서 사용하는 attribute의 이름을 빈 프로퍼티로 사용하게 된다.
태그 몸체에 들어갈 수 있는 내용들은 아래와 같다.
=> 몸체를 가질 수 없다.
<body-content>scriptless</body-content>
=> 스크립팅(스크립틀릿, 스크립팅 표현식, 선언문)은 올 수 없다. 하지만 템플릿 텍스트, EL, 커스텀 태그, 표준 액션은 가능하다.
<body-content>tagdependent</body-content>
=> 태그 몸체를 그냥 텍스트로 취급한다.
<body-content>JSP</body-content>
=> JSP 안에 들어갈 수 있는 것이라면 무엇이든지 가능하다.
<body-content>empty</body-content>라고 되어 있어도 jsp 표준액션을 사용하면 body에 내용을 기술 할 수 있다.
<jsp:attribute name="user">${userName}</jsp:attribute>
</mine:advice>
<jsp:attribute> 태그는 속성을 기술하는 또 하나의 방식이므로, body content 개수로 치지 않으며, 따라서 시작 태그와 마침 태그에 들어갈 수 있다.
taglib에 들어가는 uri는 실제 uri(위치정보)가 아니다. 다른 태그 라이브러리와 구별하기 위한 유일한 값을 지정하기 위해 사용하는 이름일 뿐이다.
uri와 실제 TLD 파일은 컨테이너가 알아서 맵핑한다. 하지만 jsp 2.0 이전 버젼에서는 web.xml에 맵핑 정보를 적어 줘야 했었다.
<taglib>
<taglib-uri>randomThings</taglib-uri>
<taglib-location>/WEB-INF/</taglib-location>
</taglib>
</jsp-config>
jsp 2.0 버전에서는 사용하지 않아도 컨테이너가 알아서 uri 이름에 대한 맵을 만든다는 의미이지, 위 내용을 web.xml에 기술 안해야지만 된다는 의미는 아니다. web.xml에 기술을 하게 된다면 해당 내용을 사용하게 되며, 없을 경우 자동으로 searching을 하게 된다.
컨테이너가 자동으로 TLD 파일을 찾는 위치는 다음과 같다.
2. WEB-INF 아래 하위 디렉토리
3. WEB-INF/lib 밑에 jar 파일로 배포 했다면 jar 안 META-INF 디렉토리
4. WEB-INF/lib 밑에 jar 파일로 배포 했다면 jar 안 META-INF 아래 하위 디렉토리
jsp에서 여러개의 태그라이브러리를 사용한다면, 각각의 TLD에 대한 uri를 작성해야 한다. uri는 유일해야 하며, 같은 값을 중복해서 사용할 수 없다.
또한 예약어를 첨자로 사용할 수 없다.
출처 - http://www.4te.co.kr/566