공부/JSF2014. 10. 6. 03:14

JSF 라이프 사이클의 상세 설명

이전 블로그 글에서 본 라이프 사이클 이미지를 보면서 각 단계(phase)에 대하여 상세 설명을 하도록 하겠습니다.

JSF 라이프 사이클

JSF 어플리케이션 라이프 사이클의 실행(execute) 단계는 다음의 하위 단계를 포함합니다.

  • 뷰 복원 단계 (Restore View Phase)
  • 요청 값 적용 단계 (Apply Request Values Phase)
  • 검증 처리 단계 (Process Validations Phase)
  • 모델 값 업데이트 단계 (Update Model Values Phase)
  • 어플리케이션 호출 단계 (Invoke Application Phase)
  • 응답 랜더링 단계 (Render Response Phase)

뷰 복원 단계 (Restore View Phase)

JSF 페이지에 대한 요청이 발생 할때 그리고 링크 또는 버튼 컴포넌트를 클릭하는 액션에 의해 JSF 구현은 뷰 복원 단계를 시작합니다.

이 단계에서 JSF 구현은 컴포넌트와 연결된 이벤트 처리기(handler)와 검증기(validator)가 포함된 뷰를 빌드 하여 FacesContext 인스턴스에 저장하는데 이 뷰에는 하나의 요청을 처리하는데 필요한 모든 정보가 포함 되어 있습니다. 모든 어플리케이션 컴포넌트의 이벤트 처리기, 변환기 그리고 검증기는 FacesContext 인스턴스에 접근할 수 있습니다.

만약 페이지 요청이 초기 요청(initial request)일 경우 JSF 구현은 이 단계에서 비어 있는 뷰(view)를 만들고 응답 랜더링 단계(Render Response Phase)로 진행 하는 동안 비어있는 뷰에는 페이지에 있는 태그를 참고 하여 컴포넌트들을 채우게 됩니다. 여기서 페이지는 개발자가 직접 태그를 이용하여 만든 xhtml 페이지 입니다.

만약 페이지에 대한 요청이 포스트백인 경우 이 페이지에 해당하는 뷰는 이미 FacesContext 인스턴스에 존재 합니다. 이때 JSF 구현은 클라이언트 또는 서버에 이미 저장되어 있는 상태 정보를 이용하여 뷰를 복원 합니다.

요청 값 적용 단계 (Apply Request Values Phase)

컴포넌트 트리가 포트스백 요청시 복원이 된 후에 트리의 각 컴포넌트는 디코드(processDocodes()) 메소드를 사용하여 요청 파라메터(request parameters)에서 새로운 값을 추출(extract) 합니다.

만약 디코드 메소드 또는 이벤트 리스너가 현재의 FacesContext 인스턴스에서 renderResponse 메소드를 호출하게 되면 JSF 구현은 응답 랜더링 단계로 건너 뜁니다.

이 단계에서 모든 이벤트가 대기(queued)중인 경우 JSF 구현은 관련 있는 이벤트 리스너에게 전달(broadcast) 합니다.

몇몇 컴포넌트들의 immediate 속성에 true 값이 설정되면 이 컴포넌트와 관련된 검증(validate), 변환(convet), 이벤트는 이 단계에서 처리됩니다. 만약 변환(conversion) 에 오류가 발생하면 해당 컴포넌트와 관련된 오류 메세지가 생성되고 FacesContext 에 대기(queue)합니다. 이 메세지는 검증 단계의 처리중 발생한 모든 검증 오류의 결과와 함께 응답 랜더링 단계(Render Response Phase)에서 표시됩니다.

이때 만약 어플리케이션이 다른 웹 어플리케이션 리소스로 리디렉션(redirect)이 필요하거나 JSF 컴포넌트를 포함하지 않는 응답을 생성할 경우 FacesContext.responseComplete 메소드를 호출 할 수 있습니다.

이 단계의 마지막에 컴포넌트는 새로운 값으로 설정되고 메세지와 이벤트가 대기(queue)하고 있습니다.

만약 현재 요청이 partial 요청으로 식별 될 경우 partial context 는 FacesContext 에서 검색되고 partial 처리 메소드가 적용 됩니다.

검증(유효성) 처리 단계 (Process Validation Phase)

이 단계에서 JSF 구현은 검증(processValidator) 메소드를 통해 뷰 트리의 컴포넌트에 등록된 모든 검증기(validator)를 처리 합니다. 그것은 컴포넌트의 속성들을 검사하는데 검증을 위한 규칙을 명확하게 하고 그 규칙은 컴포넌트에 저장된 로컬 값을 비교 합니다. JSF 구현은 또한 immediate 속성에 true 값이 설정 되지 않은 입력 컴포넌트의 변환(conversion)을 완료한다.

