'JSTL'에 해당하는 글 6건

커스텀 태그 안에 커스텀 태그가 위치해 있을 경우 서로간에 필요한 속성이라던가 내용 등을 읽어올 필요가 있다. 이럴 경우에는 다음과 같은 방법으로 접근할 수 있다.

myCustomTag3.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">

<tlib-version>0.1</tlib-version>

<uri>Nested</uri>
<tag>
    <description>NestedLevel Check</description>
    <name>NestedLevel</name>
    <tag-class>com.example.tag.NestedLevelTag</tag-class>
    <body-content>JSP</body-content>
</tag>
</taglib>

NestedLevelTag.java

package com.example.tag;

import java.io.IOException;

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

public class NestedLevelTag extends TagSupport {
    private int nestLevel = 0;
   
    public int doStartTag() throws JspException {
        nestLevel = 0;
        Tag parent = getParent();
       
        while(parent != null) {
            parent = parent.getParent();
            nestLevel++;
        }
       
        try {
            pageContext.getOut().println("<br>Tag nested level : " + nestLevel);
        } catch (IOException e) {
            // TODO: handle exception
            throw new JspException("IOException - " + e.toString());
        }
       
        return EVAL_BODY_INCLUDE;
    }
}

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib prefix="mine" uri="Nested" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<mine:NestedLevel>
    <mine:NestedLevel>
        <mine:NestedLevel/>
    </mine:NestedLevel>
</mine:NestedLevel>
</body>
</html>

결과물

Insert title hereTag nested level : 0
Tag nested level : 1
Tag nested level : 2

getParent 메소드를 반복해서 호출해서 depth가 몇단계인지 알아내는 예제이다.

SimpleTag 인터넾이스와 Tag인터페이스는 JspTag 인터페이스를 구현한 것이다. SimpleTag의 getParent 메소드는 JspTag를 리턴하는데 반해 Tag(클래식 커스텀 태그)의 getParent 메소드는 Tag를 리턴한다.
이 점은 중요한데 왜냐하면 이 차이로 인해 Tag가 SimpleTag의 부모 태그가 될 수 있지만, SimpleTag가 Tag의 부모 태그가 될 수 없기 때문이다.
아래 내용은 Tag가 SimpleTag의 부모 태그로서 사용 되어질 경우 부모 태그의 attribute를 알아오는 예제이다.

classicParent.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">

<tlib-version>0.1</tlib-version>

<uri>ClassicParentTag</uri>
<tag>
    <description>classic parent</description>
    <name>ClassicParent</name>
    <tag-class>com.example.tag.MyClassicParent</tag-class>
    <body-content>JSP</body-content>
    <attribute>
        <name>name</name>
        <required>true</required>
        <rtexprvalue>true</rtexprvalue>
    </attribute>
</tag>
<tag>
    <description>Simple Inner Tag</description>
    <name>SimpleInner</name>
    <tag-class>com.example.tag.SimpleInner</tag-class>
    <body-content>empty</body-content>
</tag>
</taglib>

SimpleInner.java

package com.example.tag;

import java.io.IOException;

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

public class SimpleInner extends SimpleTagSupport {
    public void doTag() throws JspException, IOException {
        MyClassicParent parent = (MyClassicParent) getParent();
        getJspContext().getOut().print("Parent attribute is : " + parent.getName());
    }
}

MyClassicParent.java

package com.example.tag;

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

public class MyClassicParent extends TagSupport {
    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
   
    public int doStartTag() throws JspException {
        return EVAL_BODY_INCLUDE;
    }
}

classicParentTag.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib prefix="mine" uri="ClassicParentTag" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<mine:ClassicParent name="aaa">
    <mine:SimpleInner/>
</mine:ClassicParent>
</body>
</html>

결과물

Insert title hereParent attribute is : aaa

tld 파일에서는 ClassicParent 부모 태그와 SimpleInner 자식 태그를 정의 한다. ClassicParent 에는 name 이란 attribute가 존재 한다.
ClassicParent와 SimpleInner태그를 구현한 각 Java 파일은 위 소스와 같이 구현한다.
SimpleInner.java 파일에서 눈여겨 볼 것은 getParent 메소드를 통해 리턴 받은 JspTag형 객체를 ClassicParent로 형변환 해서 사용하는 것이다.
ClassicParent.java 파일에는 setter와 getter가 있는데, 자동으로 setter는 tld 에서 정의한 name이란 attribute에 값을 할당해 주며, getter는 SimpleInner.java에서 사용한다.
물론 ClassicParent.java의 doStartTag()에서 EVAL_BODY_INCLUDE를 리턴해 주어야지만 자식 태그인 SimpleInner가 실행 되게 된다.

중요한 것은 자식 태그에서 부모 태그의 정보를 읽을 수는 있어도 부모에서 자식 태그의 정보를 읽을 수는 없다.
따라서 부모에서 자식 태그를 알기 위해서는 반대로 자식에수 부모 쪽에 값을 셋팅 하는 방법을 사용해야 한다.
다음 예제를 통해서 부모가 자식의 속성 값을 알아내는 방법을 살펴보자.

menuTag.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">

<tlib-version>0.1</tlib-version>

<uri>MenuTag</uri>
<tag>
    <description>parent menu tag</description>
    <name>Menu</name>
    <tag-class>com.example.tag.Menu</tag-class>
    <body-content>JSP</body-content>
</tag>
<tag>
    <description>child menu tag</description>
    <name>MenuItem</name>
    <tag-class>com.example.tag.MenuItem</tag-class>
    <body-content>JSP</body-content>
    <attribute>
        <name>itemValue</name>
        <required>true</required>
        <rtexprvalue>true</rtexprvalue>
    </attribute>
</tag>
</taglib>

Menu.java

package com.example.tag;

import java.util.ArrayList;

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

public class Menu extends TagSupport {
    private ArrayList<String> items;
   
    public void addMenuItem(String item) {
        items.add(item);
    }
   
    public int doStartTag() throws JspException {
        items = new ArrayList<String>();
       
        return EVAL_BODY_INCLUDE;
    }
   
