Whiteship's Note


[JSP 리팩토링] 태그 파일로 중복 코드 제거하기

모하니?/Coding : 2009.09.26 16:15


<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix="page" tagdir="/WEB-INF/tags/page"%>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib prefix="s" tagdir="/WEB-INF/tags/study"%>

<page:studypage>
<s:defaultpage>
    <h1>스터디 추가</h1>
    <form:form commandName="study" method="post">
    <p>
        <label>스터디명</label>
        <form:input path="studyName" cssClass="text" />
        <form:errors path="studyName" />
    </p>
    <p>
        <label>최대인원수</label>
        <form:input path="maximum" cssClass="text" />
        <form:errors path="maximum" />
    </p>
    <p>
        <label>시작일</label>
        <form:input path="startDay" cssClass="text"/>
        <form:errors path="startDay" />
    </p>
    <p>
        <label>종료일</label>
        <form:input path="endDay" cssClass="text"/>
        <form:errors path="endDay" />
    </p>
    <p>
        <label>설명</label>
        <form:textarea path="descr" rows="4" cols="60" cssClass="text"/>
        <form:errors path="descr" />
    </p>
    <br/><hr/><br/>
    <a href="<c:url value="/study/list.do"/>">취소</a>
    <input type="submit" value="저장" class="s_waitblock" />
    </form:form>
</s:defaultpage>
<script type="text/javascript">
  $(document).ready(function(){
    $("#startDay").datepicker({ dateFormat: 'yy/mm/dd' });
    $("#endDay").datepicker({ dateFormat: 'yy/mm/dd' });
  });
</script>
</page:studypage>

이미 태그 파일로 <html> </html>과 js, css 임포트 하는 부분을 제거 해 두었습니다. 태그 파일을 여러 추상화 계층으로 세분화 해서 로우 레벨 태그파일과 하이 레벨 태그파일로 나눌 수도 있겠습니다. 저 위에 보이는 page 태그는 하이 레벨 태그 파일로 볼 수 있고, s 태그는 로우 레벨로 볼 수 있습니다. 하이 레벨이라고 해서 뭔가 더 여러운 태그라는게 아니라, 로우 레벨 태그를 조합하여 한 단계 더 추상화시킨 태그파일 입니다. 이런 구분이 원래 있는 것이 아니라 제가 생각하는 걸 정리한 것 뿐이오니,,, 괜히 "하이 레벨 태그 파일" 이런식으로 구글링을 하는 사태가 없기를 바랍니다.

사설을 좀 길었네요, 일단락하기로 하고, 위 코드를 태그파일로 리팩토링하면 다음과 같이 됩니다.

<page:studypage>
<s:defaultpage>
    <h1>스터디 추가</h1>
    <form:form commandName="study" method="post">
    <s:ftext title="스터디명" path="studyName" />
    <s:ftext title="최대인원수" path="maximum" />
    <s:fdate title="시작일" path="startDay" />
    <s:fdate title="종료일" path="endDay" />
    <s:ftextarea title="설명" path="descr" rows="4" cols="60" />
    <hr/>
    <s:back-button url="/study/list.do" />
    <input type="submit" value="저장" class="s_waitblock" />
    </form:form>
</s:defaultpage>
<script type="text/javascript">
  $(document).ready(function(){
    $(".fdate").datepicker({ dateFormat: 'yy/mm/dd' });
  });
</script>
</page:studypage>

이렇게 했을 때 좋은 점은 소스 코드에서 중복을 제거 했을 때 얻을 수 있는 장점과 같습니다.

그러나,,, 단점도 있는데 태그 파일에 정의해준 속성만 받아서 사용하기 때문에 그만큼 사용할 수 있는 기능이 제한 될달까.. 그런게 좀 있습니다. 해결책은 있습니다. 태그 파일에 거의 모든 속성을 다 정의해 놓고 정말 필요한 것만 required로 하고 사용해도 될테지만.. 태그 파일을 만드는 비용이 꽤 많이 들겠지요. 결국 선택의 기로에 서게 되는데, 저는 귀찮아서;; 그냥 최소한의 속성만 정의해서 쓰는 편입니다.

top

Write a comment.


