2013년 9월 8일 일요일

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

Chapter.08 스크립트가 없는 JSP

애플리케이션은 속성으로 정보를 공유합니다.

속성이 String 아니고 Object(Bean)객체일 때

서블릿코드 와 JSP 코드
public void doPost(request,response) throws IOException,ServletException{
 foo.Person p = new foo.Person();
 p.setName(“Evan”);
 request.setAttribute(“person”,p);
 RequestDispatcher view = request.getRequestDispatcher(“result.jsp”);
 view.forward(request,response);
}
<html><body>
Person is : <%= request.getAttribute(“person”) %>
</body></html>
------------------------------------------------------
출력 결과는 아래와 Persion 기본적인 toString값을 보여 준다.
Persion is foo.Persion@512d66


출력부분을 수정한 JSP코드(정상출력을 위해서)
JSP
<% foo.Person p = (foo.Person) request.getAttribute(“person”); %>
Person is : <%= p.getName() %>
------------------------------------------------------
표현식
Person is : <%= ((foo.Person) request.getAttribute(“person”)).getName() %>


표준액션을 사용
<html><body>
<jsp:useBean id=”person” class=”foo.Person” scope=”request”/>
----------- ----------  ------------------ ---------------            
a           b           c                  d     
Person is : <jsp:getProperty name=”person” property=”name”/>
           ---------------- ------------- ---------------
           e                f             g       
</body></html>
  1. 표준 액션 <jsp:useBean> : 빈을 선언하고 초기화하는 태그
  2. Bean객체의 식별자를 선언
  3. Bean객체의 클래스 타입을 선언 합니다.(패키지명까지 다 써야 함.)
  4. Bean객체의 생존범위를 지정
  5. 표준 액션 <jsp:getProperty> : 속성 빈 프로퍼티를 읽어오는 태그
  6. 빈 객체 이름을 적습니다, <jsp:useBean>의 “id”에 값과 동일해야 함.
  7. 프로퍼티 이름을 적습니다. 즉 (getter/setter) 찾아냄.
<jsp:useBean>의 특징 : person 이라는 객체를 찾지 못하면 하나 만듬.
request.getSession() 메소드가 (내부적으로 getSession(true)) 행동하는 방식하고 같음.즉 먼저 존재하는지 찾아보고, 없으면 하나 만드는 방식.


** Bean 객체를 생성하고 프로퍼티까지 설정하는 방법 즉 새로운 객체가 만들어질 때만 동작하도록 하도록 할 수 있다. : <jsp:setProperty>를 사용함.
일반적인 set
<jsp:setProperty name=”person” property=”name” value=”Huni”/>


** 새로운 객체 생성시만 설정할때
<jsp:useBean id=”name” class=”foo.Person” scope=”request”>
 <jsp:setProperty name=”person” property=”name” value=”Huni”/>
</jsp:useBean>


빈(Bean) 규약 : 콩 규칙

  1. 반드시 인자없는 public 생성자가 있어야 한다.
  2. 명확한 이름에 setter(설정자)와 getter(접근자)가 이어야 합니다. 예) setFoo() getFoo()
    • boolean 인 경우에는 접근자는 ‘is’~로 시작해야 합니다.
    • 프로퍼티 이름은 get(is),set 제거하는 단어를 첫글자를 소문자로 바꾸면 프로퍼티 이름이 됨.
  3. 설정자의 인자와 접근자의 리턴 형이 동일해야 한다. 그 형이 프로퍼티의 타입이 된다.
  4. 프로퍼티 이름과 타입은 설정자와 접근자에 의해서 결정됨.(클래스 멤버 변수와 상관 없음.)
  5. JSP에 사용하기 위하여, 프로퍼티 타입은 String 이나 Primitve Type 이어야 한다.
    만약 다른 타입을 쓰러고 한다면 표준 액션으로는 할 수 없고 스크립팅을 써야 원하는 바를 얻을 수 있다.


빈 참조에 다형성 기법을 사용하는 방법