    public int doEndTag() throws JspException {
        try {
            pageContext.getOut().println("Menu items are : " + items);
        } catch (Exception e) {
            // TODO: handle exception
            throw new JspException("Exception : " + e.toString());
        }
        return EVAL_PAGE;
    }
}

MenuItem.java

package com.example.tag;

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

public class MenuItem extends TagSupport {
    private String itemValue;

    public void setItemValue(String itemValue) {
        this.itemValue = itemValue;
    }
   
    public int doStartTag() throws JspException {
        return EVAL_BODY_INCLUDE;
    }
   
    public int doEndTag() throws JspException {
        Menu parent = (Menu) getParent();
        parent.addMenuItem(itemValue);
        return EVAL_PAGE;
    }
}

menuItem.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib prefix="mine" uri="MenuTag" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<mine:Menu>
    <mine:MenuItem itemValue="Dogs"></mine:MenuItem>
    <mine:MenuItem itemValue="Cats"></mine:MenuItem>
    <mine:MenuItem itemValue="Horses"></mine:MenuItem>
</mine:Menu>
</body>
</html>

결과물

Insert title hereMenu items are : [Dogs, Cats, Horses]

menuTag.tld 파일에선 Menu태그와 MenuItem 태그를 정의한다. MenuItem 태그가 child 태그이며, itemValue라는 attribute를 가지고 있다.
Menu 태그를 정의한 Menu.java 파일에서는 ArrayList 변수 addMenuItem 메소드를 하나 만들고 값을 받아 하나씩 추가할 수 있도록 한다. addMenuItem 메소드는 child 태그인 MenuItem 클래스에서 사용할 메소드이다.
MenuItem 태그를 정의한 MenuItem.java에서는 doEndTag 부분에서 parent 객체를 하나 생성한 후 Menu 클래스에 있는 addMenuItem 메소드를 호출해 자신이 가지고 있는 itemValue라는 속성을 넘겨준다.
마지막으로 Menu 클래스의 doEndTag 메소드에서는 child 태그로부터 넘겨 받게 된 값을 화면에 보여준다.



신고

'Java > Servlet & JSP' 카테고리의 다른 글

웹 애플리케이션 보안  (4) 2009.04.10
웹 애플리케이션 배포하기  (0) 2009.04.07
부모 자식 태그간의 통신  (0) 2009.03.26
클래식 커스텀 태그  (0) 2009.03.26
사용자 정의 태그 개발 (1)  (0) 2009.03.23
커스텀 태그 사용하기  (0) 2009.03.17

WRITTEN BY
체리필터
프로그램 그리고 인생...

받은 트랙백이 없고 , 댓글이 없습니다.
secret
JSP2.0 이전 버젼에서의 커스텀 태그는 심플 방식이 아닌 클래식 방식을 사용한다. simple 방식에서는 doTag() 메소드 하나로 모든 작업을 하고, exception 처리도 JspException, IOException를 throw 해서 catch 블럭이 없지만, 클래식 방식에는 doStartTag(), doEndTag() 메소드를 사용하며, JspException만을 throw 해서 catch 블럭에서 IOException을 잡을 필요가 있다.
간단하게 아래 예제를 통해 알아보자

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">

<tlib-version>0.9</tlib-version>

<uri>KathyClassicTags</uri>
<tag>
    <description>ludicrous use of a Classic tag</description>
    <name>classicOne</name>
    <tag-class>com.example.tag.Classic1</tag-class>
    <body-content>empty</body-content>
</tag>
</taglib>

com.example.tag.Classic1.java 파일

package com.example.tag;

import java.io.IOException;

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

public class Classic1 extends TagSupport {
    JspWriter out;
   
    public int doStartTag() throws JspException {
        out = pageContext.getOut();
        try {
            out.println("in doStartTag()");
        } catch (IOException e) {
            // TODO: handle exception
            throw new JspException("IOException - " + e.toString());
        }
        return SKIP_BODY;
    }
   
    public int doEndTag() throws JspException {
        try {
            out.println("in doEndTag");
        } catch (IOException e) {
            // TODO: handle exception
            throw new JspException("IOException - " + e.toString());
        }
        return EVAL_PAGE;
    }
}

closeTag1.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib prefix="mine" uri="KathyClassicTags" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
Classic Tag One : <br>
<mine:classicOne/>
</body>
</html>

Classic1 클래스를 보면 SimpleTagSupport가 아닌 TagSupport를 확장한다. 또한 getJspContext 대신에 pageContext를 사용한다.

doStartTag() 메소드에서 SKIP_BODY를 리턴 하는 것은 컨테이너가 다음에 어떤 일을 수행하도록 알려주는 것이다. 이 뜻은 body가 있더라도 실행하지 말고 곧바로 doEndTag()로 가라는 뜻이다.
화면에 print 해보면 해당 값이 0이라는 것을 알 수 있다.

또한 doEndTag() 메소드에서는 EVAL_PAGE를 리턴 하는데, 이 뜻은 작업이 끝났으니 페이지 뒷 부분을 실행하라는 의미이다.
심플 태그 핸들러의 SkipPageException과 비슷한 의미이다.

태그에 몸체가 있는 경우 몸체 안의 내용은 다음처럼 사용할 수 있다.

<?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">

<tlib-version>0.9</tlib-version>

<uri>KathyClassicTags</uri>
<tag>
    <description>ludicrous use of a Classic tag</description>
    <name>classicOne</name>
    <tag-class>com.example.tag.Classic1</tag-class>
    <body-content>tagdependent</body-content>
</tag>
</taglib>

com.example.tag.Classic1.java 파일

package com.example.tag;

import java.io.IOException;

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

public class Classic1 extends TagSupport {
    JspWriter out;
   
    public int doStartTag() throws JspException {
        out = pageContext.getOut();
        try {
            out.println("in doStartTag()");
            out.println("SKIP_BODY : " + SKIP_BODY);
            out.println("EVAL_BODY_INCLUDE : " + EVAL_BODY_INCLUDE);
        } catch (IOException e) {
            // TODO: handle exception
            throw new JspException("IOException - " + e.toString());
        }
        //return SKIP_BODY;
        return EVAL_BODY_INCLUDE;
    }
   
