CUSTOM TAG (JSP 문서에서 스크립트 요소 대신 사용하기 위해 직접 만든 태그)

woom·2023년 1월 25일
0

MVC

목록 보기
4/6
post-thumbnail

🌼 CUSTOM TAG

  • 커스텀 태그(Custom Tag) : JSP 문서에서 스크립트 요소 대신 사용하기 위해 프로그래머가 직접 만든 태그

    • 태그 클래스 작성 >> TLD 파일에 커스텀 태그 등록 >> JSP 문서에 커스텀 태그 사용

📕 Custom Tag Class (속성 X, 내용 X)

  • 태그 클래스 : JSP 문서에서 커스텀 태그를 사용할 경우 호출될 메소드가 선언된 클래스

  • TagSupport 클래스, BodyTagSupport 클래스, SimpleTagSupport 클래스 중 하나를 상속받아 작성

  • 커스텀 태그 사용시 호출되는 메소드는 부모클래스의 메소드를 오버라이드 선언하여 작성

  • 기본생성자 : JSP 문서에서 커스텀 태그를 최초로 사용할 경우 태그 클래스 객체를 생성하기 위해 한번만 호출

  • doStartTag 오버라이드 : JSP 문서에서 커스텀 태그의 시작태그를 사용할 때마다 자동 호출되는 메소드

    • 부모클래스(TagSupport)에게 제공받은 PageContext 객체(pageContext 변수에 저장)를 이용하여 웹프로그램 실행에 필요한 객체를 반환받아 명령 작성
    • PageContext.getOut() : 응답결과를 생성하기 위한 출력스트림(JspWriter 객체)을 반환하는 메소드
    • pageContext.getOut().println("<div>안녕하세요.</div>");
    • doStartTag() 태그의 반환값(정수값) : 부모클래스(TagSupport)에서 제공되는 상수 사용
      • SKIP_BODY, EVAL_BODY_IMCLUDE, EVAL_BODY_AGAIN 중 하나를 선택하여 반환
      • SKIP_BODY : 태그내용을 클라이언트에게 전달하지 않을 경우 사용하는 상수 (기본값)
      • EVAL_BODY_INCLUDE : 태그내용을 클라이언트에게 전달할 경우 사용하는 상수
      • EVAL_BODY_AGAIN : 태그내용을 클라이언트에게 다시 한번 전달할 경우 사용하는 상수
  • doAfterBody : JSP 문서에서 커스텀 태그의 태그내용을 사용할 때마다 자동 호출되는 메소드

    • doAfterBody() 태그의 반환값(정수값) : doStartTag() 태그의 반환값과 동일
  • doEndTag : JSP 문서에서 커스텀 태그의 종료태그를 사용할 때마다 자동 호출되는 메소드

    • doEndTag() 태그의 반환값(정수값) : 부모클래스(TagSupport)에서 제공되는 상수 사용
      • SKIP_PAGE, EVAL_PAGE 중 하나를 선택하여 반환
      • SKIP_PAGE : 종료태그 실행 후 JSP 문서를 강제로 종료할 때 사용하는 상수
      • EVAL_PAGE : 종료태그 실행 후 JSP 문서를 계속 실행할 때 사용하는 상수 (기본값)
  • 태그 속성과 태그 내용이 없는 커스텀 태그의 클래스


package xyz.itwill.custom;

import java.io.IOException;

import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.TagSupport;

//태그 속성과 태그 내용이 없는 커스텀 태그의 클래스
public class HelloTag extends TagSupport {
	private static final long serialVersionUID = 1L;

	//JSP 문서에서 커스텀 태그를 최초로 사용할 경우 태그 클래스 객체를 생성하기 위해 한번만 호출
	public HelloTag() {
		//System.out.println("HelloTag 클래스의 기본 생성자 호출 - 객체 생성");
	}
	
	//JSP 문서에서 커스텀 태그의 시작태그를 사용할 때마다 자동 호출되는 메소드
	@Override
	public int doStartTag() throws JspException {
		//System.out.println("HelloTag 클래스의 doStartTag() 메소드 호출");
		
		try {
			//부모클래스(TagSupport)에게 제공받은 PageContext 객체(pageContext 변수에 저장)를
			//이용하여 웹프로그램 실행에 필요한 객체를 반환받아 명령 작성
			//PageContext.getOut() : 응답결과를 생성하기 위한 출력스트림(JspWriter 객체)을 반환하는 메소드
			pageContext.getOut().println("<div>안녕하세요.</div>");
		} catch (IOException e) {
			e.printStackTrace();
		}
		
		//doStartTag() 태그의 반환값(정수값) : 부모클래스(TagSupport)에서 제공되는 상수 사용 
		// => SKIP_BODY, EVAL_BODY_IMCLUDE, EVAL_BODY_AGAIN 중 하나를 선택하여 반환
		// => SKIP_BODY : 태그내용을 클라이언트에게 전달하지 않을 경우 사용하는 상수 - 기본값
		// => EVAL_BODY_INCLUDE : 태그내용을 클라이언트에게 전달할 경우 사용하는 상수
		// => EVAL_BODY_AGAIN : 태그내용을 클라이언트에게 다시 한번 전달할 경우 사용하는 상수
		return SKIP_BODY;
	}
	