Person은 추상화 클래스
<jsp:useBean id=”person” type=”foo.Person” class=”foo.Employee” scope=”page” />
  • class 없이 type만 쓰는 경우 빈이 먼저 존재해야 한다.
  • type에 상관 없이 class가 있을 경우에는 추상화 클래스가 아니고 public 생성자가 있어야 한다.
  • scope 속성의 기본값은 page 입니다.
  • type == 참조 타입 ,선언할 것이므로 추상 객체여도 관계없지만
  • class == 클래스 타입, 인스턴스화 할 것이므로 실제 객체이어야 함.
  • ** <auth-constraint> 처러 위와 반대인것도 있다.


서블릿을 거치지 않고 JSP로 곧바로 요청을 할때 파라미터를 읽는 방법 (쉬운 방법은 param 태크에서)
HTML 폼
<form action=”TestBean.jsp”>
name : <input type=”text” name=”userName”/>
ID#  : <input type=”text” name=”userID” />
<input type=”submit”/>
</form>
표준 액션과 스크립팅을 함께 사용
<jsp:useBean id=”person” type=”foo.Person” class=”foo.Employee” />
<% person.setName(request.getParameter(“userName”)); %>
다른 방법
<jsp:useBean id=”person” type=”foo.Person” class=”foo.Employee”>
 <jsp:setProperty name=”person” property=”name”
   value=”<%request.getParameter(“userName”) %>” />
</jsp:useBean>


속성 param

  • 정의 : param 속성으로 요청 파라미터값을 빈 프로퍼티에 곧바로 설정할 수 있음. (요청 파라미터 이름을 사용해서)
  • 프로퍼티가 String형 이거나 기본형(Primitive Type)인 경우 컨테이너가 알아서 다 해줌.(파싱 과 형변환)
    단 스크립트를 사용한 경우에는 자동으로 변환이 이루어 지지 않는다.


  • param 속성을 사용하기
<jsp:useBean id=”person” type=”foo.Person” class=”foo.Employee”>
 <jsp:setProperty name=”person” property=”name” param=”userName” />
</jsp:useBean>
  • 더 좋은 방법
<jsp:useBean id=”person” type=”foo.Person” class=”foo.Employee”>
 <jsp:setProperty name=”person” property=”name”/>
</jsp:useBean>
단 요청 파라미터 이름과 빈 프로퍼터 이름이 동일한 경우 value 속성이나 param를 명시하지 않아도 컨테이너가 자동적을 설정
  • 빈의 모든 프로퍼티 이름과 요청 파라미터 이름이 같을 때 -> 한방에 해결됨.
<jsp:useBean id=”person” type=”foo.Person” class=”foo.Employee”>
 <jsp:setProperty name=”person” property=”*”/>
</jsp:useBean>


만약 속성이 String형 또는 기본형이 아닌 경우에 정보를 읽어 오는 방법 EL을 사용한다. (JSP 2.0 부터)



EL 표현식 : ${person.dog.name}
아래 코드와 동일
<%= ((foo.Person)request.getAttribute(“person”)).getDog().getName() %>


  • ** EL을 그냥 문자열로 처리하는 방법 /${EL} , 역슬래쉬가 EL을 무시하게 한다.
  • 표현식읠 첫 번째 변수는 내장객체일 수도 있고 속성일 수도 있음을 주의 하라.
  • - 첫번째 변수가 속성이면 page, request, session, application 중 하나에 저장된 속성 이름 입니다.
  • EL 내장객체(대부분이 map 입니다.)
    • pageScope
    • requestScope
    • sessionScope
    • applicationScope
    • param
    • paramValues
    • header
    • headerValues
    • cookie
    • initParam
    • pageContext : map이 아님.

도트(.) 연산자 사용하기

  • 표현식에서 도트 연산자 왼쪽은 반드시 맵 또는 빈이여야 한다.
  • 표현식에서 도트 연산자 오른쪽은 반드시 맵의 키이거나 빈 프로퍼티 이어야 한다.
  • 오른쪽에 오는 값은 식별자로서 일반적인 자바 명명 규칙을 따라야 합니다.

