JSF 란? JavaServer Faces 소개

JSF (JavaServer Faces)는 구성 요소 기반의 이벤트 지향 웹 인터페이스를 구축하기위한 Java 표준 기술입니다. JSP (JavaServer Pages)와 마찬가지로 JSF는 서버 측 데이터 및 로직에 대한 액세스를 허용합니다. 본질적으로 서버 측 기능이 포함 된 HTML 페이지 인 JSP와 달리 JSF는 논리적 트리에서 형식 구성 요소를 나타내는 XML 문서입니다. JSF 구성 요소는 HTML과 독립적이며 원격 API 및 데이터베이스 액세스를 포함하여 모든 범위의 Java 기능을 가진 Java 객체에 의해 지원됩니다.

JSF와 같은 프레임 워크의 핵심 아이디어는 HTML, CSS 및 JavaScript와 같은 클라이언트 측 기술 을 캡슐화 (또는 래핑 )하여 개발자가 이러한 기술과 많은 상호 작용없이 웹 인터페이스를 구축 할 수 있도록하는 것입니다.

이 기사는 자바 웹 애플리케이션을위한 컴포넌트 기반 UI 개발에 대한 JSF의 접근 방식에 대한 스냅 샷을 제공합니다. 간단한 예제는 JSF의 MVC 아키텍처, 이벤트 모델 및 구성 요소 라이브러리를 소개합니다. 예제에는 JSF 2.3의 새로운 기능이 포함되며 구성 요소 라이브러리에 PrimeFaces를 사용합니다.

진화하는 JSF

오랫동안 인기를 끌었던 JSF는 최근 클라이언트 측 JavaScript 프레임 워크를 포함한 Java 호환 웹 프레임 워크와의 경쟁에 직면 해 있습니다. 여전히 JavaServer Faces는 특히 대규모 Java 엔터프라이즈 개발을위한 Java 표준으로 남아 있습니다. JSF 사양은 또한 최근의 클라이언트 측 개선 사항에 보조를 맞춰 다양한 프레임 워크와 라이브러리를 생성했습니다. 이 중 하나는 PrimeFaces이며이 튜토리얼에서 살펴 봅니다.

향후 개발 일정은 불분명하지만 JSF 2.3은 개발자가 기다리는 동안 작업 할 수있는 충분한 기회를 제공합니다. 2017 년 3 월에 출시 된 JSF 2.3은 의도적으로 JSF를 현대화하도록 설계되었습니다. 수백 개의 소규모 수리와 대규모 업데이트 중에서 JSF 2.3은 CDI를 위해 관리 빈 주석을 더 이상 사용하지 않습니다.

Jakarta EE의 JSF 2.3

2017 년 9 월 Oracle은 Java EE를 Eclipse Foundation으로 전환 할 계획을 발표했습니다. Java EE는 이후 Jakarta EE로 리 브랜딩되었으며 JSF 2.3 (Eclipse Mojarra)이 계속 채택되었습니다. JSF 사양의 다음 주요 릴리스는 Eclipse Mojarra 3.0입니다.

JSF에서 컴포넌트 기반 웹 인터페이스 빌드

JSF의 핵심 아이디어는 기능을 재사용 가능한 구성 요소로 캡슐화하는 것입니다. 이는 JSP에서 사용되는 재사용 가능한 태그와 유사하지만 JSF 구성 요소는 더 형식적입니다.

JavaServer Pages 내에서 JSF 페이지를 사용할 수 있지만 Facelet을 사용하여 독립형 JSF 페이지를 빌드하는 것이 더 일반적입니다. Facelet 은 JSF 인터페이스를 정의하기 위해 설계된 XHTML 페이지입니다. Facelets를 사용하면 XML 태그를 사용하여 JSF 사용자 인터페이스의 스캐 폴드가되는 구성 요소 트리를 만듭니다.

목록 1은 Facelet을 사용하여 작성된 간단한 JSF 페이지의 주요 부분을 보여줍니다. 이 예제에서 우리는 CDI를 통해 범위에 배치 된 빈을 통해 Java의 서버 측 기능에 액세스합니다. 나중에 CDI에 대해 더 많이 알게 될 것입니다.

Listing 1. JSF 샘플 페이지

    Hello JavaWorld!   #{javaBean.content}  

목록 1에는 표준 XHTML 페이지가 있습니다. Facelets보기는 XHTML 위에 구축됩니다. XHTML 네임 스페이스 외에도 보조 네임 스페이스가 정의되고 참조됩니다.

h라이브러리는 JSF HTML 페이지에 사용되는 표준 구성 요소가 포함되어 있습니다. //xmlns.jcp.org/jsf/html라이브러리는이 경우, 일반적인 HTML 요소의 컬렉션을 JSF 구성 요소의 컬렉션을 정의합니다. 이러한 구성 요소 중 하나는 요소입니다.

JSF의 HTML 구성 요소

구문 측면에서 목록 1의 요소 jsf/htmlh접두사가 있는 라이브러리를 참조합니다 . 그런 다음 라이브러리 내에서 구성 요소 인 특정 구성 요소를 참조합니다 head.

