소프트웨어 개발/Java - Basic

JSP 커스텀 태그 만들기

늘근이 2014. 11. 7. 22:26

JSP에 커스텀태그는 JSTL등을 이용할때 많이 볼수 있다.

<c:when> <c:if>

와 같은 함수들은 상당히 유용하게 JSP <%%>태그를 써서 루프문을 돌리는 데에 있어 상당한 편의성을 제공한다고 할수 있다. 대체 이게 어떻게 작동하는가? 사실 아무 질문없이 '어 편하네?'라고 쓸수 있지만, 호기심많은 개발자라면 도대체 어떻게 커스텀 태그를 구현하는지 조금 더 파보고 싶기 마련이다. 이번 포스팅에서는 최소한의 설명과 효율성으로 자동으로 영어를 한국어로 번역해주는 커스텀 태그를 만들어보기로 한다.


일단 커스텀 태그는 생각해보면 굉장히 복잡한데, 필요한것은 단 세가지이다. 

1) BodyTagSupport를 상속받은 클래스 (doAfterBody()와 같은 함수를 오버라이드하기 위해서이다.)

2) taglib을 정의해놓은 *.tld 파일

3) jsp파일


1. 이번에는 이해를 돕기위해, 거꾸로 진행해 보기로 한다.

 일단 커스텀 태그를 적용시킨 jsp파일을 만들도록 한다.


다른건 볼필요도 없고, 맨 윗단에서, 태그에 관련된 설정파일인 WEB-INF 폴더 밑의 my.tld 태그 설정파일을 gorakgarak이라는 접두사와 쓴다고 선언해주고 있다.

<% taglib uri="/WEB-INF/my.tld" prefix="gorakgarak" %> 

이후, gorakgarak이라는 접두사와 함께 쓰면 된다. 일단 태그는 hi 라는 영어문구를 '안녕하세요'라는 문구로 바꿔줄것이다.

 <gorakgarak:translate>hi</gorakgarak:translate>

전체 소스코드는 다음과 같을것이다.


<%@ page language="java" contentType="text/html; charset=UTF-8"   

 pageEncoding="UTF-8"%>

    <%@ taglib uri="/WEB-INF/my.tld" prefix="gorakgarak" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">

<html>

<body>

<gorakgarak:translate>hi</gorakgarak:translate>

</body>

</html> 


2. 이번에는 저 TLD 설정파일을 만들어보자.

WEB-INF 폴더밑에 위치한다고 해놓아 버렸으니까 my.tld파일을 설정해주기 시작하면 된다. xml형식이기 때문에 이와 맞춰서 써준다.


<?xml version="1.0" encoding="UTF-8"?>

<taglib>

      <tlibversion>1.0</tlibversion>

      <jspversion>1.1</jspversion>

      <tag>

            <name>translate</name>

            <tagclass>com.gorakgarak.filter.GorakgarakTag</tagclass>

            <bodycontent>JSP</bodycontent>

      </tag>

</taglib>


뻔하지 않은가? 이 설정파일에서 빼먹을수 있는건 단 하나도 없다. tlibversion과 jspversion 모두 생략할수 없다. 버전을 명기해 주어야한다. 태그의 노드 밑에 translate는 커스텀 태그의 이름이며, 태그클래스는 실제로 자바 클래스가 위치할 그곳을 써주어야 한다.


3. 태그 동작을 정의할 JAVA클래스를 만든다.

최대한 간단히 적는다. 일단은 톰캣을 설치할때 같이 들어있는 BodyTagSupport클래스를 상속한 태그 클래스를 하나 만든다. 여기서는 GorakgarakTag extends BodyTagSupport라는 형식으로 만들었다. 그리고, doAfterBody() 함수를 오버라이드 하면 된다. JSP바디를 일단 불러와야한다. 필요한 코드는 다음에 불과하다.


BodyContent body = getBodyContent();

String filteredString = body.getString().replaceAll("hi", "안녕하세요~");

JspWriter out = getPreviousOut();

out.print(filteredString);

return SKIP_BODY;

BodyTagSupport에 포함된 getPreviousOut()함수가, 전에 있는 출력객체 JspWriter를 반환해주며 이것을 가지고 print()로찍어내면 된다.


전체 코드는 다음과 같다.

 

public class GorakgarakTag extends BodyTagSupport {     

private static final long serialVersionUID = 1L;

 

      @Override

      public int doAfterBody() throws JspException {

 

            try {

                  BodyContent body = getBodyContent();

                  String filteredString = body.getString().replaceAll("hi", "안녕하세요~");

                  JspWriter out = getPreviousOut();

                  out.print(filteredString);

            } catch (IOException e) {

                  // TODO Auto-generated catch block

                  e.printStackTrace();

            }

 

            // TODO Auto-generated method stub

            return SKIP_BODY;

      }

 

}