[] 연산자는 도트 연산자 보다 막강합니다.

  • ${person[“name”]}  == ${person.name}
  • 왼쪽에 리스트나 배열도 가능하다.
  • [] 연산자 안의 값이 문자열(“”로 묶여 있다면) 이것은 맵의 키나 빈의 프로퍼티 , 리스트 나 배열 인텍스가 될 수 있음.
  • 배열과 리스트인 경우 문자로 된 인텍스값은 숫자로 바뀜.
  • 사용예 movieList = {“Superman”,”타잔”,”수퍼맨”};
    • ${movieList} : 출력 결과 object의 toString() 값 호출됨.
    • ${movieList[0]} : Superman 출력
    • ${movieList[“1”]} : 타잔 출력
  • 문자열이 아닐때는 그것을 평가 합니다.
  • ${moviceMap[superman]} - superman 이라는 이름을 가진 속성을 찾습니다. 없으면 null을 리턴합니다.
    예)
    Genre 라는 이름을 갖는 속성의 값이 fantasy 라면 값으로
    ${moviceMap[Genre]} --> ${movieMap[“fantasy” ]} 변경됨.
  • [] 안에 내장 표현식을 쓸 수 있다. 예)${movieMap[movieNams[0]]}

EL 내장객체(대부분이 map 입니다.)

  • 생존범위 속성 맵
    • pageScope
    • requestScope
    • sessionScope
    • applicationScope
  • 요청 파라미터 맵
    • param
    • paramValues
  • 요청 헤더 맵
    • header
    • headerValues
  • 쿠기
    • cookie
  • 컨텍스트 초기화 파라미터 맵
    • initParam
  • pageContext 객체에 대한 참조
    • pageContext : map이 아님.

EL 사용예

  • host 헤더 정보 읽기 : ${header[“host”]} 혹은 ${header.host}
  • HTTP 요청 메소드 알아 내기 :  
    • 설명 : resquestScope는 request 정보(property)가 아닌 request 속성을 가지고 온다. 그러므로
      request 정보 pageContext를 통해서 접근 할 수 있음.
    • 예 ) ${pageContext.request.method}
  • 생존 범위 관련 내장 객체를 이용해야 할 때
    • 생존 범위 내에 동일한 이름을 가진 객체 존재 할때 명시적으로 사용된다.
      • 예) ${requestScope.person.name}
    • 속성 이름 문자열 인경우
      • 예) request.setAttribute(“foo.person”,p);
        ${foo.person.name} --> x , foo. 속성이름으로 분석하므로 오류 발생${requestScope[“foo.person”].name}
  • 쿠키 “userName”의 값을 읽기 : ${cookie.userName.value}
  • 컨텍스트 초기화 파라미터 값을 읽기
    • DD의 <context-param> **) 주의 <init-param>이 아니다.
    • 예) ${initParam.mainEmail}

EL 함수(function) 작성 및 사용순서

  1. 정적인 공용 메소드를 제공하는 메소드를 먼저 작성 :
    • 메소드는 반드시 public static 메소드 이어야 하고 , 원만하면 리턴형 이어야 함.(선택사항)
    • 작성한 class는 WEB-INF/classes 하위에 있어야 함.
    • 코드 예제


package foo;
public class DiceRoller{
 public static int rollDice(){
   return (int)((Math.random() * 6) +1);
 }
}
  1. 태그 라이브러리 서술자(TLD:Tag Library Descriptor) 작성
    • 정의 : 함수를 정의한 클래스와 이를 호출할 JSP 매핑해야 함. 확장자는 tld 입니다.
    • 파일 예제