성분은 HTML 헤드 구성 요소를 출력한다. (이 모든 구문은 단순한 목적으로 인해 과잉처럼 보일 수 있지만 곧 알게 될 것입니다.)

구성 요소 중첩

헤드 내부에는 표준 HTML 요소 가 중첩되어 있습니다 . 이 요소는 그 안에 중첩 된 콘텐츠 하위 요소와 함께 구성 요소에 제공됩니다 .

문서 본문에는 #{}구문에 JSF 표현식이 포함되어 있습니다. 이것은 ${}형식 을 사용하는 JSP 표현식과 정확히 유사 합니다. 범위 및 간단한 기능에있는 Java 객체에 액세스 할 수 있습니다.

JSF의 기본 패턴은 간단합니다. Facelet을 사용하여 구성 요소 라이브러리를 참조하는 XML 트리를 만든 다음 라이브러리 내의 구성 요소를 사용하여 Java 객체를 HTML로 렌더링합니다.

JSF에서 Java 객체 사용

목록 1로 돌아가서 JSF 표현식 ( ${javaBean.content) 내부 javaBean에이 마크 업이 실행될 때 객체가 범위 내에 있음을 알 수 있습니다 . Facelets의 XHTML은 객체 의 .content속성에 액세스 javaBean합니다. 최종 출력은 Facelets보기 구조를 Java의 서버 측 데이터 및 논리 기능과 병합하는 웹 인터페이스입니다.

JSF 표현식을 사용하는 것은 JSF 사용자 인터페이스에서 Java 애플리케이션 데이터에 액세스하는 한 가지 방법 일뿐입니다. 결국 JSF 구성 요소가 Java 백엔드와 상호 작용할 수있는 다른 방법 (데이터 목록 및 그리드, 다양한 입력 제어 등)을 탐색하고 싶을 것입니다. 현재로서는 JSF가 XML 태그 (또는 주석)를 사용하여 Java 객체에 포함 된 데이터를 기반으로 HTML을 출력하는 구성 요소 트리를 만드는 방법을 이해하는 것으로 충분합니다.

주석과 XML

JSF 2.3에서는 주석이있는 JSF 구성 요소를 정의하여 XML 메타 데이터를 완전히 피할 수있게되었습니다. XML을 편집하지 않고도 JSF 앱을 ​​정의하고 배포 할 수 있습니다.

JSF 애플리케이션의 구조

JavaServer Pages 및 Servlet API와 마찬가지로 JavaServer Faces에는 표준 디렉토리 구조 및 메타 데이터가 필요합니다. .war 파일 로 배포됩니다 .

.war 파일의 구조는 Servlet 또는 JSP 애플리케이션과 유사합니다. 여기에는 /web-app애플리케이션의 마크 업 파일 (이 경우 HTML, JSP 및 Facelets)이있는 /WEB-INF디렉토리와 애플리케이션을 설명하는 메타 데이터를 제공 하는 디렉토리가 포함됩니다.

JSF 제공

Glassfish와 같은 Java EE 컨테이너에서 JSF를 실행할 수 있지만 간단한 서블릿 컨테이너 만 있으면됩니다. Tomcat은 JSF 및 기타 서버 측 Java 기술에 널리 사용되는 컨테이너입니다.

JSF 2.3 : 사양 및 구현

Java의 강점 중 하나는 표준 기반이며 이러한 표준은 오픈 소스 커뮤니티 프로세스에 의해 관리된다는 것입니다. 처음부터 JCP (Java Community Process)는 Java 기술 개발을 감독했습니다. 사양 또는 사양 개선이 JCP에 의해 개발되고 승인되면 여러 당사자가 구현할 수 있습니다. 최근까지 Servlet, JSP 및 JSF는 모두 JCP의 오픈 소스 사양 프로세스를 사용하여 개발되었습니다.

이 글을 쓰는 시점에서 가장 최근의 JSF 사양은 JSF 2.3으로, 2017 년 Java EE 8의 일부로 출시되었습니다. Oracle (현재 Eclipse의) Mojarra는 JSF 참조 구현이며 MyFaces 및 PrimeFaces는 널리 사용되는 타사 구현입니다.

이러한 각 프레임 워크는 일부 표준 구성 요소를 포함하는 JSF 코어를 구현합니다. 공급 업체는 표준 위에 추가 구성 요소 라이브러리를 제공 할 수도 있습니다. JSF 프레임 워크를 평가할 때 애플리케이션의 요구 사항과이를 빌드하는 데 사용할 수있는 컴포넌트 라이브러리를 고려하는 것이 좋습니다. 이상적으로는 JSF 프레임 워크를 사용하면 즉시 필요한 항목에 최대한 가깝게 도달 할 수 있습니다.

JSF 2.3의 MVC

JSF is an MVC framework, implementing the model-view-controller pattern. In the MVC pattern, the idea is to separate the three concerns of a UI into discreet parts, so they're easier to manage. In general, the view is responsible for displaying data in the model, and the controller is responsible for setting up the model and routing the user to the correct view.

In a JSF implementation, the view is the Facelets page with its set of XML tags. These define the layout of the user interface. The other half of using JSF is the server-side, where Java classes back those UI components.

Managed beans deprecated in JSF 2.3

Managed bean annotations have been deprecated in JSF 2.3, and replaced by CDI (Contexts and Dependency Injection). With CDI, developers define a context and inject objects to that context. Those familiar with managed beans will find the annotation syntax slightly different, but the semantics remain exactly the same.

Controller beans

In JSF 2.3, controller beans provide the controller part of the MVC equation. Normal Java objects (often called POJOs, or plain old Java objects) provide the model.

In terms of process flow, controller beans:

  1. Decide where to direct user requests
  2. Set up POJOs for the model
  3. Use the model to render the Facelets view

JSF then folds together the component tree and model to render the output HTML.

목록 2는 javaBeanCDI를 사용하여 목록 1 의 객체를 정의하는 방법을 보여줍니다 . 이 목록은 애플리케이션의 종속성에 cdi-api-1.2.jar이 있다고 가정합니다.

Listing 2. CDI를 사용하여 정의 된 JavaBean

 import javax.inject.Named; import javax.enterprise.context.SessionScoped; @Named @ViewScoped public class JavaBean implements Serializable { private String content = ìWelcome to JSF!î // getters/setters } 

PrimeFaces를 사용한 JSF 2.3

다음 섹션에서는 PrimeFaces를 사용하여 JSF가 MVC 패턴, 이벤트 기반 메시징 및 재사용 가능한 구성 요소를 구현하는 방법을 보여줍니다. 시작하려면 PrimeFaces Showcase를 열고 왼쪽 열의 데이터 링크를 클릭 한 다음 DataList를 선택 합니다. PrimeFaces에 대한 DataList 데모 코드가 표시됩니다.

그림 1은 이러한 샘플을 찾을 수있는 위치를 보여줍니다.

매튜 타이슨

그림 2는 PrimeFaces DataList 데모에서 가져온 간단한 데이터 테이블의 출력을 보여줍니다.

매튜 타이슨

PrimeFaces DataList : 데이터 모델 액세스

Listing 3 presents the markup for this dataList display. If you scroll to the bottom of the PrimeFaces showcase, you can see the markup in the dataList.xhtml tab.

Listing 3. Facelet for PrimeFaces DataList

   Basic  #{car.brand}, #{car.year}  

In Listing 3, notice the value property of the dataList component. You can see that this references a dataListView object, and accesses the .cars1 property on it. The component is going to use the model object returned by that field. JSF tokens use conventional accessors to reference object properties, so .cars1 will refer to the getCars() getter on the object.

Next, notice the var="car" property. This tells the dataList component what variable to use when it iterates over the list of cars returned by the value field. These properties are specific to the dataList component, but the value property is very common. The var attribute is also conventional for components that iterate over lists.

In the body of the component in Listing 3, you can see the car variable is accessed via JSF expressions like #{car.brand}. Each iteration of the dataListView.cars1 instance will output the car.brand field.

Notice that the tag demonstrates the ability to customize components for how they will display. In this case, the header is defined as Basic.

You can see how the Facelets XML will drive this output by combining the data with the markup. Now let's look at the Java code behind it.

DataList's server-side components

Listing 4 shows DataListView, the Java class that is used by the markup in Listing 3. You'll see shortly how the dataListView instance is associated with the DataListView class.

Listing 4. DataListView class

 package org.primefaces.showcase.view.data; import java.io.Serializable; import java.util.List; import javax.annotation.PostConstruct; import javax.inject.Named; // Pre JSF 2.3, this was: // import javax.faces.bean.ManagedBean; import javax.inject.Inject; import javax.faces.bean.ViewScoped; import org.primefaces.showcase.domain.Car; import org.primefaces.showcase.service.CarService; @Named @ViewScoped public class DataListView implements Serializable { private List cars1; private Car selectedCar; @Inject("#{carService}") private CarService service; @PostConstruct public void init() { cars1 = service.createCars(10); } public List getCars1() { return cars1; } public void setService(CarService service) { this.service = service; } } 

Listing 4 has a few other important elements, which we'll consider piece by piece.

Dependency injection and annotations

First, notice that the DataListView class is annotated with @Named, which you can see from the import import javax.inject.Named; is part of JSF. The @Named annotation tells JSF this bean is part of the app. The @ViewScoped annotation informs JSF that the bean will live for just the life of the view.

다음으로 CarService속성에 @Inject주석 ( @ManagedPropertyJSF 2.3 이전 이라고 함) 이 있는지 확인합니다 . 이것은 빈을 "함께 연결"할 수있는 또 다른 JSF 기능으로, Spring 프레임 워크 및 기타 종속성 주입 도구에서 널리 사용되는 기술입니다. 본질적으로 JSF는 carService범위 내 에서 개체를 찾아 자동으로 개체 의 service필드에 연결 DataListView합니다.