만약 로컬 값이 잘못되거나 모든 변환(conversion)이 실패하면 JSF 구현은 FacesContext 인스턴스에 오류 메세지를 추가하고 라이프 사이클은 응답 랜더링 단계로 곧장 이동하고 페이지는 오류 메세지를 다시 랜더링 합니다.

로컬값이 잘못되거나 변환(conversion)이 실패하면 JSF 구현은 FacesContext 에 오류 메세지를 추가하고 페이지가 오류 메세지를 다시 랜더링 할 수 있게 응답 랜더링 단계로 바로 이동합니다. 만약 변환 오류가 요청값 적용 단계(Apply Request Values Phase)에서 발생 할 경우 그 에러 메세지 또한 함께 표시됩니다.

만약 검증 메소드 또는 이벤트 리스너가 현재의 FacesContext 에서renderResponse 메소드를 호출하면 JSF 구현은 응답 랜더링 단계로 건너 뜁니다.

요청값 적용 단계에서 처럼 만약 어플리케이션이 다른 웹 어플리케이션 리소스로 리디렉션이 필요하거나 JSF 컴포넌트를 포함하지 않는 응답을 생성(generate) 할 경우 FacesContext.responseComplete 메소드를 호출 할 수 있습니다.

만약 이벤트가 이 단계동안 대기 하고 있으면 JSF 구현은 관련된 리스너로 전달 할 수 있습니다.

현재 요청이 partial 요청으로 식별 될 경우 partial context 는 FacesContext 에서 검색되고 partial 처리 메소드가 적용 됩니다.

모델 값 업데이트 단계 (Update Model Values Phase)

JSF 구현은 데이터가 유효한것으로 검증한 후 컴포넌트 트리에 있는 모든 컴포넌트의 로컬 값을 서버측(server-side) 객체의 구성요소에 설정합니다. JSF 구현은 오직 입력 컴포넌트의 속성(attribute) 값이 가리키는 빈(bean)의 구성요소(property)를 업데이트 합니다. 만약 로컬 데이터를 빈(bean) 구성요소에 의해 지정된 타입으로 변환(convert) 할 수 없는 경우에 라이프 사이클은 오류를 표시하는 페이지를 다시 랜더링 하기 위해 응답 랜더링 단계로 바로 진행합니다. 이것은 검증(validation) 오류가 발생하는 것과 동일합니다.

만약 updateModels 메소드 또는 리스너가 현재의 FacesContext 인스턴스의 renderResponse 메소드를 호출하면 JSF 구현은 응답 랜더링 단계로 건너 뜁니다.

이때 만약 어플리케이션이 다른 웹 어플리케이션 리소스로 리디렉션(redirect)이 필요하거나 JSF 컴포넌트를 포함하지 않는 응답을 생성할 경우 FacesContext.responseComplete 메소드를 호출 할 수 있습니다.

만약 이벤트가 이 단계동안 대기 하고 있으면 JSF 구현은 관련된 리스너로 전달 할 수 있습니다.

현재 요청이 partial 요청으로 식별 될 경우 partial context 는 FacesContext 에서 검색되고 partial 처리 메소드가 적용 됩니다.

어플리케이션 호출 단계 (Invoke Application Phase)

이 단계에서 JSF 구현은 폼 제출(submit a form) 또는 다른 페이지로 연결(linking)과 같은 어플리케이션 수준의 이벤트를 처리합니다.

이때 만약 어플리케이션이 다른 웹 어플리케이션 리소스로 리디렉션(redirect)이 필요하거나 JSF 컴포넌트를 포함하지 않는 응답을 생성할 경우 FacesContext.responseComplete 메소드를 호출 할 수 있습니다.

뷰(view)가 이전 요청의 상태 정보로 부터 재구성하는 처리를 하고 컴포넌트가 이벤트를 발생시키면 그 이벤트는 관련된 리스너로 전달이 됩니다.

마지막으로 JSF 구현은 응답 랜더링 단계로 제어를 전달합니다.

응답 랜더링 단계 (Render Response Phase)

이 단계에서 JSF는 뷰를 생성(build) 하고 페이지를 랜더링 하기 위해 적당한 리소스에 권한을 위임 합니다.