    public int doEndTag() throws JspException {
        try {
            out.println("in doEndTag");
            out.println("EVAL_PAGE : " + EVAL_PAGE);
        } catch (IOException e) {
            // TODO: handle exception
            throw new JspException("IOException - " + e.toString());
        }
        return EVAL_PAGE;
    }
}


closeTag1.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib prefix="mine" uri="KathyClassicTags" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
Classic Tag One : <br>
<mine:classicOne>
This is the body
</mine:classicOne>
</body>
</html>

Insert title here결과물

Insert title hereClassic Tag One :
in doStartTag() SKIP_BODY : 0 EVAL_BODY_INCLUDE : 1 This is the body in doEndTag EVAL_PAGE : 6

EVAL_BODY_INCLUDE는 몸체를 실행 시키라는 내용이며, 화면에 print 해 보면 1이라는 것을 알 수 있다. EVAL_PAGE의 값은 6이다.

심플 태그에서는 doTag 안에서 iterator를 실행 하면서 getJspBody().invoke(null)을 실행하면 루핑을 돌리면서 반복적인 작업을 할 수 있었다.
클래식 커스텀 태그에서는 doStartTag와 doEndTag로는 iterator 작업을 할 수 없으므로, doAfterTag를 이용할 수 밖에 없다. doAfterTag는 doStartTag에서 EVAL_BODY_INCLUDE를 리턴 하는 경우에만 실행 된다.
관련 소스는 아래를 참고하면 된다.

myCustomTag2.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">

<tlib-version>0.9</tlib-version>

<uri>KathyClassicTags2</uri>
<tag>
    <description>ludicrous use of a Classic tag</description>
    <name>iterateMovies</name>
    <tag-class>com.example.tag.Classic2</tag-class>
    <body-content>scriptless</body-content>
</tag>
</taglib>

Classic2.java

package com.example.tag;

import java.io.IOException;

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

public class Classic2 extends TagSupport {
    String[] movies = new String[] {"Spiderman", "Saved!", "Amelie"};
    int movieCounter;
   
    public int doStartTag() throws JspException {
        movieCounter = 0;

        pageContext.setAttribute("movie", movies[movieCounter]);
        movieCounter++;
       
        return EVAL_BODY_INCLUDE;
    }
   
    public int doAfterBody() throws JspException {
        if(movieCounter < movies.length) {
            pageContext.setAttribute("movie", movies[movieCounter]);
            movieCounter++;
            return EVAL_BODY_AGAIN;
        } else {
            return SKIP_BODY;
        }
    }
   
    public int doEndTag() throws JspException {
        return EVAL_PAGE;
    }
}

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib prefix="mine" uri="KathyClassicTags2" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<table border="1">
<mine:iterateMovies>
    <tr><td>${movie}</td></tr>
</mine:iterateMovies>
</table>
</body>
</html>

doStartTag()에서는 EVAL_BODY_INCLUDE를 리턴하며 따라서 doAfterBody()를 호출하게 된다. doAfterBody 안에서는 movies 배열을 이용해 iterator 하면서 movie 객체에 값을 담는다. movieCounter가 movies의 길이만큼 루프를 돌게 되면 SKIP_BODY를 리턴 하면서 doEndTag를 호출하게 된다.
유의 할 점은 doAfterTag는 body가 한번 호출된 후부터 호출 되므로, doStartTag에서 "pageContext.setAttribute("movie", movies[movieCounter]);"를 한번 호출 한다.
doStartTag에서 호출하지 않을 경우 빈 값으로 <tr> 부분이 한번 iterator를 하기 때문에 빈 row가 하나 들어가게 된다.

movieCounter를 doStartTag 안에서 0으로 초기화 하는 것은 컨테이너가 풀(pool)로 관리하기 때문이다. 선언하면서 바로 초기화를 하게 되면, 재사용 될 경우에는 0으로 시작하지 않고 doAfterTag 의 iterator가 끝날 때 가지고 있는 값을 사용하게 될 것이기 때문이다.









신고

'Java > Servlet & JSP' 카테고리의 다른 글

웹 애플리케이션 배포하기  (0) 2009.04.07
부모 자식 태그간의 통신  (0) 2009.03.26
클래식 커스텀 태그  (0) 2009.03.26
사용자 정의 태그 개발 (1)  (0) 2009.03.23
커스텀 태그 사용하기  (0) 2009.03.17
JSTL 사용하기 (2)  (0) 2009.03.16

WRITTEN BY
체리필터
프로그램 그리고 인생...

받은 트랙백이 없고 , 댓글이 없습니다.
secret
<jsp:include> 표준 액션 또는 <c:import> JSTl과 같은 기능을 하는 태그 파일을 만들어 보자.

<img src="http://wstatic.naver.com/w9/lg_naver_v3.gif"><br>

위와 같이 코딩 한 후 WEB-INF 아래 tags란 디렉토리를 만들어 Header.tag 파일로 저장한다.
그리고 난 후 우리가 url에 호출할 파일을 만들어 보자.

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib prefix="myTags" tagdir="/WEB-INF/tags" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<myTags:Header></myTags:Header>
Welcome to our site.
</body>
</html>

위와 같이 만든 다음 DocumentRoot 아래 customTag란 디렉토리 안에 customTag.jsp란 파일로 만들었다.
브라우져에 http://localhost:8080/customTag/customTag.jsp를 호출하면 아래와 같은 모습이 보여진다.


위에서 <myTags:Header></myTags:Header> 라고 사용한 부분을 보면 파일명이 바로 Tag 명이 된 것을 알 수 있다.
또한 <jsp:include> 표준액션에서 param을 사용한 것처럼 사용할 수 있다.

customTag.jsp

<jsp:include page="Header.jsp">
    <jsp:param name="subTitle" value="We take the sting out of SOAP"/>
