2013년 9월 10일 화요일

[Head First]Servlets & JSP 내용정리-9장

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 으로 구현
<%@ taglib prefix=”c” uri=”http://java.sun.com/jsp/jstl/core” %>
<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=”http://xxx.xx.xx/aaa.html” />
<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” ?>
<taglib xmlns=”http://java.sun.com/xml/ns/j2ee
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곳
  1. WEB-INF
  2. WEB-INF 아래 하위 디렉토리 안
  3. WEB-INF/lib 밑 JAR 파일로 배포 했다면 JAR 안 META-INF 디렉토리
  4. WEB-INF/lib 밑 JAR 파일로 배포 했다면 JAR 안 META-INF 아래 하위 디렉토리

JSP가 하나 이상 태그 라이브러리를 사용하는 경우

  • taglib 지시자 uri 이름은 유일 해야 함.
  • 앞 첨자로 다음 예약어는 사용 불가
    • jsp
    • jspx
    • java
    • javax
    • servlet
    • sun
    • sunw

Perl 제대로 배우기 - 11장 (Format)

11. Format
포맷이란 ?
펄은 리포트 언어다? 리포트 언어라고 불리는 이유에 대해서 배운다.
포맷의 사용은 구성
  1. 포맷 정의하기
  2. 출력되어질 데이터를 포맷의 가변부(필드)로 로드하기
  3. 포맷 호출하기

포맷 정의하기
format 선언을 통해서 정의됨. format 선언은 서브루틴과 마찬가지로 프로그램 텍스트의 임의의 장소에 존재 할 수 있다.
format 정의 모양
format someformatname =
fieldline
value_one,value_two,value_three
fieldline
value_one,value_two
fieldline
value_one,value_two,value_three
.

**포맷이름은 파일핸들 이름과 동일하다.
첫번째 행 다음은 0 혹은 그 이상은 텍스트 행으로 구성됨 템플릿이 온다.(템플릿은 여백에 민감하다.)
예)
Hello, my name is @<<<<<<<<<<< :: @<<<<<<<<<<< 는 필드 홀더라고 부른다. 11 문자이면 왼쪽 맞춤 정렬이다.
$name
** 값 행 내의 여백은 무시된다.

실제 포맷 정의
format ADDRESSLABEL =
=============================
|  @<<<<<<<<<<<<<<<<<<<<<<  |
$name
|  @<<<<<<<<<<<<<<<<<<<<<<  |
$address
|  @<<<<<<<<<<<<, @< @<<<<  |
$city,$state,$zip
============================
.

포맷의 호출
포맷은 write 함수로 호출됨.
이 함수는 파일핸들의 이름을 받아서 그 파일 핸들에 대한 현재 포맷을 사용하여 파일 핸들에 대한 텍스트를 생성한다. 디폴트로 파일핸들에 대한 현재 포맷은 동일한 이름의 포맷(STDOUT)
** 파일핸들 이름은 포맷의 이름과 동일함을 주목하라.

open (ADDRESSLABEL,">labels-to-print") || die "can't create";
open (ADDRESSES,"addresses") || die "cannot open addresses";
while (<ADDRESSES>){
       chomp;
       ($name,$address,$city,$state,$zip) = split(/:/);
       write (ADDRESSLABEL);   #출력을 보냄
}

필드홀더에 대한 상세
필드홀더는 @으로 시작한다.
<<<<< :: 왼쪽 맞춤
>>>>> :: 오른쪽 맞춤
||||| :: 중앙 맞춤

산술필드
@로 시작 하나 이상의 # 과 마침표(optional)

복수행 필드
일반적으로 값의 첫번째 뉴라인에서 멈춘다.
@*

충전필드 (filled field) : 채우는 역할을 수행 한다.
@ 대신 ^ (캐럿)을 대신 사용함.
~ : 억제 지시자 , 임의의 행은 그것이 빈행으로 출력되지 않도록 한다.
~~ : 임의행에 대해서 처리 한다. 즉 4개행이 넘어도 가능
예) 여기서 원래 PEOPLE을 STDOUT으로 일부려 변경 했음.
format STDOUT =
Name: @<<<<<<<<<<<< Comment: ^<<<<<<<<<<<<<<<<<<<<<<<<<<<
$name, $comment
~                            ^<<<<<<<<<<<<<<<<<<<<<<<<<<<
$comment
~                            ^<<<<<<<<<<<<<<<<<<<<<<<<<<<
$comment
~                            ^<<<<<<<<<<<<<<<<<<<<<<<<<<<
$comment
.
무한행이 되어도 만족한다.
format STDOUT =
Name: @<<<<<<<<<<<< Comment: ^<<<<<<<<<<<<<<<<<<<<<<<<<<<
$name, $comment
~~                            ^<<<<<<<<<<<<<<<<<<<<<<<<<<<
$comment
.

Top-of-Page 포맷
포맷이름에 _TOP 이 붙은 파일 핸드 이름이다.
디폴트 페이지 길이는 60행

포맷에 대한 디폴트 변경
select()를 이용한 파일 핸들 바꾸기
- STDOUT print에 대해 디폴트이기 때문이다.
select 연산은 점착성이 있음. 다른것을 선택하기 전까지는 지속성이 있다.
select 함수의 리턴값은 이전에 선택된 핸들의 이름이다.
예)
$oldhandle = select (LOGFILE);
print “this goes to LOGFILE\n”;
select ($oldhandle);

포맷이름 바꾸기
특정 파일핸들에 대한 디폴트 포맷이름은 파일핸들과 동일하다.
$~ :: 특별 변수 현재 선택된 파일핸들
Top-of-page 포맷이름 바꾸기
$^ :: top-of-page 포맷을 바꿀 수 있다.
$= :: 페이지 길이 변경
$- :: 페이지 위치 변경