	//JSP 문서에서 커스텀 태그의 태그내용을 사용할 때마다 자동 호출되는 메소드
	@Override
	public int doAfterBody() throws JspException {
		//System.out.println("HelloTag 클래스의 doAfterBody() 메소드 호출");
		
		//doAfterBody() 태그의 반환값(정수값) : doStartTag() 태그의 반환값과 동일
		return super.doAfterBody();
	}
	
	//JSP 문서에서 커스텀 태그의 종료태그를 사용할 때마다 자동 호출되는 메소드
	@Override
	public int doEndTag() throws JspException {
		//System.out.println("HelloTag 클래스의 doEndTag() 메소드 호출");

		//doEndTag() 태그의 반환값(정수값) : 부모클래스(TagSupport)에서 제공되는 상수 사용 
		// => SKIP_PAGE, EVAL_PAGE 중 하나를 선택하여 반환
		//SKIP_PAGE : 종료태그 실행 후 JSP 문서를 강제로 종료할 때 사용하는 상수
		//EVAL_PAGE : 종료태그 실행 후 JSP 문서를 계속 실행할 때 사용하는 상수 - 기본값
		return EVAL_PAGE;
	}
}






⭐ TLD 파일에 커스텀 태그 등록

  • tag : 커스텀 태그를 등록하기 위한 엘리먼트

    • name : 커스텀 태그의 이름을 등록하기 위한 엘리먼트
    • tag-class : 커스텀 태그 사용시 생성될 객체의 태그 클래스를 설정하기 위한 엘리먼트
    • body-content : 커스텀 태그에서 사용 가능한 태그내용을 설정하기 위한 엘리먼트
      (empty : 태그내용이 없는 커스텀 태그를 설정하기 위한 엘리먼트 값,
      body-content 엘리먼트 값으로 [JSP]를 설정하면 태그내용으로 JSP 명령 사용 가능)
  • attribute : 태그 속성을 등록하기 위한 엘리먼트

    • name : 태그 속성명을 설정하는 엘리먼트 - 태그 클래스의 필드명과 같은 이름으로 작성
    • required : 커스텀 태그의 속성에 대한 필수 여부를 설정하기 위한 엘리먼트
      (false : 선택 속성(기본) , true : 필수 속성)
    • rtexprvalue(runtime expression value) : 태그 속성값으로 JSP Expression 또는 EL 사용 여부를 설정하기 위한 엘리먼트
      (false : 사용 불가능(기본), true : 사용 가능)

<?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 ">
  <description>단순한 형태의 커스텀 태그 구현</description>	
  <tlib-version>1.0</tlib-version>
  <short-name>simple</short-name>
  <uri>http://www.itwill.xyz/mvc/custom</uri>
  
  <!-- tag : 커스텀 태그를 등록하기 위한 엘리먼트 -->
  <tag>
  	<!-- name : 커스텀 태그의 이름을 등록하기 위한 엘리먼트 -->
  	<name>hello</name>
  	<!-- tag-class : 커스텀 태그 사용시 생성될 객체의 태그 클래스를 설정하기 위한 엘리먼트 -->
  	<tag-class>xyz.itwill.custom.HelloTag</tag-class>
  	<!-- body-content : 커스텀 태그에서 사용 가능한 태그내용을 설정하기 위한 엘리먼트 -->
  	<!-- => empty : 태그내용이 없는 커스텀 태그를 설정하기 위한 엘리먼트 값 -->
  	<body-content>empty</body-content>
  </tag>
  
  <tag>
  	<name>helloMessage</name>
  	<tag-class>xyz.itwill.custom.HelloMessageTag</tag-class>
  	<body-content>empty</body-content>
  	<!-- attribute : 태그 속성을 등록하기 위한 엘리먼트 -->
  	<attribute>
  		<!-- name : 태그 속성명을 설정하는 엘리먼트 - 태그 클래스의 필드명과 같은 이름으로 작성 -->
  		<name>name</name>
  		<!-- required : 커스텀 태그의 속성에 대한 필수 여부를 설정하기 위한 엘리먼트 -->
  		<!-- => false : 선택 속성(기본) , true : 필수 속성 -->
  		<required>true</required>
  	</attribute>
  </tag>
  
  <tag>
  	<name>helloBody</name>
  	<tag-class>xyz.itwill.custom.HelloBodyTag</tag-class>
  	<!-- body-content 엘리먼트 값으로 [JSP]를 설정하면 태그내용으로 JSP 명령 사용 가능 -->
  	<body-content>JSP</body-content>
  	<attribute>
  		<name>test</name>
  		<required>true</required>
  		<!-- rtexprvalue : 태그 속성값으로 JSP Expression 또는 EL 사용 여부를 설정하기 위한 엘리먼트 -->
  		<!-- => false : 사용 불가능(기본), true : 사용 가능 --> 
  		<rtexprvalue>true</rtexprvalue>
  	</attribute>
  </tag>