OSAF 검색 폼 태그 파일 완성

모하니?/Coding : 2008.09.25 15:59


사용자 삽입 이미지

태그 파일을 활요한 JSP 코드는 다음과 같습니다.

<o:searchpage title="사원관리">
    <o:searchbuttons popupheight="400" popupwidth="700" />

    <o:searchform action="grid.do">
        <o:searchrow>
            <o:stext path="name" label="이름" size="20" maxlength="30" />
            <o:sselect path="location" label="국적" items="${ref.locations}" isCOV="yes" />
            <o:sdate path="birthday" label="생일" />
        </o:searchrow>
        <o:searchrow>
            <o:sradiobuttons path="sex" label="성별" items="${ref.sexType}" />
        </o:searchrow>
        <o:searchrow>
            <o:scheckboxes path="hobbies" label="취미" items="${ref.hobbyType}" />
        </o:searchrow>
    </o:searchform>
</o:searchpage>

뭔가 많아 보여도, <o:searchrow>를 사용해서 세 줄로 표시했을 뿐, <o:searchrow>를 빼면 별거 없습니다. 이젠 정말 폼 태그 파일 만들차례.. ㅎㄷㄷㄷ.. 어려울텐데.. ㄷㄷㄷㄷ DisplayTag로 만들어봐야지
top

Write a comment.


JavaScript Calendar

View/JavaScript : 2008.09.25 13:52


참조: http://www.dynarch.com/projects/calendar/
사용자 삽입 이미지

저렇게 달력을 뿌려주는 자바스크립트 라이브러리입니다. Date 정보를 입력받을 때 사용하면 유용하겠죠. 여러 가지 스타일 시트도 제공해주고, 여러 포맷으로 데이터를 조작할 수도 있고, 좋습니다.

jscalander가 제공하는 예제 소스 코드를 보면 어떻게 이용할 수 있을지 대충 알 수 있습니다.
<form action="#" method="get">
<input type="text" name="date" id="f_date_b" /><button type="reset" id="f_trigger_b">...</button>
</form>

<script type="text/javascript">
    Calendar.setup({
        inputField     :    "f_date_b",      // id of the input field
        ifFormat       :    "%m/%d/%Y %I:%M %p",       // format of the input field
        showsTime      :    true,            // will display a time selector
        button         :    "f_trigger_b",   // trigger for the calendar (button ID)
        singleClick    :    false,           // double-click mode
        step           :    1                // show all years in drop-down boxes (instead of every other year as default)
    });
</script>

친절하게 주석도 있기 때문에, 금방 적용하실 수 있겠죠. 하지만, 약간의 번거로움은 감수를 하셔야 하며, 저런 컴포넌트가 여럿 필요할 때는 복사 붙여넣기 코드가 JSP 페이지 사방에 나타날 수 있을 겁니다. 그럴 땐 태그 파일을 만들어서 컴포넌트화 해 두면 매우 편합니다.

언젠가 공개할 OSAF를 사용하신다면, 간단한 태그 파일 sdata.tag로 쉽게 저런 UI 컴포넌트를 만들 수 있습니다.

<o:sdate path="birthday" label="생일" />

이렇게 한 줄이면 끝이죠. 캬오~ 태그 파일 만쉐이! OSAF 만쉐이!!
top

Write a comment.


휴.. 폼 태그 파일 완성.

View/JSP : 2008.09.22 11:59


<o:popuppage title="사원등록">
    <o:buttons>
        <o:savebtn />
        <o:cancelbtn />
    </o:buttons>
    
    <o:form>
        <o:ftext label="이름" path="name" size="10" maxlength="20" />
        <o:ftext label="아이디" path="loginId" size="15" maxlength="20" desc="최대 20자리까지 입력 할 수 있습니다." />
        <o:fpassword label="패스워드" path="password" size="10" maxlength="16" desc="최대 16자리까지 입력 할 수 있습니다." />
        <o:fradiobuttons label="성별" path="sex" items="${ref.sexType}" />
        <o:fcheckboxes label="취미" path="hobbies" items="${ref.hobbyType}" />
        <o:fselect label="국적" path="location" items="${ref.locations}" isCOV="yes" />
        <o:ftextarea label="메모" path="memo" rows="3" cols="50" />
    </o:form>
