Recent Posts
Recent Comments
Link
11-21 14:38
Today
Total
관리 메뉴

삶 가운데 남긴 기록 AACII.TISTORY.COM

클래스 기반 커스텀 태그 JSP 2.1 본문

DEV&OPS/Java

클래스 기반 커스텀 태그 JSP 2.1

ALEPH.GEM 2022. 7. 6. 14:45

커스텀 태그 JSP1.2 버전과의 차이점은 아래와 같습니다.

  • SimpleTag 인터페이스 추가
  • SimpleTagSupport 클래스 제공
  • doTag() 메소드로 태그 관련 메소드 통일
  • JspFragment를 이용한 body 전달
  • 동적 Attribute 추가 방법 제공

 

기본 예제

net.aacii.customTag 패키지에 MyCustomTag2.java 파일을 생서합니다.

package net.aacii.customTag;

import java.io.IOException;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.SimpleTagSupport;

public class MyCustomTag2 extends SimpleTagSupport {

	@Override
	public void doTag() throws JspException, IOException {
		System.out.println("커스텀 태그의 바디가 실행되기 전");
		getJspBody().invoke(null);
		System.out.println("커스텀 태그의 바디가 실행된 후");
	}
	
}

getJspBody()는 JspFragment 객체를 리턴합니다.

invoke(Writer)메소드는 커스텀 태그의 몸체에 있는 내용을 추출한 다음, invoke()메소드의 인자로 지정된 출력스트림에 추출된 내용을 출력합니다.

invoke()메소드를 기준으로 이전은 몸체가 실행되기 전, 이후는 몸체가 실행된 후 처리됩니다.

 

WEB-INF 폴더에 myTag2.tld 파일을 다음과 같이 작성합니다.

WEB-INF폴더에서 New->Other에서 XML을 선택한 후 Create XML file from an XML schema file 을 선택한 후 Select XML Catalog entry를 선택하고 목록에서 web-jsptaglibrary_2_1.xsd를 선택후 Namespace Informaiton에서 첫번째 항목을 선택하고 Edit 버튼을 누른 뒤 Prefix 항목의 값을 삭제한 후 OK버튼을 누릅니다.

<?xml version="1.0" encoding="UTF-8"?>
<taglib version="2.1" xmlns="http://java.sun.com/xml/ns/javaee" 
					  xmlns:xml="http://www.w3.org/XML/1998/namespace" 
					  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
					  xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-jsptaglibrary_2_1.xsd ">
  <tlib-version>1.0</tlib-version>
  <short-name>myTags2</short-name>
  <uri>http://myTags2.com</uri>
  
  <tag>
  	<name>second</name>
  	<tag-class>net.aacii.customTag.MyCustomTag2</tag-class>
  	<body-content>scriptless</body-content>
  </tag>
  
</taglib>

<short-name>은 현재 태그 라이브러리의 이름을 지정합니다.

JSP1.2에서는 TLD 파일과 JSP파일의 연결을 web.xml에 설정하여 사용했었지만 2.0부터는 TLD 파일이 WEB-INF 하위 경로에 있으면 자동으로 인식하므로 jsp 파일에서는 uri에서 지정한 값으로 선언해서 사용하면됩니다.

태그 이름은 second이고 연결된 태그 핸들러 클래스는 net.aacii.customTag 패키지의 MyCustomTag2입니다.

커스텀 태그의 내용에 대한 처리는 <body-content>에 scriptless로 지정했으므로 스크립트 태그를 사용할 수 없습니다.

 

WebContent 폴더에 ex24.jsp 파일을 작성합니다.

<%@ page language="java" contentType="text/html; charset=UTF-8"    pageEncoding="UTF-8"%>
<%@ taglib prefix="my2" uri="http://myTags2.com" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Custom Tag2</title>
</head>
<body>
	<my2:second>hello~ </my2:second>
	<br>
	Custom Tag 2 Test!
</body>
</html>

jsp 페이지에서 커스텀 태그를 사용하기 위해서 먼저 taglib 지시자(<%@ %>)에 TLD파일의 uri와 prefix(접두사) 값을 선언해야합니다. 

uri는 TLD 파일의 <uri>태그에서 설정했던 값을 지정해야 바르게 연결됩니다. 

 

 

몸체(body) 처리

먼저 MyCustomTag3.java 파일을 작성합니다.

package net.aacii.customTag;

import java.io.IOException;
import java.io.StringWriter;
import javax.servlet.jsp.JspContext;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.tagext.JspFragment;
import javax.servlet.jsp.tagext.SimpleTagSupport;

public class MyCustomTag3 extends SimpleTagSupport {

	@Override
	public void doTag() throws JspException, IOException {
		JspContext context = this.getJspContext();
		JspWriter out = context.getOut();
		
		JspFragment body = this.getJspBody();
		StringWriter sw = new StringWriter();
		body.invoke(sw);
		String str = sw.toString();
		out.print(str.toUpperCase());
		return;
	}
	
}

JspContext객체의 getOut()은 현재 jsp 페이지와 서비스를 요청한 클라이언트간에 연결된 출력스트림인 JspWriter를 추출하여 리턴하는 메소드입니다.

getJspBody()는 커스텀 태그의 몸체를 처리하는 JspFragment 객체를 추출하는 메소드입니다.

JspFragment객체의 invoke()는 커스텀 태그의 몸체를 추출합니다. 

invoke()의 인자값으로 sw가 지정되었으므로 추출된 커스텀 태그의 몸체를 sw에 출력합니다.

out.print()는 웹브라우저 쪽으로 출력합니다.

 