</jsp:include>

Header.jsp

<img src="http://wstatic.naver.com/w9/lg_naver_v3.gif"><br>
<em><strong>${param.subTitle}</strong></em>

표준 액션을 사용하면 위와 같이 할 수 있다. 태그를 사용하면 아래와 같이 사용하면 된다.

customTag.jsp

<myTags:Header subTitle="We take the sting out of SOAP" />
Welcome to our site.

Header.tag

<%@ attribute name="subTitle" required="true" rtexprvalue="true" %>
<img src="http://wstatic.naver.com/w9/lg_naver_v3.gif"><br>
<em><strong>${subTitle}</strong></em>

attribute로 넘어온 값은 param 이라는 이름 없이 ${subTitle} 과 같이 바로 사용하면 된다. 또한 사용하기 위해서는 상단에 "<%@ attribute name="subTitle" required="true" rtexprvalue="true" %>" 와 같이 attribute 정의를 해 놔야 한다.
tld에 정의한 바와 같이 required는 필수 여부, rtexprvalue는 표현식 사용 여부를 나타내는 것이다.

속성으로 넘겨야 할 내용이 길다면 다음과 같이 사용할 수 있다.

customTag.jsp

<myTags:Header fontColor="#660099" subTitle="We take the sting out of SOAP">
Welcome to our site.
Welcome to our site.
Welcome to our site.
Welcome to our site.
Welcome to our site.
Welcome to our site.
Welcome to our site.
Welcome to our site.
Welcome to our site.
</myTags:Header>

Header.tag

<%@ attribute name="fontColor" required="true" %>
<%@ tag body-content="tagdependent" %>

<em><strong><font color="${fontColor}"><jsp:doBody></jsp:doBody></font></strong></em>

body-content에 들어가는 내용은 tld 정의에서 배운 내용 그대로이다.

컨테이너가 태그 파일을 찾는 위치는 4군데이다.

1. WEB-INF/tags 바로 밑
2. WEB-INF/tags의 하위 디렉토리
3. WEB-INF/lib에 JAR 파일로 배포되었다면, JAR파일 META-INF/tags 밑에
4. WEB-INF/lib에 JAR 파일로 배포되었다면, JAR파일 META-INF/tags의 하위 디렉토리

태그 파일이 JAR 파일로 배포 되었다면, 반드시 TLD 파일이 있어야 한다.

태그 파일만으로 부족할 경우에는 자바 클래스를 이용한 사용자 정의 태그를 만들 수 있다. http://www.4te.co.kr/566에서 이미 만들어 본 내용이지만 다시 한번 정리하면 아래와 같다.

package com.example;

import java.io.IOException;

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

public class simpleTagTest1 extends SimpleTagSupport {
    public void doTag() throws JspException, IOException {
        getJspContext().getOut().print("This is the lamest use of a custom tag");
    }
}

/WEB-INF/simpleTag.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">

<tlib-version>1.2</tlib-version>
<uri>simpleTags</uri>
<tag>
    <description>worst use of a custom tag</description>
    <name>simple1</name>
    <tag-class>com.example.simpleTagTest1</tag-class>
    <body-content>empty</body-content>
</tag>

</taglib>

/customTag/customTag2.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib prefix="myTags" uri="simpleTags" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<myTags:simple1/>
</body>
</html>

설명은 http://www.4te.co.kr/566 에서 설명한 내용을 참고하면 된다.
몸체가 있는 태그일 경우에는 아래와 같이 하면 된다.

package com.example;

import java.io.IOException;

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

public class simpleTagTest1 extends SimpleTagSupport {
    public void doTag() throws JspException, IOException {
        //getJspContext().getOut().print("This is the lamest use of a custom tag");
        getJspBody().invoke(null);    //태그 몸체를 읽은 후 응답에 출력하라는 의미, 인자가 null이므로 Response로 출력하라는 의미
    }
}

<?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">

<tlib-version>1.2</tlib-version>
<uri>simpleTags</uri>
<tag>
    <description>worst use of a custom tag</description>
    <name>simple1</name>
    <tag-class>com.example.simpleTagTest1</tag-class>
    <body-content>scriptless</body-content>
</tag>

</taglib>

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib prefix="myTags" uri="simpleTags" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<myTags:simple1>
    This is the body
</myTags:simple1>
</body>
</html>

태그 몸체에 표현식이 있을 경우에는 다음과 같이 할 수 있다.

<myTags:simple1>
    This is the body ${message}
</myTags:simple1>

public class simpleTagTest1 extends SimpleTagSupport {
    public void doTag() throws JspException, IOException {
        //getJspContext().getOut().print("This is the lamest use of a custom tag");
        getJspContext().setAttribute("message", "Wear sunscreen");
        getJspBody().invoke(null);
    }
}

동적으로 테이블 행을 출력하는 태그를 만들어 보면 아래와 같이 하면 된다.

public class simpleTagTest1 extends SimpleTagSupport {
    String[] movies = {"Monsoon Wedding", "Saved!", "Fahrenheit 9/11"};
    public void doTag() throws JspException, IOException {
        //getJspContext().getOut().print("This is the lamest use of a custom tag");
        //getJspContext().setAttribute("message", "Wear sunscreen");
       
        for(int i=0 ; i<movies.length ; i++) {
            getJspContext().setAttribute("movie", movies[i]);
            getJspBody().invoke(null);
        }
    }
}

<table>
<myTags:simple1>
    <tr><td>${movie}</td></tr>
</myTags:simple1>
</table>

태그 속성이 반드시 있어야 한다고 TLD에서 설정했다면, 태그핸들러 클래스에서는 Bean 스타일의 Setter가 있어야 한다.

<%@ taglib prefix="myTags" uri="simpleTags5" %>
<myTags:simple1 movieList="${movieCollection}">
    <tr>
        <td>${movie.name}</td>
        <td>${movie.gener}</td>
    </tr>
</myTags:simple1>

package com.example;

import java.io.IOException;
import java.util.Iterator;
import java.util.List;

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

public class simpleTagTest5 extends SimpleTagSupport {
    private List<String> movieList;

    public void setMovieList(List<String> movieList) {
        this.movieList = movieList;
    }
   
    public void doTag() throws JspException, IOException {
        Iterator<String> i = movieList.iterator();
       
        while(i.hasNext()) {
            Movie movie = (Movie) i.next();
            getJspContext().setAttribute("movie", movie);
            getJspBody().invoke(null);
        }
    }
}

<?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">

<tlib-version>1.2</tlib-version>
<uri>simpleTags5</uri>
<tag>
    <description>worst use of a custom tag</description>
    <name>simple1</name>
    <tag-class>com.example.simpleTagTest5</tag-class>
    <body-content>scriptless</body-content>
    <attribute>
        <name>movieList</name>
        <required>true</required>
        <rtexprvalue>true</rtexprvalue>
    </attribute>
</tag>

</taglib>


어떤 태그를 호출 했을 경우, 오류가 떨어지더라도 지금까지 출력 된 내용은 화면에 나와야 한다면 SkipPageException을 사용할 수 있다.

getJspContext().getOut().print("Message from within doTag()<br>");
getJspContext().getOut().print("About to throw a SkipPageException");

if(thingsDontWork) {
    throw new SkipPageException();
}

<myTags:simple/>
Back in the page after invoking the tag.

위 클래스에서 thingsDontWork가 참이라서 SkipPageException이 던져지게 되면, 그 이전에 출력하려 했던 "Message from within doTag()<br>About to throw a SkipPageException은 나오지만, "Back in the page after invoking the tag."은 출력되지 않는다.

다음과 같이 하게 됬을 경우 나오게 되는 내용에 주의해야 한다.

pageA.jsp

aaaa<br>
<jsp:include page="pageB.jsp"></jsp:include>
after aaaa<br>

pageB.jsp

<%@ taglib prefix="myTags" uri="simpleTags" %>
bbbb<br>
<myTags:simple1></myTags:simple1>
after bbbb<br>

doTag() 메소드

    public void doTag() throws JspException, IOException {
        getJspContext().getOut().print("in doTag()<br>");
        throw new SkipPageException();
    }

pageB 안에 있는 myTags.simple1 태그는 doTag() 메소드를 호출 할 것이며 doTag 메소드에서는 SkipPageException을 throw 할 것이다.
이럴 경우에는 pageB.jsp에서만 처리가 중지 되며, pageA.jsp에서는 그대로 나머지 내용이 출력된다.
즉 다음과 같이 내용이 나오게 될 것이다.

aaaa
bbbb
in doTag()
after aaaa

즉, after bbbb 라는 내용은 나오지 않게 된다.


신고

'Java > Servlet & JSP' 카테고리의 다른 글

부모 자식 태그간의 통신  (0) 2009.03.26
클래식 커스텀 태그  (0) 2009.03.26
사용자 정의 태그 개발 (1)  (0) 2009.03.23
커스텀 태그 사용하기  (0) 2009.03.17
JSTL 사용하기 (2)  (0) 2009.03.16
JSTL 사용하기 (1)  (5) 2009.03.12

WRITTEN BY
체리필터
프로그램 그리고 인생...

받은 트랙백이 없고 , 댓글이 없습니다.
secret
사용자 정의 태그를 만들어서 사용할 수 있다.
사용 방법은 EL에서 함수를 만드는 방법과 유사하나 조금 더 복잡한 부면이 있다.
커스텀 태그를 만들기 위해서는 tld 파일과 java class 파일이 필요하다.
예제로 유저에게 랜덤하게 조언을 해 주는 커스텀 태그 소스를 보면 이해하는데 도움이 된다.(소스는 역시 Head & First Servelet & JSP에서 사용된 것이다.)

우선 tld 파일은 EL과 마찬가지로 WEB-INF 밑에 작성한다. 이름은 myCustomTag.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">

<tlib-version>0.9</tlib-version>

<short-name>RandomTags</short-name>
<function>
    <name>rollIt</name>
    <function-class>com.example.DiceRoller</function-class>
    <function-signature>int rollDice()</function-signature>
</function>

<uri>randomThings</uri>
<tag>
    <description>random advice</description>
    <name>advice</name>
    <tag-class>com.example.AdvisorTagHandler</tag-class>
    <body-content>empty</body-content>
    <attribute>
        <name>user</name>
        <required>true</required>
        <rtexprvalue>true</rtexprvalue>
    </attribute>
</tag>
</taglib>

태그 이름은 <name> 태그의 내용을 사용하며 해당 태그가 호출될 경우 사용하는 java class 파일은 <tag-class> 태그에 있는 클래스를 사용한다.
<body-content>가 empty인 것은 몸체가 없이 사용한다는 뜻이며, 속성으로 사용되는 것으로 user라는 것이 있다는 의미이다.
rtexprvalue가 true인 것은 EL과 같은 표현식(스크립팅, 표준액션 포함) 값이 들어갈 수 있다는 뜻이다. 만일 rtexprvalue가 false라면 EL 표현식은 사용 불가이다.
위 내용을 jsp 페이지에서 커스텀 태그로 사용한다면 아래와 같이 사용할 수 있다.

<%@ taglib prefix="mine" uri="randomThings" %>

<c:set var="userName" value="오봉근"></c:set>
<mine:advice user="${userName}" />

위와 같이 쓰게 된다면 AdvisorTagHandler 클래스에서는 user라는 변수를 사용하여 어떤 액션을 하게 될 것이다.
AdvisorTagHandler 클래스의 소스는 아래와 같다.

com.example.DiceRoller.java 파일
package com.example;

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

public class AdvisorTagHandler extends SimpleTagSupport {
    private String user;
   
    public void doTag() throws JspException, IOException {
        getJspContext().getOut().write("Hello " + user + " <br>");
        getJspContext().getOut().write("Your advice is : " + getAdvice());
    }
   
    public void setUser(String user) {
        this.user = user;
    }
   