</o:popuppage>

이게 추가와 수정시에 사용할 JSP 페이지 코드입니다. JSP를 몰라도 금방 태그 파일 몇개만 익히면 쉽게 페이지를 찍어낼 수 있습니다. 이 페이지에서 사용하고 있는 태그 파일들은 다음과 같습니다.

사용자 삽입 이미지

흠냐~ 이 녀석들로 만들어 낸 화면입니다.
사용자 삽입 이미지

물론 CSS도 가미가 되어 있습니다. CSS는 잘 몰라서 사부님이 만들어 둔 걸 그대로 쓰고 있습니다. 저기 items 뿌리는 부분의 label 스타일을 좀 변경하고 싶은데;; 일단 스타일은 나중에 변경하기로.. ㅋㅋ

사용자 삽입 이미지

업데이트 뷰에서도 위와 동일한 태그를 사용하면 됩니다. 흠.. 버튼을 하나 추가해서 삭제버튼을 달아야겠군요.

이것으로 폼 태그 파일들은 다 준비가 됐습니다. 이제 그리드 태그 파일만 완성하면... 드디어 OSAF를 출시할 수 있게 됩니다. 캬오~~
top

Write a comment.


1년 반 만에 다시 찾은, EL 안에 EL 사용하는 방법

View/JSP : 2008.09.17 17:50


커스텀 태그에서 Expression Language를 사용하다보면, 언젠간 아래처럼 쓰고 싶은 경우가 발생할 수도 있습니다. 전 예전에 한 번 이 벽에 부딪혀서 결국 못 넘고 좌절한 적이 있는데, 해당 글에 물개선생님이 남겨주신 댓글과 사부님이 만든 태그를 보니.. 이해가 됩니다.

먼저 상황부터 설명을 하자면,..

일단 EL 안에 EL을 사용하고 싶은 경우가 어떤 경우냐면.. 보통 ${member.name} 이렇게 쓰는데, 만약 이 때 이 name라는 값도 변수화 해서 property라는 태그 파일 속성으로 받도록 할 수 있겠습니다. 그리고 이 속성에는 name 뿐만 아니라, age, height 등등 여러 가지 member 객체가 가지고 있는 속성 값을 넣을 수 있다고 했을 때.. EL로 그 속성값을 뿌리려면..

<%@ attribute name="property" required="false" %>

${member.${property}}

이렇게 하고 싶습니다. 그쵸? 하지만, 해보시면 아시겠지만 안 됩니다. 저런 문법을 EL이 지원하질 않습니다.

심각: Servlet.service() for servlet sample threw exception
org.apache.el.parser.ParseException: Encountered "{" at line 1, column 4.
Was expecting one of:
    "}" ...
    "." ...
    "[" ...
    ">" ...
    "gt" ...
    "<" ...
    "lt" ...
    ">=" ...
    "ge" ...
    "<=" ...
    "le" ...
    "==" ...
    "eq" ...
    "!=" ...
    "ne" ...
    "&&" ...
    "and" ...
    "||" ...
    "or" ...
    "*" ...
    "+" ...
    "-" ...
    "?" ...
    "/" ...
    "div" ...
    "%" ...
    "mod" ...
    "(" ...
   
    at org.apache.el.parser.ELParser.generateParseException(ELParser.java:1874)
    at org.apache.el.parser.ELParser.jj_consume_token(ELParser.java:1754)
    at org.apache.el.parser.ELParser.DynamicExpression(ELParser.java:156)

자.. 이런 에러가 발생합니다. 괄호를 안쪽부터 처리해주면 좋겠지만, 희망사항이었던 것 같습니다. ${property}의 값이 name이면 ${member.name} 이 되고.. 이건 내부적으로 member.getName()을 호출해서 가져다주면 좋을텐데 말이죠. 흠... 복잡해 질까봐 이렇게 구현하지 않았을지도 모르겠습니다.

어쨋든, 저 윗 글에 물개선생님이 알려주신 코드대로 하면 EL안에 EL을 사용하는 효과를 얻을 수 있습니다.

<%@ attribute name="property" required="false" %>