만약 초기 요청(initial request)이면 페이지페 표시될 컴포넌트를 컴포넌트 트리에 추가 합니다. 만약 초기 요청이 아니면 컴포넌트는 이미 트리에 추가 되어 있고 다시 추가될 필요는 없습니다.

만약 포스트백 요청이고 오류가 요청값 적용 단계, 검증 처리 단계, 모델 값 갱신 단계중 발생된 경우 오리지널 페이지는 이 단계에서 다시 랜더링 합니다. 만약 페이지에 h:message 또는 h:messages 태그가 있는 경우 대기중인 모든 오류 메세지가 페이지에 나타납니다.

뷰의 내용들이 랜더링되고 난 후 응답의 상태는 저장되는데 바로 다음 요청은 이 상태에 접근 할 수 있습니다. 저장된 상태는 뷰 복원 단계에서 사용 할 수 있습니다.

JSF 라이프 사이클의 개발자를 위한 요약

어느정도 JSF 개발에 익숙해진 개발자를 위해 간단하게 라이프 사이클을 코드를 이용하여 표현해 봤습니다.

  • fc = FacesContext
  • vh = ViewHandler
  • in = UIInput
  • rq = HttpServletRequest
  • id = in.getClientId(fc);

  1. 뷰 복원
  2. String viewId = rq.getServletPath();
    fc.setViewRoot(vh.createView(fc, viewId));
    
  3. 요청값 적용
  4. in.setSubmittedValue(rq.getParameter(id));
    
  5. 검증 처리
  6. Object value = in.getSubmittedValue();
    try {
       value = in.getConvertedValue(fc, value);
       for (Validator v : in.getValidators())
          v.validate(fc, in, value);
       }
       in.setSubmittedValue(null);
       in.setValue(value);
    } catch (ConverterException
       | ValidatorException e) {
       fc.addMessage(id, e.getFacesMessage());
       fc.validationFailed(); // Skips phases 4+5.
       in.setValid(false);
    }
    
  7. 모델 값 갱신
  8. bean.setProperty(in.getValue());
    
  9. 어플리케이션 호출(실행)
  10. bean.submit();
    
  11. 응답 랜더링
  12. vh.renderView(fc, fc.getViewRoot());
    



출처


'공부 > JSF' 카테고리의 다른 글

JSF 간단 예제 두번째  (0) 2014.10.07
Managed bean 스코프에 대하여  (0) 2014.10.06
JSF 라이프 사이클 개요  (0) 2014.10.05
JSF 어플리케이션 Hello World 예제  (0) 2014.10.04
JavaServer Faces 어플리케이션 개발 준비  (0) 2014.10.04
Posted by #HanaLee
공부/JSF2014. 10. 5. 04:32

JavaServer Faces 라이프 사이클

JavaServer Faces(JSF) 라이프 사이클은 꽤나 긴 내용이기 때문에 라이프 사이클 각 단계(phase)별로 나눠서 작성 하도록 하겠습니다.

어플리케이션의 라이프 사이클은 해당하는 어플리케이션 처리의 여러 단계이며 시작과 끝을 의미한다. 모든 어플리케이션은 라이프 사이클이 있습니다. 어플리케이션의 라이프 사이클 동안 일반적인 작업은 다음의 내용을 포함하여 실행 됩니다.

  • 들어오는 요청을 처리
  • 파라메터의 디코딩
  • 상태를 수정 및 저장
  • 웹 브라우저에 웹 페이지를 랜더링

JSF 웹 어플리케이션 프레임워크는 간단한 어플리케이션을 위해 라이프 사이클의 각 단계를 자동으로 관리 하거나 필요에 따라 복잡한 어플리케이션에 대해서는 수동으로 관리 할 수 있습니다.

고급 기능을 사용하는 JSF 어플리케이션은 특정 단계에서 라이프 사이클과의 상호 작용이 필요합니다.

예를 들어 Ajax 어플리케이션은 라이프 사이클의 부분 처리 기능을 사용합니다. (참조 : Partial Processing and Partial Rendering)

라이프 사이클의 명확한 이해는 잘 디자인된 컴포넌트를 만드는 핵심이 됩니다.

기본적으로 JSF 웹 어플리케이션은 실행 단계와 랜더링 단계 두 가지 주요 단계로 구성 됩니다. 이번 글에서는 JSF 어플리케이션의 라이프 사이클에 대하여 더 자세히 알아보겠습니다.

JSF 라이프 사이클의 개요

JSF 어플리케이션의 라이프 사이클은 클라이언트의 요청(request)으로 시작하여 서버가 응답(response) 페이지를 HTML 로 변환 하면서 종료 됩니다.