    String getAdvice() {
        String[] adviceStrings = {"That color's not working for you", "You should call in sick", "You might want to rethink that haircut."};
        int random = (int) (Math.random() * adviceStrings.length);
       
        return adviceStrings[random];
    }
}


위 클래스에서 주의 해야 할 점은 doTag 메소드이다.
JSP가 태그를 실행하게 되면 컨테이너는 자동으로 doTag 메소드를 실행하게 된다. EL에서 메소드 명을 지정할 수 있었던 것과 다르다.
또 주의해서 볼 것은 setUser 메소드이다. 이름에서 볼 수 있듯이 자바 빈 프로퍼티 명명 규칙을 따서 사용하게 된다. 즉 커스텀 태그에서 사용하는 attribute의 이름을 빈 프로퍼티로 사용하게 된다.

태그 몸체에 들어갈 수 있는 내용들은 아래와 같다.

<body-content>empty</body-content>
=> 몸체를 가질 수 없다.

<body-content>scriptless</body-content>
=> 스크립팅(스크립틀릿, 스크립팅 표현식, 선언문)은 올 수 없다. 하지만 템플릿 텍스트, EL, 커스텀 태그, 표준 액션은 가능하다.

<body-content>tagdependent</body-content>
=> 태그 몸체를 그냥 텍스트로 취급한다.

<body-content>JSP</body-content>
=> JSP 안에 들어갈 수 있는 것이라면 무엇이든지 가능하다.

<body-content>empty</body-content>라고 되어 있어도 jsp 표준액션을 사용하면 body에 내용을 기술 할 수 있다.

<mine:advice>
    <jsp:attribute name="user">${userName}</jsp:attribute>
</mine:advice>

<jsp:attribute> 태그는 속성을 기술하는 또 하나의 방식이므로, body content 개수로 치지 않으며, 따라서 시작 태그와 마침 태그에 들어갈 수 있다.

taglib에 들어가는 uri는 실제 uri(위치정보)가 아니다. 다른 태그 라이브러리와 구별하기 위한 유일한 값을 지정하기 위해 사용하는 이름일 뿐이다.
uri와 실제 TLD 파일은 컨테이너가 알아서 맵핑한다. 하지만 jsp 2.0 이전 버젼에서는 web.xml에 맵핑 정보를 적어 줘야 했었다.

  <jsp-config>
      <taglib>
          <taglib-uri>randomThings</taglib-uri>
          <taglib-location>/WEB-INF/</taglib-location>
      </taglib>
  </jsp-config>

jsp 2.0 버전에서는 사용하지 않아도 컨테이너가 알아서 uri 이름에 대한 맵을 만든다는 의미이지, 위 내용을 web.xml에 기술 안해야지만 된다는 의미는 아니다. web.xml에 기술을 하게 된다면 해당 내용을 사용하게 되며, 없을 경우 자동으로 searching을 하게 된다.
컨테이너가 자동으로 TLD 파일을 찾는 위치는 다음과 같다.

1. WEB-INF 안
2. WEB-INF 아래 하위 디렉토리
3. WEB-INF/lib 밑에 jar 파일로 배포 했다면 jar 안 META-INF 디렉토리
4. WEB-INF/lib 밑에 jar 파일로 배포 했다면 jar 안 META-INF 아래 하위 디렉토리

jsp에서 여러개의 태그라이브러리를 사용한다면, 각각의 TLD에 대한 uri를 작성해야 한다. uri는 유일해야 하며, 같은 값을 중복해서 사용할 수 없다.
또한 예약어를 첨자로 사용할 수 없다.

jsp:, jspx:, java:, javax:, servlet:, sun:, sunw:




신고

'Java > Servlet & JSP' 카테고리의 다른 글

클래식 커스텀 태그  (0) 2009.03.26
사용자 정의 태그 개발 (1)  (0) 2009.03.23
커스텀 태그 사용하기  (0) 2009.03.17
JSTL 사용하기 (2)  (0) 2009.03.16
JSTL 사용하기 (1)  (5) 2009.03.12
템플릿 형태로 JSP 사용하기  (0) 2009.02.16

WRITTEN BY
체리필터
프로그램 그리고 인생...

받은 트랙백이 없고 , 댓글이 없습니다.
secret
클라이언트의 브라우져에서 쿠키 사용을 제한 하고 있을 경우 jsessionid를 추가하여 url로 세션 정보를 공유하는 방법은 이미 서블릿에서 살펴 봤다.
jstl에서도 이와 같은 방법을 사용할 수 있다.

서블릿
response.encodeURL("/BeerTest.do");

jstl
<c:url value="/inputCommets.jsp"></c:url>

위와 같이 하게 되면 url 뒤에 jsessionid를 덧 붙여서 사용하게 된다.
하지만 urlencoding을 자동으로 하지는 않게 된다.
urlencoding을 하게 하려면 아래와 같은 방법을 사용해야 한다.

<c:set var="last" value="Hidden Cursor"></c:set>
<c:set var="first" value="Crouching Pixels"></c:set>
<c:url value="/inputCommets.jsp">
    <c:param name="firstName" value="${first}"></c:param>
    <c:param name="lastName" value="${last}"></c:param>
</c:url>

위와 같이 하게 되면 last, first에 설정 된 값에 있는 공백과 같은 값이 인코딩 되어 사용 된다.

* 오류 페이지 만들기

오류 메시지를 그대로 보여주지 않고 디자인 된 페이지를 보여주려면, 예외 사항이 발생하는 페이지에 다음과 같이 코딩해 주면 된다.

<%@ page errorPage="errorPage.jsp" %>
<% int x = 10/0; %> -> 예외 발생

에러 시 보여줄 페이지

<%@ page isErrorPage="true" %>
<body>
Error Page!!!
</body>

하지만, 모든 페이지에서 <%@ page errorPage="errorPage.jsp" %> 내용을 삽입하게 된다면 여간 귀찮은 일이 아닐 것이다. 따라서 configuration에서 error page를 지정하는 방법을 써서 수고를 덜 수 있다.

web.xml

  <error-page>
      <exception-type>java.lang.Throwable</exception-type>
      <location>/errorPage.jsp</location> => 일반적인 에러
  </error-page>
  <error-page>
      <exception-type>java.lang.ArithmeticException</exception-type>
      <location>/arithmeticError.jsp</location> => 특수한 경우의 에러
  </error-page>
  <error-page>
      <error-code>404</error-code>
      <location>/notFoundError.jsp</location> => 에러 코드에 따른 경우
  </error-page>

물론 web.xml에서 error page임을 명시해도 errorPage.jsp 파일에서는 "<%@ page isErrorPage="true" %>" 내용을 꼭 넣어야 한다.
errorPage.jsp에서는 exception 객체를 사용할 수 있다.
사용 방법은 다음과 같이 쓴다.

<%@ page isErrorPage="true" %>
You caused a ${pageContext.exception} on the Server.

Insert title hereError Page!!! You caused a java.lang.ArithmeticException: / by zero on the Server.

위의 예와 같은 경우에는 위와 같이 브라우져에 출력되게 된다.

오류가 났을 경우 오류 페이지로 가지 않고 catch로 잡을 수도 있다.
방법은 다음과 같다.

<c:catch>
    Inside the catch
    <% int x = 10/0; %>
</c:catch>

오류가 난 원인을 알기 위해서는 exception 객체를 사용해야 하는데, isErrorPage로 설정되지 않은 jsp에서는 exception 객체를 사용할 수 없다. 따라서 다음과 같이 사용해야 한다.

<c:catch var="myException">
    Inside the catch
    <% int x = 10/0; %>
</c:catch>

<c:if test="${myException != null}">
    There was an exception : ${myException.message}<br>
</c:if>

Insert title hereThere was an exception : / by zero

jstl에서 사용되는 5개의 라이브러리 중에서 자주 사용되는 태그는 다음과 같다.

* Core 라이브러리

<c:out>, <c:set>, <c:remove>, <c:catch>

<c:if>, <c:choose>, <c:when>, <c:otherwise>

<c:import>, <c:url>, <c:redirect>, <c:param>

<c:forEach>, <c:forTokens>

* 포맷팅 라이브러리

<fmt:message>, <fmt:setLocale>, <fmt:bundle>, <fmt:setBundle>, <fmt:param>, <fmt:requestEncoding>

<fmt:timeZone>, <fmt:setTimeZone>, <fmt:formatNumber>, <fmt:parseNumber>, <fmt:parseDate>

* SQL 라이브러리

<sql:query>, <sql:update>, <sql:setDataSource>, <sql:param>, <sql:dateParam>

* XML 라이브러리

<x:parse>, <x:out>, <x:set>

<x:if>, <x:choose>, <x:when>, <x:otherwise>, <x:forEach>

<x:transform>, <x:param>





신고

'Java > Servlet & JSP' 카테고리의 다른 글

사용자 정의 태그 개발 (1)  (0) 2009.03.23
커스텀 태그 사용하기  (0) 2009.03.17
JSTL 사용하기 (2)  (0) 2009.03.16
JSTL 사용하기 (1)  (5) 2009.03.12
템플릿 형태로 JSP 사용하기  (0) 2009.02.16
EL 함수 사용하기  (0) 2009.02.13

WRITTEN BY
체리필터
프로그램 그리고 인생...

받은 트랙백이 없고 , 댓글이 없습니다.
secret
jsp에서 스크립팅을 사용하지 않고 루프를 돌리거나 조건문을 실행하는 방법으로 사용하는 것이 JSTL이다.
JSTL을 사용하기 위해서는 다음과 같은 방법으로 설정을 해 줘야 한다.

apache-tomcat-6.0.18\webapps\examples\WEB-INF\lib 에 있는 jstl.jar 파일과 standard.jar 파일을 WebContent/WEB-INF/lib 밑으로 copy 한다.

위와 같이 하게 되면 jstl을 사용할 수 있다.
jstl을 사용할 수 있게 됬으므로 forEach 문을 돌려보자.
사용 방법은 php에서 사용하는 foreach 문과 별로 다를 바가 없다.

web.xml

  <servlet>
      <servlet-name>jstlTest</servlet-name>
      <servlet-class>com.example.jstlTest</servlet-class>
  </servlet>
  <servlet-mapping>
      <servlet-name>jstlTest</servlet-name>
      <url-pattern>/Jstl</url-pattern>
  </servlet-mapping>


서블릿 코드

package com.example;

import java.awt.List;
import java.io.IOException;
import java.util.ArrayList;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class jstlTest extends HttpServlet {
    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws IOException, ServletException {
        String[] movieList = {"Amelie", "Return of the King", "Mean Girls"};
        request.setAttribute("movieList", movieList);
       
        String[] movies1 = {"Matrix Revolutions", "Kill Bill", "Boondock Saints"};
        String[] movies2 = {"Amelie", "Return of the King", "Mean Girls"};
       
        ArrayList movieList2 = new ArrayList();
        movieList2.add(movies1);
        movieList2.add(movies2);
        request.setAttribute("movies", movieList2);
       
        RequestDispatcher view = request.getRequestDispatcher("jstlTest.jsp");
        view.forward(request, response);
    }
}

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<table>
    <c:forEach var="movie" items="${movieList}" varStatus="movieLoopCount">
        <tr><td>${movieLoopCount.count} : ${movie}</td></tr>
    </c:forEach>
    <c:forEach var="listElement" items="${movies}" varStatus="listCount">
        <c:forEach var="movie" items="${listElement}" varStatus="movieCount">
            <tr><td>${listCount.count}, ${movieCount.count}, ${movie}</td></tr>
        </c:forEach>
    </c:forEach>
</table>
</body>
</html>

서블릿에서 배열이나 ArrayList에 담아서 request 객체에 담아 jsp로 forwarding을 넘긴다.
jsp에서는 "<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>"라고 taglib 지시자를 선언하고 아래 부분에 forEach문을 통해서 해당 내용을 출력한다.
forEach문에서 items를 통해서 서블릿에서 넘겨준 request의 속성을 사용할 수 있으며 배열이나 ArrayList의 각 속성은 var라고 선언한 이름에 담겨 사용되어 진다.
forEach문을 통해 루푸가 도는 동안에는 for문에서 사용되어지는 i와 같은 속성을 varStatus를 통해서 사용할 수 있다.

말로 주저리 주저리 설명하는 것보다 위 소스 코드를 직접 실행해 보는 것이 이해하는데 훨씬 도움이 될 듯 하다.
위 소스를 실행(http://localhost:8080/Jstl)해 보면 아래와 같이 출력된다.

1 : Amelie
2 : Return of the King
3 : Mean Girls
1, 1, Matrix Revolutions
1, 2, Kill Bill
1, 3, Boondock Saints
2, 1, Amelie
2, 2, Return of the King
2, 3, Mean Girls

jstl을 사용한 if문은 다음과 같이 사용할 수 있다.

서블릿 코드
String userType = "member";
request.setAttribute("userType", userType);

jsp 코드
<c:if test="${userType eq 'member'}">
    <jsp:include page="inputComments.jsp"></jsp:include>
</c:if>

test 문을 사용해서 조건부의 내용을 검사한다.
else 문은 따로 없으며 여러 조건 들 중을 검사하거나, else와 같은 경우를 처리하려면 choose, when, ohterwise를 사용하면 된다.

서블릿
String userPref = "safety";
request.setAttribute("userPref", userPref);

jsp 코드
<c:choose>
    <c:when test="${userPref == 'performance'}">
        Performance...
    </c:when>
   
    <c:when test="${userPref == 'safety'}">
        Safety...
    </c:when>
   
    <c:when test="${userPref == 'maintenance'}">
        Maintenance...
    </c:when>
   
    <c:otherwise>
        Otherwise...
    </c:otherwise>
</c:choose>

변수를 셋팅하기 위해서는 set을 사용한다. 사용 방법은 다음과 같다.

<c:set var="userLevel" scope="session" value="Cowboy"></c:set>
userLevel : ${userLevel}<br>
<c:set var="Fido" value="${person.dog}"></c:set>
<c:set var="userLevel" scope="session">
    Sheriff, Bartender, Cowgirl
</c:set>
userLevel : ${userLevel}<br>

<c:set target="${PetMap}" property="dogName" value="Clover"></c:set>
<c:set target="${person}" property="name">
    ${foo.name}
</c:set>

var로 셋팅하는 경우는 변수이며, target인 경우에는 빈이나 맵을 셋팅하게 된다. property는 빈인 경우 프로퍼티가, 맵인 경우에는 키가 된다.
value는 몸체가 없는 경우에는 value property를 사용해서 정의하면 되며, 몸체가 있는 경우에는 그냥 나열하면 된다. value는 꼭 문자열일 필요가 없으며, 객체를 사용할 수 있다.
value가 null일 경우에는 var나 target은 파괴된다.
target에는 실제 객체를 표현하는 표현식이 들어가야 한다. 빈이나 맵의 id 이름을 나타내는 문자열을 기입하면 안된다.

scope는 옵션이며, scope를 표기하지 않을 경우에는 page -> request -> session -> application(context) 순서대로 찾아 나간다. 4군데 모두 없다면, 새롭게 생성하게 된다.

셋팅된 변수를 제거하기 위해서 value를 null로 셋팅해도 되지만, remove 태그를 사용해서 사용하는 것이 정석이다.

<c:set var="userStatus" scope="request" value="Brilliant"></c:set>
userStatus : ${userStatus} <br>
<c:remove var="userStatus" scope="request"/>
userStatus : ${userStatus} <br>

결과물

Insert title hereuserStatus : Brilliant
userStatus :

다른 컨텐츠를 포함하는 jstl 태그는 다음과 같다.

<c:import url="http://www.naver.com/"></c:import>

현재까지 알아본 다른 컨텐츠를 포함하는 방법으로는 include 지시자와 표준액션, 그리고 jstl 태그를 사용하는 방법까지 총 3가지였다.

<%@ include file="Header.html" %>    //include 지시자
<jsp:include page="Header.jsp"></jsp:include>    //include 표준액션

include 지시자는 정적인 페이지를, include 표준 액션은 동적인 페이지를, 그리고 jstl import 태그는 동적인 페이지와 외부 서버에 있는 url 형식의 페이지까지 포함할 수 있다.
include 지시자는 정적인 페이지를 include 하므로 file이란 속성을 사용하며, 표준액션은 동적인 페이지를 include 하므로 page란 속성을 사용한다.
jstl import 태그는 외부 서버에 있는 페이지까지 include할 수 있으므로 url 이란 속성을 사용한다.

<jsp:include> 태그에서 파라미터 값을 넘길 경우 param 태그를 사용하였는데, 그와 같은 기능을 하는 jstl 태그도 있다.

<jsp:include page="Header.jsp">
    <jsp:param name="subTitle" value="We take the sting out of SOAP"/>
</jsp:include>

<c:import url="Header.jsp">
    <c:param name="subTitle" value="We take the sting out of SOAP"></c:param>
</c:import>

Header.jsp

<body>
subTitle : ${param.subTitle}
</body>

Insert title heresubTitle : We take the sting out of SOAP




신고

'Java > Servlet & JSP' 카테고리의 다른 글

커스텀 태그 사용하기  (0) 2009.03.17
JSTL 사용하기 (2)  (0) 2009.03.16
JSTL 사용하기 (1)  (5) 2009.03.12
템플릿 형태로 JSP 사용하기  (0) 2009.02.16
EL 함수 사용하기  (0) 2009.02.13
EL 사용하기  (3) 2009.02.12

WRITTEN BY
체리필터
프로그램 그리고 인생...

받은 트랙백이 없고 , 댓글  5개가 달렸습니다.
  1. 좋은 자료 감사합니다. ^^
  2. 저도 좋은 자료에 감사드립니다 ^^
  3. 잘보고갑니다.^^ 퍼갈게요.
  4. 비밀댓글입니다
secret