<%
property = (property != null) ? property : "name";
Object memberPropertyValue = PageContextImpl.proprietaryEvaluate("${member." + property + "}", Object.class, (PageContext)this.getJspContext(), null, false);
out.print(memberPropertyValue.toString());
%>

이렇게 PageContextImpl를 이용해서 가져오면 됩니다. 위에서 제가 원하던 방법대로 자바 코드를 사용해서 처리한 겁니다. "${member." + property + "} 이렇게 하는 순간, 이미 안 쪽의 변수 값을 가져오기 때문에 이후에는 ${member.name}를 쓰는 것과 같은 것이 됩니다.

흠.. 이상합니다. 저 때도 분명 물개 선생님이 댓글로 코드까지 주셨는데, 저걸 못 써먹고 포기했었습니다. 거의 1년 반이 지난 이제와서 그때 포기했던걸 다시 하게 되네요. ㅋㅋ 1년 반이라...
top

  1. Favicon of http://toby.epril.com BlogIcon '토비 2008.09.17 19:57 PERM. MOD/DEL REPLY

    저 코드는 문제가 있음. 멀까나.

    Favicon of https://whiteship.tistory.com BlogIcon 기선 2008.09.17 20:55 신고 PERM MOD/DEL

    앗!.. 수정했습니다.

  2. 자바인 2009.03.03 11:27 PERM. MOD/DEL REPLY

    단순 출력만을 위해서는
    빈 태그를 사용해도 무난합니다.

    전 게시판 목록을 뿌릴때 사용합니다만..
    <logic:iterate id="list" name="to" property="lists">
    <logic:iterate id="titParam" name="module" property="titParams">
    <bean:write name="list" property="${titParam}" />
    </logic:iterate>
    </logic:iterate>

    제가 구현한 소스의 일부분입니다.
    단순 출력만 할땐 문제가 안되었지만 ..
    length를 체크하여 너무 길면 잘라서 ...으로 나타나게 할려고 하는데 .

    <c:if test="${fn:length(list.${titParam}) > 15}">
    이때가 문제가 되더군요 ..
    네이버에서 'el 안에 el'이라는 키워드로 검색하다 오게되었습니다..

    이 게시물을 보고 희망이 생겼습니다.
    감사합니다 !!
    하지만 PageContextImpl 에 proprietaryEvaluate가 없는것 같은데 ㅠㅠ
    해결방법이 없을까요 ?

    이클립스에서 계속 proprietaryEvaluate 부분에 빨간 밑줄이 그어지네요 .. ㅠㅠ

    Favicon of http://whiteship.me BlogIcon 기선 2009.03.03 11:56 PERM MOD/DEL

    에잉~ 왜그러세요 아마추어 같이 ;)
    API를 보시면 되죠.ㅋㅋ (확인해보시면 아시겠지만 PageContextImpl이 그 매서드 가지고 있습니다.)

    JSP나 태그파일에서 import 문을 빠트리신거 아닐까요?
    아님 이클립스 편집기가 말썽이거나요..
    혹은 오타??

    셋 중 하나일것 같네요.

  3. 자바인 2009.03.03 12:16 PERM. MOD/DEL REPLY

    다른 패키지인가 봅니다 -.,-
    프로젝트에는
    org.apache.taglibs.standard.lang.jstl.test.PageContextImpl
    밖에 없네요 ㅠㅠ
    org.apache.jasper.runtime.PageContextImpl 인가 봐요 ??

    Favicon of http://whiteship.me BlogIcon 기선 2009.03.03 15:09 PERM MOD/DEL

    아.. 다른 패키지에 있는 클래스였군요.ㅎㅎ;;
    넹 후자가 맞습니다.

  4. leeplay 2011.05.11 13:47 PERM. MOD/DEL REPLY

    <%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8" import="java.util.*,org.apache.jasper.runtime.PageContextImpl"%>

    저렇게 선언하고

    <%@ attribute name="property" required="false" %>

    <%
    property = (property != null) ? property : "name";
    Object memberPropertyValue = PageContextImpl.proprietaryEvaluate("${member." + property + "}", Object.class, (PageContext)this.getJspContext(), null, false);
    out.print(memberPropertyValue.toString());
    %>

    했는데 getJspContext 부분에 에러가 뜹니다-ㅅ-a;; getServletContext 가 있어서 써봣는데
    안되더라구요-ㅁ-; 뭐가 문제인가요?

Write a comment.


태그 파일 활용 예제

View/JSP : 2008.02.18 21:19


참조 : Developing Custom Tag Libraries as Tag Files

1. JSP 조각 태그 파일로 넘겨주기
- attribute의 fragment 사용하면 돼.
<%@ page contentType="text/html" %>
<%@ taglib prefix="my" tagdir="/WEB-INF/tags/mytags" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
<title>Even and Odd Rows</title>
</head>
<body bgcolor="white">
<h1>Even and Odd Rows</h1>
<table>
<my:forEvenAndOdd items="a,b,c,d,e">
<jsp:attribute name="even">
<c:set var="counter" value="${counter + 1}" />
<tr bgcolor="red"><td>${counter}: Even Row</td></tr>
</jsp:attribute>
<jsp:attribute name="odd">
<c:set var="counter" value="${counter + 1}" />
<tr bgcolor="blue"><td>${counter}: Odd Row</td></tr>
</jsp:attribute>
</my:forEvenAndOdd>
</table>
</body>
</html>

이런 HTML이 있을 때 even이랑 odd라는 JSP 조각을 forEvenAdnOdd 태그 파일로 넘긴다. 물론 items라는 속성도 가지고 있다.

<%@ tag body-content="empty" %>
<%@ attribute name="items" rtexprvalue="true" required="true" %>
<%@ attribute name="even" fragment="true" required="true" %>
<%@ attribute name="odd" fragment="true" required="true" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

<c:forEach items="${items}" varStatus="status">
<c:choose>
<c:when test="${status.count % 2 == 0}">
<jsp:invoke fragment="even" />
</c:when>
<c:otherwise>
<jsp:invoke fragment="odd" />
</c:otherwise>
</c:choose>
</c:forEach> 

태그 파일 안에서 <jsp:invoke>를 사용해서 해당 조각들을 호출할 수 있다. items 속성의 값을 , 로 구분된 리스트로 인식하려고 한 듯, 기본값도 true니까 굳이 적어주지 않아도 될 듯. fragment="true" 는 반드시 설정해 주어야 함. 기본값이 false니까.

JSP에서 태그 파일에서 사용하는 값도 알아야 할 필요가 있다. 위와 같은 경우 태그 타일 내부에서는 a, b, c, d, e를 구분하여 하나씩 값으로 처리하고 있는데 이걸 JSP에서는 모르니까.. JSP로 넘겨주어야 한다. 이럴 때 variable 지시자를 사용한다.

<%@ tag body-content="empty" %>
<%@ attribute name="items" rtexprvalue="true" required="true" %>
<%@ attribute name="even" fragment="true" required="true" %>
<%@ attribute name="odd" fragment="true" required="true" %>
<%@ variable name-given="current" variable-class="java.lang.Object"
scope="NESTED" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<c:forEach items="${items}" varStatus="status" var="current">
<c:choose>
<c:when test="${status.count % 2 == 0}">
<jsp:invoke fragment="even" />
</c:when>
<c:otherwise>
<jsp:invoke fragment="odd" />
</c:otherwise>
</c:choose>
</c:forEach> 

나머지 부분은 동일하고, current라는 변수를 루프 돌 때 사용하고 있다, 그러면 이제 JSP에서도 current라는 변수로 태그 파일에서 사용하고 있는 값을 참조할 수 있다.

<%@ page contentType="text/html" %>
<%@ taglib prefix="my" tagdir="/WEB-INF/tags/mytags" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
<title>Even and Odd Rows</title>
</head>
<body bgcolor="white">
<h1>Even and Odd Rows</h1>
<table>
<my:forEvenAndOdd2 items="a,b,c,d,e">
<jsp:attribute name="even">
<c:set var="counter" value="${counter + 1}" />
<tr bgcolor="red"><td>${counter}: Even Row: ${current}</td></tr>
</jsp:attribute>
<jsp:attribute name="odd">
<c:set var="counter" value="${counter + 1}" />
<tr bgcolor="blue"><td>${counter}: Odd Row: ${current}</td></tr>
</jsp:attribute>
</my:forEvenAndOdd2>
</table>
</body>
</html>
 
