ILoveCoffee, ILoveJava/JSP

내 Custum Tags 에서 EL을 지원하게 하기~

jeeyong 2008. 6. 26. 21:22

JSTL을 사용하면 EL이 되어 매우 편하다.


<c:out value="<%=request.getParameter("aaa")%>"/> 요런게

<c:out value="${param.aaa}"/> 일케 되니 보기도 좋고 얼마나 편한가!!


자신이 만드는 Custom Tags에서도 매우 쉽게 attribute 값을 받을 때 EL을 사용할 수 있다.

단 jstl 의 standard.jar 에 의존적이다.


* 입력값으로 null을 허용하지 않는 attribute에 대한 EL처리

   org.apache.taglibs.standard.tag.el.core.ExpressionUtil 사용

   JSTL의 out tag 소스를 살펴보면 다음과 같은 부분이 있다

this.value = ExpressionUtil.evalNotNull(
                    "out",           // 태그명 <c:out 이니까 out
                    "value",        // 속성명
                    value,          // EL속성으로 넘어온 값(EL표현식)

                    Object.class,  // 반환될 값으로 기대되는 클래스타입
                    this,
                    pageContext)


* 입력값으로 null을 허용하는 attribute에 대한 EL처리  

  org.apache.taglibs.standard.lang.support.ExpressionEvaluatorManager 사용

   JSTL의 if tag의 소스중에는 다음과 같은 부분이 있다.

Object r = ExpressionEvaluatorManager.evaluate(
                  "test",          // 속성명

                   test,            // EL속성으로 넘어온 값(EL표현식)

                   Boolean.class,  // 반환될 값으로 기대되는 클래스타입

                   this,

                   pageContext);


요것이 value값을 받아서 EL 처리 (해당 el 파싱 및 적당한 scope에서 객체 얻어오기) 를 하는거이다.


저걸 내 CustomTag의 Attribute별 setter 에 넣어주면 된다.

예를 들자면 다음과 같겠다..

페이징 태그의 현재 페이지 값으로 EL을 사용할 수 있게 한 것이다.

    public void setPage(String page) {
        try {

            // page 값을 el 이라 생각하고 값 찾아봄. 없으면 JspException 이나 NullAttributeException 이 던져질것임
            Integer value = (Integer)ExpressionUtil.evalNotNull(
                                                         "paging",
                                                         "page",
                                                          page,
                                                         Integer.class,
                                                         this,
                                                         pageContext);

             this.cpage = value.intValue();
        } catch (Exception ex) {

            // EL에 실패하면 page값을 el이 아니라 생각하고 할당함

            try {
                this.cpage = Integer.parseInt(page);
            } catch (Exception e) {
                this.cpage = 1;
            }
        }      
    }


이렇게 하면 페이징 태그에서 <paging:page page="${qpage}" ..... />

이런식으로 사용가능하다, 물론 el이 알아서 4개 scope를 모두 뒤져서 알아서 찾아주니

qpage라는 name으로 4개 scope어디에 박아넣던 상관없다.