</taglib>





📕 JSP 문서에 커스텀 태그 사용

  • taglib 디렉티브를 사용하여 TLD 파일을 제공받아야 JSP 문서에서 커스텀 태그를 사용 가능

  • custom tag 작성 <prefix name:tag name/>

    • 태그내용이 있는 경우 시작태그와 종료태그를 따로 작성
    • 태그내용이 없는 경우 시작태그와 종료태그를 같이 작성
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%-- taglib 디렉티브를 사용하여 TLD 파일을 제공받아야 JSP 문서에서 커스텀 태그를 사용 가능 --%>
<%@taglib prefix="simple" uri="http://www.itwill.xyz/mvc/custom"%>    
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>MVC</title>
</head>
<body>
	<h1>Custom Tag - NoAttribute And NoBody</h1>
	<hr>
	<%-- 태그내용이 있는 경우 시작태그와 종료태그를 따로 작성 --%>
	<%-- <simple:hello></simple:hello> --%>
	<%-- 태그내용이 없는 경우 시작태그와 종료태그를 같이 작성 --%>
	<simple:hello/>
	<simple:hello/>
	<simple:hello/>
	<simple:hello/>
	<simple:hello/>
</body>
</html>





📙 Custom Tag Class (속성 O, 내용 X)

  • 태그 속성이 있으며 태그 내용이 없는 커스텀 태그의 클래스

  • 태그 속성값을 저장하기 위한 필드 선언 (태그의 속성명과 같은 이름으로 필드 선언)

  • 생성자에서는 객체 생성에 필요한 초기화 작업에 대한 명령 작성 (필드 초기값 설정)

    • 커스텀 태그에서 속성을 생략할 경우 기본적으로 사용될 속성값을 필드에 자동 저장하기 위해 작성
    • 태그 속성이 필수인 경우 필드 기본값 설정 생략
  • 커스텀 태그에서 태그의 속성을 사용하여 속성값을 설정할 경우 Setter 메소드 자동 호출

    • 매개변수로 속성값을 제공받아 필드값 변경
  • 커스텀 태그 사용시 실행될 명령이 있는 경우에만 메소드를 오버라이드 선언하여 작성
    • 메소드를 오버라이드 선언하지 않으면 자동으로 부모클래스의 명령이 없는 메소드 호출

package xyz.itwill.custom;

import java.io.IOException;

import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.TagSupport;

//태그 속성이 있으며 태그 내용이 없는 커스텀 태그의 클래스
public class HelloMessageTag extends TagSupport {
	private static final long serialVersionUID = 1L;

	//태그 속성값을 저장하기 위한 필드 선언 - 태그의 속성명과 같은 이름으로 필드 선언
	private String name;
	
	//생성자에서는 객체 생성에 필요한 초기화 작업에 대한 명령 작성 - 필드 초기값 설정
	public HelloMessageTag() {
		//커스텀 태그에서 속성을 생략할 경우 기본적으로 사용될 속성값을 필드에 자동 저장하기 위해 작성
		// => 태그 속성이 필수인 경우 필드 기본값 설정 생략 
		name="홍길동";
	}

	public String getName() {
		return name;
	}

	//커스텀 태그에서 태그의 속성을 사용하여 속성값을 설정할 경우 Setter 메소드 자동 호출
	// => 매개변수로 속성값을 제공받아 필드값 변경
	public void setName(String name) {
		this.name = name;
	}
	
	//커스텀 태그 사용시 실행될 명령이 있는 경우에만 메소드를 오버라이드 선언하여 작성
	// => 메소드를 오버라이드 선언하지 않으면 자동으로 부모클래스의 명령이 없는 메소드 호출 
	@Override
	public int doStartTag() throws JspException {
		try {
			if(name.equals("홍길동")) {
				pageContext.getOut().println("<h3>관리자님, 안녕하세요.</h3>");
			} else {
				pageContext.getOut().println("<h3>"+name+"님, 안녕하세요.</h3>");
			}
		} catch (IOException e) {
			throw new JspException(e.getMessage());
		}
		return super.doStartTag();
	}
}