라이프 사이클은 실행(execute)과 랜더(render) 의 두가지 주요 단계로 나눌 수 있습니다. 실행 단계에서는 더 정교한 컴포넌트 트리를 지원하는 하위단계로 나누어집니다. 이러한 구조는 컴포넌트 데이터의 변환(convert)과 검증(validate), 컴포넌트 이벤트의 처리, 그리고 컴포넌트 데이터가 규칙적으로 빈(bean) 들에 전달 될 것을 요구 합니다.

JSF 페이지는 컴포넌트들의 트리로 나타나며 뷰(view) 라고 합니다. 라이프 사이클 동안 JSF 구현체는 뷰를 만들때 페이지를 제출 하기 이전에 상태(state)를 저장할지 고려 해야 합니다. 클라이언트가 페이지를 요청할때 JSF 구현체는 뷰의 컴포넌트에 입력된 데이터의 검증과 입력 데이터를 서버측(server side)에 지정된 특정 타입으로 변환 작업등을 수행해야 한다.

JSF 구현체는 JSF 요청에서 응답까지 라이프 사이클의 모든 단계의 작업을 수행해야 합니다. 다음 그림은 라이프 사이클의 단계를 보여줍니다.

<JSF 요청에서 응답까지 표준 라이프 사이클>

요청-응답 라이프 사이클은 두가지 종류의 요청이 있습니다. 최초 요청과 포스트백. 최초 요청(initial request) 는 사용자가 처음으로 페이지를 요청하면 발생합니다. 포스트백 요청은 최초 요청에 의해 실행 된 결과가 브라우저에 이미 로드가 된 페이지의 폼을 사용자가 제출(submit)을 하면 발생 합니다.

라이프 사이클이 최초 요청을 처리 할때는 오직 뷰 복원과 응답을 랜더링하는 단계가 실행됩니다. 왜냐하면 최초 요청에는 유저의 입력이나 액션 처리가 없기 때문입니다. 라이프 사이클이 포스트백을 처리 할 때에는 반대로 모든 단계가 실행 됩니다.

보통은 클라이언트의 첫번째 JSF 페이지 요청은 JSF 페이지의 링크나 버튼 컴포넌트를 클릭한 결과입니다. 이것은 또 다른 JSF 페이지를 랜더링 하여 응답하는것이며 이 어플리케이션은 들어오는 요청과 응답을 생성하여 처리하는것과 관계가 있는 javax.faces.context.FacesContext 인스턴스 내부에 새로운 뷰를 만들고 저장합니다. 그런 뒤 어플리케이션은 뷰가 필요로 하는 객체의 레퍼런스를 취득하고 FacesContext.renderResponse 메소드를 호출하여 즉시 라이프 사이클의 랜더 응답 단계로 건너띄어 뷰를 강제로 랜더링 하며 위 그림에서 화살표로 표시 되어 있습니다.

가끔 어플리케이션은 웹서비스와 같은 다른 웹 어플리케이션 리소스로 리디렉션(redirect) 또는 JSF 컴포넌트를 포함하지 않는 응답을 랜더링 해야 할 수도 있습니다. 이러한 상황에서 개발자는 FacesContext.responseComplete 메소드를 호출 하여 응답을 랜더링하는 단계를 생략 하면 됩니다. 이 상황은 또한 위 그림에서 Response Complete 의 화살표를 나타냅니다.

가장 일반적인 상황은 JSF 컴포넌트가 다른 JSF 페이지에 대한 요청을 서밋 하는 것입니다. 이 경우에는 JSF 구현체가 요청을 처리하고 라이프 사이클 내부의 단계를 통해 모든 필요한 변환들, 검증들 그리고 모델을 업데이트 하고 응답을 생성하는 작업을 수행합니다.

여기서 설명한 라이프 사이클에 대한 한가지 예외가 있습니다. 컴포넌트의 immediate 속성 값이 true 로 설정 되었을때 이러한 컴포넌트와 관련된 검증, 변환, 이벤트가 요청값 적용 단계 (Apply Request Values Phase) 보다 이후 단계에서 처리 됩니다.

개발자를 위한 검증, 변환, 이벤트를 일반적으로 처리 하는 방법과 변화를 어떻게 언제 처리하는지 라이프 사이클에 대한 더 자세한 설명을 다음 블로그에서 작성 하도록 하겠습니다.




출처


'공부 > JSF' 카테고리의 다른 글