그런데, JSP 입장에서 보면 참 쌩뚱 맞을 수 밖에 없다. 느닺없이 current라는 변수가 튀어 나왔다. 도대체 어디서 튀어 나온 녀석이냐며 심각한 고민에 빠질 수도 있다. 그래서 태그의 속성으로 current라는 이름을 리스트의 인자를 가리킬 때 사용할 거라는 것을 알려줘야 한다.

<%@ tag body-content="empty" %>
<%@ attribute name="items" rtexprvalue="true" required="true" %>
<%@ attribute name="var" rtexprvalue="false" required="true" %>
<%@ attribute name="even" fragment="true" required="true" %>
<%@ attribute name="odd" fragment="true" required="true" %>
<%@ variable name-from-attribute="var" alias="current"
variable-class="java.lang.Object" scope="NESTED" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<c:forEach items="${items}" varStatus="status" var="current">
<c:choose>
<c:when test="${status.count % 2 == 0}">
<jsp:invoke fragment="even" />
</c:when>
<c:otherwise>
<jsp:invoke fragment="odd" />
</c:otherwise>
</c:choose>
</c:forEach>

이전 태그 파일과 다른 부분은 name-given 대신에 name-from-attibute를 사용했고, 그 값으로 var라는 attribute를 지정했다. 이 속성은 rtexprvalue를 false로 지정해두었다. 무슨 값이 오던 신경끄라는 것 같다. 그냥 그 값으로 태그 파일 내부의 값을 참조하게 된다. 안에서 보면 좀 어지럽지만.. 밖에서 보면 간단해진다.

<%@ page contentType="text/html" %>
<%@ taglib prefix="my" tagdir="/WEB-INF/tags/mytags" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
<title>Even and Odd Rows</title>
</head>
<body bgcolor="white">
<h1>Even and Odd Rows</h1>
<table>
<my:forEvenAndOdd3 items="a,b,c,d,e" var="anyName">
<jsp:attribute name="even">
<c:set var="counter" value="${counter + 1}" />
<tr bgcolor="red"><td>${counter}: Even Row: ${anyName}</td></tr>
</jsp:attribute>
<jsp:attribute name="odd">
<c:set var="counter" value="${counter + 1}" />
<tr bgcolor="blue"><td>${counter}: Odd Row: ${anyName}</td></tr>
</jsp:attribute>
</my:forEvenAndOdd3>
</table>
</body>
</html> 

멋지다. 이제 더 이상 current라는 변수 명이 어디서 왔는지 신경쓰지 않아도 되고, 거기에 얽매이지 않아도 된다. 원하는 이름으로 태그 파일에 주고 그 이름으로 태그 파일에 있는 값을 가져올 수 있다.

이렇게 진화하는 예제를 가지고 글을 써주는 사람들은 정말 멋진 것 같다. 머리에도 잘 들어오고, 이해하기도 좋은 것 같다. Good!!

top

Write a comment.


태그 파일

View/JSP : 2008.02.18 20:00


참조
Easy Custom Tags with Tag Files, Part 1
Easy Custom Tags with Tag Files, Part 2

JSP 2.0 이전의 커스텀 태그 사용법
1. 핸들러를 작성하고 컴파일 한다.
2. 태그 핸들러와 관련된 태그를 정의한다.

그러나 태그 파일은 미리 컴파일 할 필요 없다. 호출 되는 순간 컴파일 된다.
핸들러 또한 오직 JSP 문법만을 사용하여 만들 수 있다.
태그 라이브러리 서술자 역시 만들 필요 없다. 태그 파일이름을 태그 이름으로 사용하기 때문에.

태그 파일에서 묵시적으로 사용 가능한 객체들
- request     javax.servlet.http.HttpServletRequest
- response     javax.servlet.http.HttpServletResponse
- out     javax.servlet.jsp.JspWriter
- session     javax.servlet.http.HttpSession
- application     javax.servlet.ServletContext
- config     javax.servlet.ServletConfig
- jspContext     javax.servlet.jsp.JspContext