📙 JSP 문서에 커스텀 태그 사용

  • 커스텀 태그의 속성을 생략한 경우 태그 클래스의 생성자에서 설정한 기본값을 속성값으로 사용

    • 커스텀 태그의 속성이 필수로 설정된 경우 속성을 생략하면 에러 발생
    • 커스텀 태그의 속성이 필수로 설정된 경우 태그 사용시 속성 자동 완성
  • 커스텀 태그의 속성을 사용하여 속성값을 설정한 경우 태그 클래스의 필드에 대한 Setter 메소드를 자동 호출하여 속성값을 전달받아 필드명 변경

    • 태그 클래스에 필드에 대한 Setter 메소드가 없는 경우 500 에러 발생


<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@taglib prefix="simple" uri="http://www.itwill.xyz/mvc/custom" %>    
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>MVC</title>
</head>
<body>
	<h1>Custom Tag - AnyAttribute And NoBody</h1>
	<hr>
	<%-- 커스텀 태그의 속성을 생략한 경우 태그 클래스의 생성자에서 설정한 기본값을 속성값으로 사용 --%>
	<%-- => 커스텀 태그의 속성이 필수로 설정된 경우 속성을 생략하면 에러 발생 --%>
	<%-- <simple:helloMessage/> --%>

	<%-- 커스텀 태그의 속성이 필수로 설정된 경우 태그 사용시 속성 자동 완성 --%>
	<simple:helloMessage name="홍길동"/>

	<%-- 커스텀 태그의 속성을 사용하여 속성값을 설정한 경우 태그 클래스의 필드에 대한 Setter 
	메소드를 자동 호출하여 속성값을 전달받아 필드명 변경 --%>
	<%-- => 태그 클래스에 필드에 대한 Setter 메소드가 없는 경우 500 에러 발생 --%>
	<simple:helloMessage name="임꺽정"/>
</body>
</html>





📒 Custom Tag Class (속성 O, 내용 O)

  • 태그 속성과 태그 내용이 있는 커스텀 태그의 클래스

  • 커스텀 태그의 속성값을 저장하기 위한 필드

    • 태그 속성이 필수인 경우 생성자를 이용하여 필드 초기화 작업 생략
package xyz.itwill.custom;

import java.io.IOException;

import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.TagSupport;

public class HelloBodyTag extends TagSupport {
	private static final long serialVersionUID = 1L;

	//커스텀 태그의 속성값을 저장하기 위한 필드
	// => 태그 속성이 필수인 경우 생성자를 이용하여 필드 초기화 작업 생략
	private boolean test;

	public boolean isTest() {
		return test;
	}

	public void setTest(boolean test) {
		this.test = test;
	}
	
	@Override
	public int doStartTag() throws JspException {
		try {
			if(test) {
				pageContext.getOut().println("<h3>");
			} else {
				pageContext.getOut().println("<p>");
			}
		} catch (IOException e) {
			throw new JspException(e.getMessage());
		}
		return EVAL_BODY_INCLUDE;
	}
	
	@Override
	public int doEndTag() throws JspException {
		try {
			if(test) {
				pageContext.getOut().println("님, 안녕하세요.</h3>");
			} else {
				pageContext.getOut().println("님, 반갑습니다.</p>");
			}
		} catch (IOException e) {
			throw new JspException(e.getMessage());
		}
		return EVAL_PAGE;
	}
}





📒 JSP 문서에 커스텀 태그 사용

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@taglib prefix="simple" uri="http://www.itwill.xyz/mvc/custom" %>    
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>MVC</title>
</head>
<body>
	<h1>Custom Tag - AnyAttribute And AnyBody</h1>
	<hr>
	<simple:helloBody test="true">홍길동</simple:helloBody>
	<simple:helloBody test="false">임꺽정</simple:helloBody>
	<hr>
	<%
		String name="전우치";
		request.setAttribute("name", "일지매");
	%>
	<simple:helloBody test="true"><%=name %></simple:helloBody>
	<simple:helloBody test="false">${name }</simple:helloBody>
	<hr>
	<%
		boolean sw=true;
		request.setAttribute("sw", false);
	%>
	<simple:helloBody test="<%=sw %>">장길산</simple:helloBody>
	<simple:helloBody test="${sw }">홍경래</simple:helloBody>
</body>
</html>





profile
Study Log 📂

0개의 댓글