Managed bean 스코프에 대하여  (0) 2014.10.06
JSF 라이프 사이클 상세  (0) 2014.10.06
JSF 어플리케이션 Hello World 예제  (0) 2014.10.04
JavaServer Faces 어플리케이션 개발 준비  (0) 2014.10.04
Facelets 란 무엇인가?  (0) 2014.10.02
Posted by #HanaLee
공부/JSF2014. 10. 4. 02:53

JavaServer Faces 는 쉽고, 유저 친화적인(user-friendly) 방법으로 웹 어플리케이션 만들기를 지원합니다. JavaServer Faces 개발에는 일반적으로 다음의 절차가 꼭 필요하며 예제를 통해 살펴 보겠습니다.

  • 컴포넌트 태그를 이용하여 웹 페이지 만들기
  • 관리되는빈(managed beans) 개발하기
  • FacesServlet 매핑하기

HelloWorld!! 출력하기

모든 언어의 기본 출발점… HelloWorld!! 를 브라우저에 출력 해보겠습니다.

이클립스에서 웹서버를 신규로 등록합니다.

Dynamic Web Project를 hello 라는 이름으로 새로 만드세요.

프로젝트의 카테고리를 펼쳐 WebContent/WEB-INF/lib 폴더에 JSF 라이브러리 및 JSTL 라이브러리 파일을 복사해 넣어주세요.

web.xml 에 아래의 내용을 추가 해 주세요.

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns="http://java.sun.com/xml/ns/javaee"
	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
	id="WebApp_ID" version="2.5">
	<servlet>
		<servlet-name>Faces Servlet</servlet-name>
		<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
		<load-on-startup>1</load-on-startup>
	</servlet>
	<servlet-mapping>
		<servlet-name>Faces Servlet</servlet-name>
		<url-pattern>*.xhtml</url-pattern>
	</servlet-mapping>
</web-app>

JavaBean 클래스를 Hello 라는 이름으로 새로 만들고 아래의 내용을 입력해주세요.

package hello;

import javax.faces.bean.ManagedBean;

@ManagedBean
public class Hello {

	private final String world = "Hello World!!";

	public String getWorld() {
		return world;
	}
}

WebContent 아래에 hello.xhtml 이라는 이름으로 view page 하나 만들고 내용을 아래와 같이 입력해주세요.

<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml"
	xmlns:h="http://java.sun.com/jsf/html">
<h:head>
	<title>Hello World Example</title>
</h:head>
<h:body>
	#{hello.world}
</h:body>
</html>

모든 준비가 완료 되었습니다. 이제 이클립스에서 Tomcat 웹서버를 실행하고 브라우저에서 아래의 주소를 입력하여 HelloWorld!! 가 출력되는지 확인 해보세요.

http://localhost:8080/hello/hello.xhtml

동작 설명

JavaServer Faces 어플리케이션 뿐만 아니라 대부분의 웹 어플리케이션은 라이프사이클이 존재 합니다. 먼저 이번 예제가 실행될때 JavaServer Faces 컨테이너에서 일어나는 일에 대해 간단히 정리 하겠습니다.

  • 클라이언트로부터 서버로 요청이 시작됩니다.
  • JavaServer Faces 어플리케이션의 뷰가 생성되거나 복원을 합니다.
  • 요청 파라메터 값을 반영 합니다.
  • 컴포넌트 값에 대한 변환(conversion) 과 검증(validation) 이 수행됩니다.
  • 컴포넌트의 값을 가지고 Managed beans 가 업데이트 됩니다.
  • 어플리케이션의 로직이 호출 됩니다.

클라이언트로 부터 요청이 처음일 경우에는 뷰가 생성이 되며, 이후 부터는 동일한 요청에 대해서는 뷰를 복원하게 됩니다. 위와 같이 몇가지 작업이 일어난 후 최종적으로는 클라이언트가 해석 할 수 있는 HTML 이 만들어지게 됩니다.

이상으로 초간단 JavaServer Faces 어플리케이션을 만들어 보았습니다. 다음 블로그 글에서는 JavaServer Faces 에서 아주 중요하고 꼭 이해해야만 하는 라이프 사이클에 대해 알아 보겠습니다.

'공부 > JSF' 카테고리의 다른 글

JSF 라이프 사이클 상세  (0) 2014.10.06
JSF 라이프 사이클 개요  (0) 2014.10.05
JavaServer Faces 어플리케이션 개발 준비  (0) 2014.10.04
Facelets 란 무엇인가?  (0) 2014.10.02
JavaServer Faces 버전 히스토리  (0) 2014.10.02
Posted by #HanaLee