Chapter.09 JSTL 사용하기 (막강한 커스텀 태그)
JSTL이 필요하다.
EL와 표준액션으로는 부족할때
<c:forEach>
- 컬렉션으로 루핑을 돌릴 때
JSP 스크립트으로 구현
<table>
<% String[] items = (String[]) request.getAttribute(“movieList”);
String var = null;
for (int i = 0 ; i < items.length;i++){
var = items[i];
%>
<tr><td><%= var %></td></tr>
<% } %>
</table>
JSTL 으로 구현
<table>
<c:forEach var=”movie” items=”${movieList}” >
<tr><td>${movie}</td></tr>
</c:forEach>
</table>
|
- <c:forEach>의 추가적인 속성 varStatus : javax.servlet.jsp.jstl.core.LoopTagStatus 객체의 인스턴스 변수를 생성
LoopTagStatus.count -> 몇번째 루핑인지 알 수 있음. - <c:forEach>의 추가적인 속성들 begin, end ,step
- <c:forEach> 의 c의 의미는 core
<c:if> : 조건문 만들기
<c:if test=”${userType eq ‘member’}”>
...
</c:if>
|
- else 구문 없다.
<c:choose> ,<c:when>,<c:otherwise>
<c:choose>
<c:when test=”${x == ‘a’}”>
...
</c:when>
<c:when test=”${x == ‘b’}”>
...
</c:when>
<c:otherwise>
...
</c:otherwise>
</c:choose>
|
<c:set>
- 빈 , 맵 모두 사용가능 하다.
- **<jsp:setProperty>는 빈의 프로퍼티만 설정 가능함.
- 두 가지 설정 방식 : var(속성) , target(빈,맵) 동시 사용 불가
- scope는 옵션 없을 경우 디폴트는 page임.
- var 이름으로 속성이 없으면, 자동적으로 생성함. value가 not null 일때
- target이 null이면 컨테이너가 예외 사항을 던짐.
- target 표현식이 빈/맵이 아니면 예외 사항을 던짐.
- target 표현식이 빈이고 property에 명시된값이 없으면 예외 사항처리됨.
주의 할점은 EL은 예외 사항을 보여주지 않으므로 notAPropety라는 예외를 던지게 된다.
var : 속성 var 설정
- 몸체가 [있는 경우/ 없는 경우]
- value값이 null인 경우는 변수가 삭제됨.
몸체가 없는 경우
<c:set var=”userLevel” scope=”session” value=”Cowboy”/>
<c:set var=”Fido” value=”${person.dog}”/>
몸체가 있는 경우
<c:set var=”userLevel” scope=”session”>
Sheriff, Bartender, Cowgirl
</c:set>
|
target : 빈 프로퍼티나 맵 값 설정하기
- target 속성에는 객체(Object)가 들어가야 함. 빈이나 맵의 id가 들어갈수 없음.
몸체가 없는 경우
<c:set target=”${PetMap}” property=”dogName” value=”Clover” />
----------------- ------------------ --------------
a) 널이면 않됨. b) c)
a) null이면 않됨. id이름을 사용하면 않됨.
b) target이 빈이면 프로퍼티 이름, 맵이면 key 이름
c) 설정할 값
몸체가 있는 경우
<c:set target=”${person}” property=”name”>
${foo.name} // 몸체안에 문자열또는 표현식이 들어 갈 수 있음.
</c:set>
|
<c:remove>
주어진 이름에 대한 속성을 제거함.
<c:remove var=”userStatus” scope=”request” />
|
<c:import>
컨텐츠를 포함 시킴
외부자원도 가능함. (실제 구현해 보니 잘되는지 모르겠음.)
<c:import url=”Header.jsp”>
<c:param name=”subTitle” value=”cosmoslight Hello”/>
</c:import>
|
<c:url>
하이퍼링크에 관련된 건을 모두 할 수 있음.(즉 URL 컨테이너의 재작성)
url에 끝에 Jessionid를 추가 하기
<a href=”<c:url value=’/inputComments.jsp’/>”>Click here</a>
|
질의어를 가진 <c:url> 사용
<c:url value=”/inputComments.jsp?first=${first}&last=${last}” var=”inputURL”/>
----------------------------------------------------- ---------------
a) b)
a) URL를 재작성을 함. 그러나 URL 인코딩은 하지 않음.
b) 나중에 이 URL값을 참조 하기 위해서 사용됨.
|
URL 재작성과 인코딩도 하기
<c:url value=”/inputComments.jsp” var=”inputURL”>
<c:param name=”firstName” value=”${first}”/>
<c:param name=”lastName” value=”${last}”/>
</c:url>
|
나만의 오류페이지 만들기
- 개별 페이지 설정 방법
- 오류처리용 페이지(“errorPage.jsp”) : 지시자 사용.. <%@ page isErrorPage=”true” %>
- 예외사항이 발생하는 페이지 : <%@ page errorPage=”errorPage.jsp” %> 사용하여 에러가 발생하면 호출됨.
- DD에 설정하는 방법 : 전체 웹 어플리케이션에 적용됨.
- 모두 다 적용되는(디폴트) 오류 페이지 선언
<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>
|
- HTTP 상태 코드에 따라 다르게 오류 페이지 선언
<error-page>
<error-code>404</error-code>
<location>/notFoundError.jsp</location>
</error-page>
|
- 오류 페이지에서 사용가능한 내장 객체 exception : ${pageContext.exception}
- <%@ page isErrorPage=”true” %> 라고 선언되어 있어야 한다.
- exception은 Throwable class 임. ( stackTrace , message 접근 가능)
- <c:catch> 태그 : 자바의 try/catch , 이것을 사용하면 현재 페이지에서 에러를 처리 한다.
<c:catch var=”myException”> // var를 선택사항 , exception를 myException에 할당함.
<% int x = 10/0; %> //예외 항상 발생.
.. 예외가 발생하면 처리되지 않는 블록
</c:catch>
<c:if test=”${myException != null}”>
예외가 존재함. 메시지는 ${myException.message}
</c:if>
If you see this, we survice
|
JSTL 라이브러리들
코어(Core) 라이브러리
- 일반적인것
- <c:out>
- <c:set>
- <c:remove>
- <c:catch>
- 조건
- <c:fi>
- <c:choose>
- <c:when>
- <c:otherwise>
- URL관련
- <c:import>
- <c:url>
- <c:redirect>
- <c:param>
- 반복
- <c:forEach>
- <c:forEachToken>
포맷팅 라이브러리
- 국제화
- <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:dataParam>
XML 라이브러리
- 코어 XML 액션
- <x:parse>
- <x:out>
- <x:set>
- XML 흐름 제어
- <x:if>
- <x:choose>
- <x:when>
- <x:otherwise>
- <x:forEach>
- 변환 액션
- <x:transfrom>
- <x:param>
JSTL에 없는 태그 라이브러리 사용하기 (즉 Custom Tag Library 사용)
- TLD에는 커스텀 태그에 대한 정의가 들어 있음.
- 필수 사항
- 태그 이름과 문법 : <c:set> --> c 는 prefix, set 태그 이름 , 그리고 나머지 문법은 TLD에 정의됨.
- 라이브러리 URI : 유일한 식별자 URI 이 이름으로 태그 이름과 실행될 자바 코드를 서로 맵핑 한다.
- uri 가 실제 태그 핸들러가 있는 위치를 나타낼 필요는 없음.
- TLD 이해
TLD 정의
<? xml version=”1.0” encoding=”ISO-8859-1” ?>
version=”2.0”>
<tlib-version>0.9</tlib-version>
--------------------------------
필수 항목 (태그가 필수) - 태그 라이브러리 버젼 선언
<short-name>RandomTags</short-name>
-----------------------------------
필수 항목 : 가장 중요하게 사용할 문구
<function>
…
</function>
<uri>randomThings</uri>
-----------------------
taglib 지시자에서 사용할 자신을 나타내는 유일한 이름.
<tag>
<description>radmon advice</description> //[선택] 설명
<name>advice</name> //[필수]태그안에서 사용될 이름, <my:advice>
<tag-class>foo.AdvisorTagHandler</tag-class> //[필수] 태그 호출시 처리하는 클래스
<body-content>empty</body-content> //[필수] 몸체의 종류(empty- 없다는 뜻)
<attribute> //속성이 있는 경우
<name>user</name> //속성명
<required>true</required> // 필수 여부
<rtexprvalue>true</rtexprvalue> // run time expression vluae , 표현식이 들어갈 수 있는 여부
</attribute>
</tag>
</taglib>
태그 사용 JSP
<%@ taglib prefix=”mine” uri=”randomThings” %>
Advisor Page<br/>
<mine:advice user=”${userName}” />
커스텀 태그 핸들러 클래스
packe foo:
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.SimpleTagSupport;
import java.io.IOException;
public class AdvisorTagHandler extends SimpleTagSupport{
private String user;
public void doTag() throws JspException, IOException{
getJspContext().getOut().write(“xxx”);
}
public void setUser(String user){this.user=user;}
그밖에 코드들
}
|
<rtexprvalue> 태그에 대한 추가 설명
- 속성값을 실행시 평가할 것인지, 변환 시 실행 할것인지 결정
- 기본값이 false, 정의되지 않을 때 : 문자열만 사용가능 하다.
- true 일때 - 아래 모두 사용 가능.
- EL표현식 : <mine:advice user=”${userName}/>
- 스크립트 : <mine:advice user=’<%= request.getAttribute(“userName”) %>’ />
- 표준 액션 :
<mine:advice>
<jsp:attribute name=”user”>${userName}</jsp:attribute>
</mine:advice>
<body-content>에 대한 추가 설명
- 들어가는 값들 : empty , scriptless , tagdependent , JSP
- empty : 몸체를 가질 수 없음.
- scriptless : 스크립팅(스크립틀릿, 스크립팅 표현식, 선언문)오지 못함. 그러나 템플릿 텍스트 , EL, 컴스텀 태그, 표준 액션 가능
- tagdependent : 태그를 그냥 텍스트로 취급함.
- JSP : JSP에 들어 갈 수 있는 것은 모두 가능 함.
- 몸체 없는 태그를 호출하는 3가지 방법
- 가장 간다한 태그 : <mine:advice user=”${userName}” />
- 시작, 마침 태그 사이에 아무것도 없는 태그 : <mine:advice user=”${userName}”></mine:advice>
- 시작, 마침 태그 사이에 <jsp:attribute> 만 있는 태그 :
<mine:advice>
<jsp:attribute name=”user”>${userName}</jsp:attribute>
</mine:advice>
컨데이너가 알아서 매핑합니다.
- JSP2.0 이전 uri와 실제 TLD 파일이 있는 위치를 서로 매핑해야 했음. (DD에 설정)
<web-app>
<jsp-config>
<taglib>
<taglib-uri>randomThings</taglib-uri>
<taglib-location>/WEB-INF/myFunction.tld</taglib-location>
</taglib>
</jsp-config>
</web-app>
|
- JSP2.0에서는 taglib 지시와 TLD 파일을 매핑하는 새로운 방법. (DD에 설정 하지 않음.) : 컨테이너가 알아서
컨데이너가 TLD를 찾는 4곳
- WEB-INF
- WEB-INF 아래 하위 디렉토리 안
- WEB-INF/lib 밑 JAR 파일로 배포 했다면 JAR 안 META-INF 디렉토리
- WEB-INF/lib 밑 JAR 파일로 배포 했다면 JAR 안 META-INF 아래 하위 디렉토리
JSP가 하나 이상 태그 라이브러리를 사용하는 경우
- taglib 지시자 uri 이름은 유일 해야 함.
- 앞 첨자로 다음 예약어는 사용 불가
- jsp
- jspx
- java
- javax
- servlet
- sun
- sunw
댓글 없음:
댓글 쓰기