<?xml version=”1.0” encoding=”ISO-8859-1”?>
<taglib xmlns=”http://java.sun.com/xml/ns/j2ee
version=”2.0”>
 <tlib-version>1.2</tlib-version>
 <uri>DiceFunctions</uri>
 <function>
   <name>rollIt</name>
   <function-class>foo.DiceRoller</function-class>
   <function-signature>
     int rollDice()
   </function-signature>
 </function>
</taglib>


  1. JSP에 taglib 지시자를 코딩 합니다.
    • 앞첨자 - 다른이름과 구분 하기위한것(namespace)
    • 파일 예제


<%@ taglib prefix=”mine” uri=”DiceFunctions” %>
<html><body>
${mine:rollIt()}
</body></html>


  1. 함수를 호출하는 EL를 작성함. : ${prefix:name()}


EL함수 배포

  • WEB-INF 디렉토리나 그 하위 디렉토리


EL 연산자

  • 산술 연산자 (5)
    • 더하기 : +
    • 빼기 : -
    • 곱하기: *
    • 나누기 : / 와 div (0으로 나누면 결과 오류가 아닌 infinity가 나옴.
    • 나머지 : % 와 mod
  • 논리 연산자 (3)
    • AND : && 와 and
    • OR : || 와 or
    • NOT : ! 와 not
  • 관계연산자(6)
    • 등호 :  == 와 eq
    • 부등호 : != 와 ne
    • ~보다 작다 : < 와 lt
    • ~보다 크다 : > 와 gt
    • ~보다 작거나 같다 : <= 와 le
    • ~보다 크거나 같다 : >= 와 ge


EL 식별자

  • true : 부울린 문자
  • false : 부울린 문자
  • null : null을 의미
  • instanceof : 향후를 위한 예약
  • empty : null 이거나 비어 있는지 체크하기 위한 연산자


EL은 null을 아주 자연스럽게 처리합니다.

  • 속성/프로퍼티/키 등을 못 찾을때 : 빈문자열
  • 산출연산에서는 0으로 처리
  • 논리연산에서는 false으로 처리


페이지 재사용하기

  • include 지시자
    • 형식 : <%@ include file=”Header.jsp” %>
    • 포함 시기 : 변환하기 바로 직접에 소스를 추가함.
    • ** 최신 컨데이너들은 파일내용이 변경되는 자동으로 재변환 하나 이 기능을 표준에 정의 되어 있지 않으므로 주의
    • 최초 요청시에는 많은 작업(변환 -> 컴파일 -> 로딩)을 하나 두번째 요청 부터는 기능 처리만 한다.
    • 만약 동적인 페이지 이라면 단 한번만 평가되므로 (EL 함수나 평가 구문이 들어간 경우) 주의 하라.
  • 지시자중 유일하게 위치가 중요함 : 항상 포함될곳에 위치 해야 한다.
    • <jsp:include> 표준 액션
    • 형식 : <jsp:include page=”Header.jsp” />
    • 포함 시기 : 실행(런타임)시 응답(Response)에 추가
    • 항상 새롭게 포함 되므로 파일 내용이 변경될이 없는 경우에는 성능 손해를 본다.
    • 변환 작업이 없으므로 매번 요청 마다 할일 많음.


페이지 재사용 주의 사항

  • 재사용할 페이지는 <html><body> 사용하지 마라
  • 재사용 페이지로 파라미터 넘겨 주기


Main JSP
<jsp:include page=”Header.jspf”>
 <jsp:param name=”subTitle” value=”We …”/>
</jsp:include>
Header.jspf
<em><strong>${param.subTitle}</strong></em>

<jsp:forward /> 표준 액션


  • 역할 : JSP에서 다른 JSP(서블릿,다른 웹 애플리케이션)로 요청을 넘길 수 있습니다.
  • 형식 : <jsp:forward page=”HandleIt.jsp” />
  • 주의 사항
    • forward 전에 작성한 것은 foward가 일어난 다음에는 모두 삭제 됨.(응답 버퍼를 지우기 때문)
    • forward전에 <% out.flush(); %>를  사용하지 마라 사용하는 forward도 되지 않는다.

댓글 없음: