로컬 인터페이스 보기를 사용하여 공개되는 EJB(Enterprise
JavaBeans) 애플리케이션이 있는 경우,
JAX-RS(Java™ API for RESTful Web Services)를 사용하여
엔터프라이즈 Bean에 RESTful 인터페이스를 공개할 수 있습니다.
JAX-RS 어노테이션이 있는 엔터프라이즈 Bean을 구현하여 트랜잭션 지원,
Java EE 컴포넌트 및 자원의 인젝션, 기타
EJB 세션 bean 기능을 포함하는 EJB 기능을 유지합니다.
시작하기 전에
EJB 3.1 이전에는 EJB 로컬 클라이언트 보기를 필요로 하는 엔터프라이즈 Bean에서
로컬 보기 메소드를 선언한 별도의 Java 인터페이스가
필요했습니다. 이것은 보통 다른 파일에 있습니다. 엔터프라이즈 Bean에서는 배치 디스크립터 또는 EJB 어노테이션을
사용하여 EJB 로컬 보기 인터페이스를 구현하도록 지정했습니다.
EJB 3.1 스펙을
사용하는 경우 명시적 EJB 로컬 인터페이스를 사용하지 않고 엔터프라이즈 Bean의 로컬 보기를
공개하는 옵션이 제공됩니다. 대신 엔터프라이즈 Bean에는 사용자 Bean 클래스의 공용 메소드를
기반으로 하는 인터페이스 없는 클라이언트 보기가 있습니다. 인터페이스가 없는 보기 엔터프라이즈 Bean은
다음의 이유로 로컬 보기 엔터프라이즈 Bean보다 개발이 더 간단할 수 있습니다.
- 인터페이스가 없는 보기 엔터프라이즈 Bean에서는 Java 인터페이스를 별도로 선언할 필요가 없습니다.
- 인터페이스가 없는 보기 엔터프라이즈 Bean에서는 배치 관리자에서 또는 어노테이션 사용 시
추가 메타데이터를 지정할 필요가 없습니다.
엔터프라이즈 Bean의 인터페이스가 없는 보기에 대한 세부사항은 EJB 3.1 스펙을 참조하십시오.
JAX-RS는 로컬 비즈니스 인터페이스와 인터페이스가 없는 보기 엔터프라이즈 Bean을
선언하는 엔터프라이즈 Bean 사용을 지원합니다.
이 태스크는 엔터프라이즈 Bean에서 JAX-RS 자원을
공개할 수 있도록 하는 로컬 엔터페이스가 있는 엔터프라이즈 Bean의 RESTful 보기 구현에 대해
설명합니다.
이 태스크 정보
JAX-RS 어노테이션이 있는 단순한 엔터프라이즈 Bean을 작성할 수 있습니다.
이 태스크에서 로컬 인터페이스 보기 엔터프라이즈 Bean의 RESTful 보기 구현 방법에 대해
구체적으로 설명하더라도, 자원 모델을 결정하고 사용자 엔터프라이즈 Bean 애플리케이션에
적합한 RESTful 보기를 결정하면서 자원 공개 방법 및 애플리케이션 아키텍처의 전체 범위를
고려해야 합니다. 이러한 고려사항은 이 태스크의 범위를 벗어납니다.
JAX-RS는 Stateless 및 싱글톤 세션 Bean을 지원합니다.
세션 Bean의 로컬 인터페이스에 JAX-RS 어노테이션을 추가할 수 있습니다.
또한 EJB 3.1을 사용하면 엔터프라이즈 Bean에서 인터페이스가 없는 보기를 공개하는
경우 EJB 클래스에 직접 JAX-RS 어노테이션을 추가할 수 있습니다.
EJB 3.1
패키징 규칙을 사용하면, WEB-INF/classes 디렉토리에서 직접 또는 WEB-INF/lib 디렉토리에 있는
JAR(Java archive) 파일을 사용하여 WAR(web application archive)
파일에 JAX-RD 엔터프라이즈 Bean을 추가할 수 있습니다. 어노테이션을 사용하거나, EJB 배치
디스크립터를 사용하거나 어노테이션과 배치 디스크립터 모두를 사용하여 엔터프라이즈 Bean을
선언할 수 있습니다.
EAR에 포함되는 별도의 ejb-jar 파일 또는 독립형에서는
JAX-RS 어노테이션이 있는 엔터프라이즈 Bean이 지원되지 않습니다.
우수 사례: 다른 방식으로 엔터프라이즈 Bean을 선언할 수 있더라도,
EJB 비즈니스 로컬 인터페이스를 직접 구현하고 항상 @javax.ejb.Local 어노테이션을 선언하는
것이 가장 좋습니다.
이 방법을 사용하면 로컬 비즈니스 인터페이스를 구현할 때 EJB Bean이 필요합니다.
그러면 인수 유형에 메소드 이름 및 변경사항 입력 시 오류가 없어집니다. 항상 @javax.ejb.Local
어노테이션을 사용하면 다중 비즈니스 인터페이스가 있는 경우, 어노테이션 값에 비즈니스 인터페이스를
간단히 추가할 수 있습니다. 이러한 방식에서는 배치 디스크립터를 사용하여 엔터프라이즈 Bean을 수정할 수도
있습니다.
bprac
프로시저
- 엔터프라이즈 Bean 애플리케이션에 대한 엔터프라이즈 Bean 로컬 인터페이스를
작성하십시오. 다음 예제에서는 구입할 항목에 대해 단순 로컬 비즈니스 인터페이스인
Purchasable EJB 로컬 비즈니스를 보여줍니다.
package com.example.jaxrs;
@javax.ws.rs.Path("itemsForPurchase/{itemID}")
public interface Purchasable {
public int getItemsLeft(String itemID);
@javax.ws.rs.POST
public Order purchase(
@javax.ws.rs.PathParam("itemID") String itemID,
@javax.ws.rs.QueryParam("orderId") String orderID);
}
getItemsLeft 메소드는 JAX-RS가 관련되지 않은 정규 EJB 메소드입니다.
javax.ws.rs.Path 어노테이션은 사용할 HTTP 요청 경로를 표시합니다.
itemsForPurchase/{itemID} 오브젝트에 대한 HTTP POST 요청이 작성되면,
JAX-RS 런타임 환경은 Purchasable 로컬 인터페이스를 구현하고 엔터프라이즈 Bean에서
구매 메소드를 호출하는 EJB Bean을 찾습니다.
JAX-RS 런타임 환경 요청 외부의
구매 메소드를 계속 사용할 수 있습니다. Purchasable 엔터프라이즈 Bean에 대해 인젝션 또는
JNDI 검색을 사용하고 2개의 문자열 인수(itemID 및 orderID)가 있는
구매 메소드를 호출할 수 있습니다.
우수 사례: 로컬 비즈니스 인터페이스를 구현하는 다중 엔터프라이즈 Bean이 있는 경우,
JAX-RS 런타임 환경은 JAX-RS 요청을 작성할 때 사용할 랜덤 EJB Bean을 선택합니다.
하나의 Bean 클래스만이 JAX-RS 어노테이션이 있는 EJB 로컬 인터페이스를 구현하도록 설정하는 것이
가장 좋습니다. 필요한 경우 별도의 EJB 로컬 인터페이스를 작성하고, 새 인터페이스에서
JAX-RS 어노테이션을 사용한 후 새 EJB 로컬 인터페이스를 구현하도록 Bean 클래스에 대한
메타데이터를 수정하십시오.
bprac
- 로컬 비즈니스 인터페이스를 구현하는 엔터프라이즈 Bean을 작성하십시오. 다음 예제에서는 Purchasable EJB bean에 대해 설명합니다.
public int getItemsLeft(String itemID) {
// Return the number of items left.
}
public Order purchase(String itemID, String orderId) {
// Add the given item to the order id and return it.
}
}
- Book 클래스는 엔터프라이즈 Bean이고 로컬 인터페이스를 구현하도록 선언합니다. 다음 메소드 중 하나를 사용하여 로컬 인터페이스를 구현하는 엔터프라이즈 Bean으로
사용자 클래스를 선언하십시오. 다음 예제에서 Book 클래스는 로컬 인터페이스를 구현하는
엔터프라이즈 Bean으로 선언합니다.
- Book 클래스에서 EJB 어노테이션 @javax.ejb.Stateless 또는 @javax.ejb.Singleton을
사용하여 EJB를 Stateless 또는 싱글톤이 되도록 지정하십시오. 또한 어노테이션 값으로서
로컬 인터페이스가 있는 @javax.ejb.Local 어노테이션을 추가하십시오. 예:
@javax.ejb.Stateless
@javax.ejb.Local(Purchasable.class)
public class Book {
다중 로컬 비즈니스 인터페이스를 구현한 경우,
@javax.ejb.Local 어노테이션 값에 인터페이스 클래스를 추가하십시오. 예:
@javax.ejb.Local({Purchasable.class, Rentable.class})
- 배치 디스크립터를 사용하여 구현하는 EJB Bean과 비즈니스 인터페이스를 선언할 수
있습니다. 예:
<ejb-jar xmlns="http://java.sun.com/xml/ns/javaee" version="3.1"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/ejb-jar_3_1.xsd">
<!--
This file must exist in the WEB-INF/
directory of your WAR file. See EJB 3.1 spec 20.4 for more details.
-->
<enterprise-beans>
<session>
<ejb-name>Book</ejb-name>
<business-local>com.example.jaxrs.Purchasable</business-local>
<ejb-class>com.example.jaxrs.Book</ejb-class>
<session-type>Stateless</session-type>
</session>
</enterprise-beans>
</ejb-jar>
다중 로컬 비즈니스 인터페이스를 구현했으면,
사용자 Bean 정의에 있는 각 로컬 인터페이스에 business-local 요소를 추가해야 합니다.
- 로컬 비즈니스 인터페이스가 하나만 있는 경우, 직접 인터페이스를 구현할 수 있습니다.
예:
@javax.ejb.Stateless
public class Book implements Purchasable {
- (선택사항) 사용자 애플리케이션에서 자원에 쉽게 액세스할 수 있도록
@javax.annotation.Resource 어노테이션이 있는 Java EE 자원 필드와 특성을 JAX-RS EJB 클래스에 추가하십시오. Java EE 인젝션은 JAX-RS 어노테이션이 있는
일반 Java 클래스에서 작동하지 않습니다.
JAX-RS 어노테이션이 있는 클래스가 엔터프라이즈 Bean 또는
JCDI(Java Context and Dependency Injection) (JSR-299) 관리
bean인 경우에만 JAX-RS EJB 클래스로 @javax.annotation.Resource 어노테이션이 있는 Java EE 자원 필드 및 특성을 삽입할 수 있습니다. 예:
package com.example.jaxrs;
@javax.ejb.Stateless
@javax.ejb.Local(Purchasable.class)
public class Book implements Purchasable {
@javax.annotation.Resource(name="jdcb/TestDataSource")
private javax.sql.DataSource datasource;
public int getItemsLeft(String itemID) {
// Reads from the datasource.
// Returns the number of items left.
}
public Order purchase(String itemID, String orderId) {
// Reads from the datasource.
// Adds the given item to the order id and returns it.
}
}
이 예에서 데이터 소스가 올바른 JNDI 이름으로 적절히 구성되면,
DataSource 오브젝트가 자원 클래스에 삽입됩니다.
- (선택사항) JAX-RS @javax.ws.rs.core.Context 인젝션을 사용하여 요청 정보에 대한
액세스를 확보하십시오. @javax.ws.rs.core.Context UriInfo 필드를 JAX-RS
EJB 클래스에 추가하여 요청 URI에 대한 정보에 액세스할 수 있습니다. 예:
package com.example.jaxrs;
@javax.ejb.Stateless
@javax.ejb.Local(Purchasable.class)
public class Book implements Purchasable {
@javax.ws.rs.core.Context
private UriInfo uriInfo;
public int getItemsLeft(String itemID) {
// Return the number of items left.
}
public Order purchase(String itemID, String orderId) {
// Add the given item to the order id and return it.
}
}
요청에서 @javax.ws.rs.HeaderParam, @javax.ws.rs.QueryParam 및
@javax.ws.rs.PathParam과 같은 매개변수를 읽으려면 자원 메소드에 매개변수를 추가하십시오. 예:
package com.example.jaxrs;
@javax.ws.rs.Path("itemsForPurchase/{itemID}")
public interface Purchasable {
public int getItemsLeft(String itemID);
@javax.ws.rs.POST
public Order purchase(
@javax.ws.rs.PathParam("itemID") String itemID,
@javax.ws.rs.QueryParam("orderId") String orderID);
}
package com.example.jaxrs;
@javax.ejb.Stateless
@javax.ejb.Local(Purchasable.class)
public class Book implements Purchasable {
@javax.ws.rs.core.Context
private UriInfo uriInfo;
public int getItemsLeft(String itemID) {
// Returns the number of items left.
}
public Order purchase(String itemID, String orderId) {
// The method parameters contain the request values.
// Add the given item to the order id and return it.
}
/* The following field will not be set. */
@javax.ws.rs.QueryParam("q")
private String willNotWork;
@javax.ws.rs.QueryParam("q")
public void setMyQueryParam(String q) {
/* This property will not be set. */
}
}
지원된 구성: 비즈니스 인터페이스를 사용하는 경우에는
EJB 비즈니스 인터페이스에 있는 자원 메소드에 JAX-RS 매개변수 어노테이션이 추가되어야 합니다.
이들은 구현 Bean에 추가될 수 없습니다.
sptcfg
- 엔터프라이즈 Bean을 WAR 파일의 WEB-INF/classes 디렉토리에 또는 WAR 파일의 WEB-INF/lib
디렉토리에 포함되는 JAR 파일 내부로 패키징하십시오.
클라이언트가 JAX-RS 어노테이션이 있는
엔터프라이즈 Bean에 대한 요청을 작성하는 경우, JAX-RS 런타임 환경을 검색하고 클래스의 EJB 인스턴스를 사용하여
JAX-RS 자원 메소드를 호출합니다.
결과
JAX-RS 자원이 이용을 위해 공개되도록 로컬 인터페이스가 있는 기존 엔터프라이즈 Bean을
사용으로 설정했습니다.