myTag2.tld 파일에 새로운 태그를 추가합니다.

<?xml version="1.0" encoding="UTF-8"?>
<taglib version="2.1" xmlns="http://java.sun.com/xml/ns/javaee" 
					  xmlns:xml="http://www.w3.org/XML/1998/namespace" 
					  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
					  xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-jsptaglibrary_2_1.xsd ">
  <tlib-version>1.0</tlib-version>
  <short-name>myTags2</short-name>
  <uri>http://myTags2.com</uri>
  
  <tag>
  	<name>second</name>
  	<tag-class>net.aacii.customTag.MyCustomTag2</tag-class>
  	<body-content>scriptless</body-content>
  </tag>
  
  <tag>
  	<name>third</name>
  	<tag-class>net.aacii.customTag.MyCustomTag3</tag-class>
  	<body-content>scriptless</body-content>
  </tag>
  
</taglib>

이어서 ex24.jsp 파일을 수정합니다.

<%@ page language="java" contentType="text/html; charset=UTF-8"    pageEncoding="UTF-8"%>
<%@ taglib prefix="my2" uri="http://myTags2.com" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Custom Tag2</title>
</head>
<body>
	<my2:second>hello~ </my2:second>
	<br>
	<my2:third>upper case</my2:third>
	<br>
	Custom Tag 2 Test!
</body>
</html>

 

태그 body의 내용이 대문자로 바뀐것을  확인할 수 있습니다.

 

실행 제어

커스텀 태그의 실행 흐름을 제어해보기 위해 MyCustomTag2.java 를 아래와 같이 수정합니다.

package net.aacii.customTag;

import java.io.IOException;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.SimpleTagSupport;

public class MyCustomTag2 extends SimpleTagSupport {

	@Override
	public void doTag() throws JspException, IOException {
		System.out.println("커스텀 태그의 바디가 실행되기 전");
		for(int i=0; i<10; i++) {
			getJspBody().invoke(null);			
		}
		System.out.println("커스텀 태그의 바디가 실행된 후");
	}
	
}

ex24.jsp 를 실행시켜보면 body가 10번 반복되는것을 확인할 수 있습니다.

 

속성 정의

커스텀 태그에 속성을 정의하고 사용해보겠습니다.

myTag2.tld 파일에 새<tag> 내용을 추가합니다.

<?xml version="1.0" encoding="UTF-8"?>
<taglib version="2.1" xmlns="http://java.sun.com/xml/ns/javaee" 
					  xmlns:xml="http://www.w3.org/XML/1998/namespace" 
					  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
					  xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-jsptaglibrary_2_1.xsd ">
  <tlib-version>1.0</tlib-version>
  <short-name>myTags2</short-name>
  <uri>http://myTags2.com</uri>
  
  <tag>
  	<name>second</name>
  	<tag-class>net.aacii.customTag.MyCustomTag2</tag-class>
  	<body-content>scriptless</body-content>
  </tag>
  
  <tag>
  	<name>third</name>
  	<tag-class>net.aacii.customTag.MyCustomTag3</tag-class>
  	<body-content>scriptless</body-content>
  </tag>
  
  <tag>
  	<name>fourth</name>
  	<tag-class>net.aacii.customTag.MyCustomTag4</tag-class>
  	<body-content>empty</body-content>
  	<attribute>
  		<name>num1</name>
  		<required>true</required>
  		<rtexprvalue>true</rtexprvalue>
  		<type>java.lang.Integer</type>
  	</attribute>
  	<attribute>
  		<name>num2</name>
  		<required>true</required>
  		<rtexprvalue>true</rtexprvalue>
  		<type>java.lang.Integer</type>
  	</attribute>
  </tag>
  
</taglib>

첫번째 attribute는 num1 이며 <required>에 true를 지정했으므로 필수 값입니다.

<rtexprvalue>를 true로 했으므로 동적으로 지정할 수 있으며 값의 타입은 Integer입니다.

 

MyCustomTag4.java 를 작성합니다.

package net.aacii.customTag;

import java.io.IOException;
import javax.servlet.jsp.JspContext;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.tagext.SimpleTagSupport;

public class MyCustomTag4 extends SimpleTagSupport {
	private int num1;
	private int num2;
	

	public int getNum1() {
		return num1;
	}


	public void setNum1(int num1) {
		this.num1 = num1;
	}


	public int getNum2() {
		return num2;
	}


	public void setNum2(int num2) {
		this.num2 = num2;
	}


	@Override
	public void doTag() throws JspException, IOException {
		JspContext context = this.getJspContext();
		JspWriter out = context.getOut();
		out.print(num1 + "+" + num2 + "=" + (num1+num2));
	}
	
}

ex24.jsp 파일을 수정합니다.

<%@ page language="java" contentType="text/html; charset=UTF-8"    pageEncoding="UTF-8"%>
<%@ taglib prefix="my2" uri="http://myTags2.com" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Custom Tag2</title>
</head>
<body>
	<my2:second>hello~ </my2:second>
	<br>
	<my2:third>upper case</my2:third>
	<br>
	<my2:fourth num1="10" num2="30" />
	<br>
	Custom Tag 2 Test!
</body>
</html>

 

 

 

 

 

 

 

 

 

728x90

'DEV&OPS > Java' 카테고리의 다른 글

JSTL Core  (0) 2022.07.08
태그 기반 커스텀 태그  (0) 2022.07.06
클래스 기반 커스텀 태그 JSP 1.2  (0) 2022.07.05
EL (Expression Language)  (0) 2022.07.01
JDBC 프로그래밍  (0) 2022.06.30