태그 파일 지시자
- <%@ 로 열고 %> 로 닫는다.
- tag      JSP 페이지의 page와 비슷한 지시자
- include     태그 파일에 다른 자원을 포함시킬 때 사용하는 지시자
- taglib     태그 파일에서 커스텀 태그 라이브러리를 사용하고자 할 때 사용
- attribute     태그 파일에 속성 선언할 때 사용
- variable     호출하는 JSP 페이지로 넘겨줄 변수를 정의할 때 사용

tag 지시자의 속성
- display-name      XML 툴에 의해 보여질 간단한 이름. 기본값은 .tag를 짤라버린 태그 파일이름.
- body-content     이 태그의 몸체 컨텐츠에 대한 정보. The value can be empty, tagdependent, or scriptless (default).
- dynamic-attributes     동적인 속성의 지원 여부 알려줌. The value identifies a scoped attribute in which to place a Map containing the names and values of the dynamic attributes passed during this invocation.
- small-icon     보통 사용하지 않는다니까 패스.
- large-icon     보통 사용하지 않는다니까 패스.
- description     태그에 대한 설명.
- example     이 액션을 사용하는 방법에 설명.
- language     태그 파일에서 사용되는 스크립트 언어. The value for this attribute for the current version of JSP must be "java".
- import     page의 import와 같다.
- pageEncoding     page의 속성과 같다.
- isELIgnored     기본값은 false. page의 속성과 같다.
- 사용예
<%@ tag body-content="empty"
import="java.util.Enumeration" %>
<%@ tag import="java.sql.*" %>
- import 빼고는 한 번만 나올 것이다.(모든 속성이 optional이다.)

include 지시자
- 여러 태그 파일에서 공통으로 사용되는 코드가 있을 때 사용한다.
- 사용예
<%@ include file="included.tagf" %>

taglib 지시자
- <%@ taglib uri="tagLibraryURI" prefix="tagPrefix" %> 이런 문법 사용한다.
- 사용예
<%@ taglib prefix="simple" tagdir="/WEB-INF/tags" %>
The server's date: <simple:firstTag/>

attribute 지시자 속성
- name      이 태그 파일이 받아들일 때 사용할 속성 이름. 이 이름은 해당 태그 파일에서 유일 해야 한다.
- required     필수 속성인지 아닌지. false가 기본값.
- fragment     태그 핸들러에 의해 계산되는 fragment인지 아닌지 컨테이너가 그냥 처리할 녀석인지 알려준다. 기본값은 false. 속성의 값을 태그 핸들러가 먼저 처리해야 되면 true로 설정하라.
- rtexprvalue     속성의 값이 scriptlet expression에 의해 동적으로 계산되는 값인지 알려준다. true가 기본값.
- type     속성의 타입. java.lang.String이 기본값.
- description     속성에 대한 설명.

variable 지시자 속성
- atttibute 지시자와 반대로, JSP로 태그 파일안에 있는 어떤 값을 넘겨 줄 수 있고, 여러개를 선언할 수 있으니까 여러 개의 값을 이 태그를 사용한 JSP로 넘길 수 있다.
- name-given      호출한 JSP에 있는 스크립트 언어나 EL 표현식에서 사용할 수 있는 변수 이름. name-from-attribute와 이 속성 둘 중 하나만 존재해야 한다. 태그 파일 내에서 유일해야 한다.
- name-from-attribute     name-given과 동일한데, 다만 이 속성의 값이 attribute의 이름이다.
- alias     이 변수의 값을 가지고 있을 로컬 attriute
- variable-class     이 변수의 타입. java.lang.String이 기본값.
- declare     이 것을 호출하는 페이지나 태그 파일에서 변수가 선언되어 있는지 알려준다. true가 기본값.
- scope     The scope of the scripting variable defined. The possible values are AT_BEGIN, AT_END, and NESTED (default).
- description     변수에 대한 설명.
- 예제
<%@ tag import="java.util.Date"
import="java.text.DateFormat"%>
<%@ variable name-given="longDate" %>
<%@ variable name-given="shortDate" %>
<%
  Date now =
new Date(System.currentTimeMillis());
  DateFormat longFormat =
DateFormat.getDateInstance(DateFormat.LONG);
  DateFormat shortFormat =
DateFormat.getDateInstance(DateFormat.SHORT);
  jspContext.setAttribute(
"longDate", longFormat.format(now));
  jspContext.setAttribute(
"shortDate", shortFormat.format(now));
%>
<jsp:doBody/>

<%@ taglib prefix="tags"
tagdir="/WEB-INF/tags" %>
Today's date:
<br/>
<tags:varDemo>
In long format: ${longDate}
<br/>
In short format: ${shortDate}
</tags:varDemo>

jsp:doBody
- 오직 태그 파일 안에서만 사용할 수 있다.
- 태그의 몸체를 실행할 때 사용한다.
- 몸체를 호출한 결과를 특정 변수에 담고 싶을 때는 var(값을 String으로 받는다.)나 varReader(값을 Reader로 받는다.) 속성을 사용한다.
- 예제
<jsp:doBody var="referer"
scope="session"/>
저렇게 정의해둔 태그로 둘러 쌓인 부분을 실행한 결과를 String 타입으로 refer라는 변수에 session 스콥으로 가지고 있는다.

jsp:invoke
- fragment attribute를 호출할 때 사용한다.
- attribute를 fragment로 설정했다면, 태그 파일 안에서 원하는 만큼 여러번 호출할 수 있다.
- 이것도 jsp:doBody과 같은 역할을 하는 속성을 가질 수 있고, fragment는 필수 속성이다.
- 예제
<%@ attribute name="productDetails"
fragment="true" %>
<%@ variable name-given="productName" %>
<%@ variable name-given="description" %>
<%@ variable name-given="price" %>
<%
  jspContext.setAttribute(
"productName", "Pelesonic DVD Player");
  jspContext.setAttribute(
"description",
    "Dolby Digital output through
coaxial digital-audio jack," +
    " 500 lines horizontal
resolution-image digest viewing");
  jspContext.setAttribute("price", "65");
%>
<jsp:invoke fragment="productDetails"/>

<%@ taglib prefix="easy"
tagdir="/WEB-INF/tags" %>
<html>
<head>
<title>Product Details</title>
</head>
<body>
<easy:invokeDemo>
  <jsp:attribute name="productDetails">
    <table width="220" border="1">
    <tr>
      <td><b>Product Name</b></td>
      <td>${productName}</td>
    </tr>
    <tr>
      <td><b>Description</b></td>
     <td>${description}</td>
    </tr>
    <tr>
      <td><b>Price</b></td>
      <td>${price}</td>
    </tr>
    </table>
  </jsp:attribute>
</easy:invokeDemo>
</body>
</html>

태그 파일 패키징하기
- 태그 라이브러리 서술자. tld 파일을 만들어야 한다.
<?xml version="1.0" encoding="UTF-8" ?>

<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">
 
  <description>JSP 2.0 tag files</description>
  <tlib-version>1.0</tlib-version>
  <short-name>My Tag Files</short-name>
  <uri>http://www.brainysoftware.com/tagfiles</uri>
  <tag-file>
    <name>encode</name>
    <path>/META-INF/tags/encode.tag</path>
  </tag-file>
</taglib>

- 루트 폴더 밑에 META-INF 폴더를 만들고 그 안에 서술자 파일을 넣는다.
- 태그 파일들은 META-INF 폴더 밑에 tags폴더를 만들고 그 안에 넣는다.
- JAR파일로 묶는다. ex) jar cvf mytagfiles.jar *
- 사용한다.
<%@ taglib prefix="easy"
uri="http://www.brainysoftware.com/tagfiles" %>
<easy:encode input="<br/> means changing line"/>

top

  1. Favicon of http://seal.tistory.com BlogIcon 물개선생 2008.02.19 02:21 PERM. MOD/DEL REPLY

    늘 그렇듯이.. 정리 구우~ㅅ ^^*

    Favicon of http://whiteship.tistory.com BlogIcon 기선 2008.02.19 09:14 PERM MOD/DEL

    헤헷 물개선생님께 배웠던 내용인데 까먹어서 다시 정리했어요. :)

Write a comment.