|
@Asset public class TransactionAsset { public Transaction transaction; public TransactionAsset(Transaction transaction) { this.transaction = transaction; } @Produces("application/xml") public Transaction getTransaction() { return this.transaction; } @Consumes("application/xml") public void setTransaction(Transaction transaction) { this.transaction = transaction; } } |
이 자산 클래스는 자원 메소드에 의해 응답으로 리턴되거나 매개변수로 전달될 수 있다. Apache Wink 런타임에서는 자산 클래스를 사용하여 자산 클래스의 해당 메소드를 호출하여 실제 응답 엔티티를 구성한다.
JAX-RS 스펙에 따라 기본적으로 공급자 및 자원 클래스는 각 JAX-RS 애플리케이션에 대해 한 번씩 인스턴스화된다. 이 인스턴스화에는 이후에 종속 항목이 삽입되는 호출 중인 클래스의 기본 생성자가 포함된다.
공급자 및 자원 오브젝트의 해당 메소드는 가비지 콜렉션에 사용할 수 있도록 하기 전에 오브젝트의 수명 동안 여러 번 호출될 수 있다. Apache Wink는 @Scope
어노테이션을 통해 공급자 및 자원에 대한 기타 라이프 사이클을 제공한다. Listing 2에서는 요청별 프로토타입 라이프 사이클을 사용하여 자원을 정의하는 방법을 보여 준다.
@Scope(ScopeType.PROTOTYPE) @Path("helloworld") public class HelloWorldResource { ... } |
프로토타입 라이프 사이클에서 Apache Wink 런타임은 모든 수신 요청에 대한 새 오브젝트를 인스턴스화한다. 이 동작은 메모리/성능 관점에서는 이상적이지 않을 수 있지만 자원 및 공급자 클래스에서의 스레드 및 동시성 문제에 대한 걱정은 하지 않아도 된다.
이 시리즈의 Part 1에서는 @Path
어노테이션에 대해 자세히 설명했으며 이 어노테이션이 JAX-RS에서 수신 요청의 URI 일치 패턴을 정의하는 데 사용됨을 지적했다. 이 어노테이션은 일반적으로 Java 클래스 또는 메소드에 배치된다.
@Parent
어노테이션은 @Path
어노테이션과 밀접하게 "관련"되어 있어 자원에 지정된 항목의 기반 URI를 제공한다. Apache Wink 런타임은 자원에 @Parent
어노테이션이 있으면 먼저 상위 자원 클래스의 URI를 보유하는 @Parent
어노테이션의 값을 계산하여 최종 자원 URI 템플리트를 계산한 후 자원 경로 URI를 상위 자원의 URI에 연결한다. Listing 3에 @Parent
어노테이션의 예제가 제공된다.
@Path("parentservice") public class ParentResource { ... } @Parent(ParentResource.class) @Path("childservice") public class ChildResource { ... } |
이 예제에는 ParentResource
자원과 ChildResource
자원이 있다. ParentResource
는 @Path
어노테이션이 parentservice
URI가 되도록 정의한다. ChildResource
는 @Path
어노테이션이 childservice
URI가 되도록 정의한다. 또한 ChildResource
는 @Parent
어노테이션을 사용하여 ParentResource
가 상위가 되도록 정의한다. 이 예제에서 Apache Wink 런타임은 parentservice/childservice
의 최종 URI 경로가 ChildResource
가 되도록 해석한다.
개발자가 RESTful 웹 서비스에 대해 더 잘 이해할 수 있도록 Apache Wink는 두 가지 유형의 관리 보기(애플리케이션 자원 XML 보기와 자원 레지스트리 XML 보기)를 제공한다. 기본적으로 이러한 두 보기는 비활성화되어 있으므로 애플리케이션 web.xml 파일에서 org.apache.wink.server.internal.servlet.AdminServlet
클래스를 등록하여 활성화해야 한다.
애플리케이션 자원 XML 보기는 사용자에게 애플리케이션을 사용할 수 있도록 만든 방식과 비슷한 방식으로 REST 자원을 URI 템플리트, HTTP 메소드 및 각 메소드에서 지원하는 MIME 유형과 함께 노출한다. 이 보기는 전개된 서비스에 대한 자동 서비스 문서를 생성하는 데 유용하다.
자원 레지스트리 XML 보기는 애플리케이션 자원 XML 보기보다 자세하며 자원과 해당 우선순위를 레지스트리에서 구현하는 클래스 이름을 포함하여 노출된 서비스의 실제 구현 세부 사항을 표시한다. 이 보기는 디버깅 용도로는 유용하지만 구현 세부 사항을 표시하여 보안에 위협이 될 수 있기 때문에 프로덕션에서는 활성화해서는 안 된다.
WebDAV(Web-based Distributed Authoring and Versioning)는 사용자가 Apache 웹 서버와 같은 웹 서버에서 파일을 편집하고 관리할 수 있게 하는 코어 HTTP 프로토콜에 대한 확장 세트이다. WebDAV 프로토콜의 기본 기능 중 일부는 다음과 같다.
Apache Wink는 확장 모듈을 통해 WebDAV 프로토콜을 지원한다. Apache Wink 확장 모듈에는 WebDAV 응답의 작성 및 처리를 지원하는 WebDAV XML 모듈 및 WebDAV 응답 빌더가 포함되어 있다.
Spring은 자주 사용되는 오픈 소스 Java 프레임워크이며 원래 EJB(Enterprise JavaBean) 기술과 같은 기존 Java 표준에 대한 경량 대체 표준으로 사용하기 위한 것이었다. EJB 표준과 마찬가지로 Spring Framework도 트랜잭션, 지속성, 보안과 더 중요하게는 종속성 삽입(JAX-RS도 이 개념에서 차용함)을 위한 기능을 제공한다. Spring Framework에 대한 자세한 정보는 참고자료를 참조한다.
Apache Wink는 코어 프레임워크와 함께 제공되는 추가 모듈을 통해 간편한 Spring 통합을 제공한다. Apache Wink Spring 통합 모듈은 다음과 같은 기본 기능을 제공한다.
Spring Framework에서 Spring 컨텍스트는 Apache Wink 애플리케이션과 비슷하며 다른 Spring Bean을 정의하고 로드하기 전에 로드되어야 한다. Spring 컨텍스트가 로드되면 자원 및 공급자를 Spring Bean으로 쉽게 등록할 수 있다.
Spring 컨텍스트를 로드하려면 먼저 컨텍스트 로드 리스너를 정의하여 웹 애플리케이션의 web.xml 파일에 추가해야 한다. 또한 contextConfigLocation context-param
도 Apache Wink 코어 컨텍스트 파일 및 애플리케이션 특정 컨텍스트 파일의 위치를 나타내야 한다. Listing 4에는 Spring 컨텍스트를 정의하고 로드하는 web.xml 파일의 예제가 제공된다.
Listing 4. web.xml을 로드하는 Spring 컨텍스트
<context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:META-INF/server/winkCoreContext-server.xml classpath:mySpringcontext.xml </param-value> </context-param> <listener> <listener-class> org.springframework.web.context.ContextLoaderListener </listener-class> </listener> |
Spring 컨텍스트가 로드된 경우 Apache Wink가 제공하는 org.apache.wink.spring.Registrar
클래스를 사용하여 자원 및 공급자를 등록할 수 있다. Registrar
클래스는 익숙한 WinkApplication
클래스의 확장이며 먼저 Spring Bean으로 정의되어야 한다.
Registrar
클래스를 사용하여 다음 특성을 정의할 수 있다.
Application
클래스에 있는 getClasses
메소드의 특성과 동일하다.
WinkApplication
의 우선순위를 정의한다. Listing 5는 Apache Wink 자원 및 공급자를 Spring Bean으로 정의하는 Spring Bean 구성 파일의 예제이다.
Listing 5. Spring 구성 파일 mySpringcontext.xml
<bean class="org.apache.wink.spring.Registrar"> <property name="classes"> <set value-type="java.lang.Class"> <value>org.openengine.example.TransactionResource</value> </set> </property> <property name="instances"> <set> <ref bean="resources.TransactionResource"/> <ref bean="providers.myprovider"/> </set> </property> </bean> |
JAX-RS 준수 서버 프레임워크인 것 외에도 Apache Wink는 정교한 클라이언트 프레임워크와 함께 제공된다. Apache Wink 클라이언트 프레임워크는 단순 Java API를 제공하여 클라이언트 구현 태스크에서 HTTP 기반 RESTful 웹 서비스를 쉽고 간단하게 이용할 수 있도록 한다. Apache Wink 클라이언트 프레임워크에도 HTTP 요청 및 응답을 조작하는 데 필요한 사용자 정의 가능한 처리기 메커니즘이 있다. Apache Wink 클라이언트는 JAX-RS 원칙에 따라 빌드되며 REST 기반 개념 및 표준을 포함한다. REST에서 유발된 아이디어를 Java 클래스에 맵핑하여 Apache Wink 기반 서비스뿐만 아니라 HTTP 구동 RESTful 웹 서비스를 위한 클라이언트 개발도 지원한다. 이로 인해 독립형 REST 기반 Java 클라이언트 프레임워크로서 매우 유용하게 된다.
Apache Wink 클라이언트 프레임워크의 기본 기능 중 일부는 다음과 같다.
java.net.HttpUrlConnection
클래스를 사용함
그림 1의 다이어그램에서는 Apache Wink 클라이언트 프레임워크의 아키텍처를 보여 준다.
이와 같이 Apache Wink 클라이언트 프레임워크는 다양한 구성 및 공급자 레지스트리를 보유하는 항목의 중심점 역할을 하는 RestClient
클래스로 기본적으로 구성되어 있다. 클라이언트 프레임워크에 대한 작업을 시작하려면 RestClient
오브젝트의 새 인스턴스를 인스턴스화해야 한다. 그런 다음 연결할 서비스의 URI를 사용하여 Resource
클래스의 인스턴스를 작성한다. Resource
클래스는 특정 URI와 연관된 RESTful 웹 자원의 Java 동등 항목이며 이 자원에서 HTTP 기반 조작을 수행하는 데 사용된다. 모든 HTTP 메소드 호출은 HTTP 요청 및 응답을 간편하게 조작할 수 있도록 하는 사용자 정의 가능한 처리기 체인을 통해 필터링된다.
Listing 6에서는 Apache Wink 클라이언트를 사용한 HTTP GET
요청의 사용에 대해 보여 준다.
// create the rest client instance RestClient client = new RestClient(); // create the resource instance to interact with Resource resource = client.resource("http://localhost:8080/HelloWorld"); // perform a GET on the resource. The resource will be returned as plain text String response = resource.accept("text/plain").get(String.class); |
이미 언급했듯이 RestClient
오브젝트는 Apache Wink 클라이언트 프레임워크의 시작점이다. RESTful 웹 서비스 클라이언트를 빌드하려면 RestClient
오브젝트의 새 인스턴스를 인스턴스화해야 하며 그러면 RestClient#resource()
메소드를 호출하여 호출하려고 하는 서비스의 URI를 사용하여 새 Resource
오브젝트가 작성된다. HTTP GET
요청을 발행하려면 Resource#get()
메소드를 호출한다. 이 메소드는 HTTP 응답을 리턴한다. 그런 다음 적절한 공급자를 호출하면 클라이언트가 응답을 직렬화 해제할 수 있다.
Listing 7에서는 Apache Wink 클라이언트를 사용한 HTTP POST
요청의 사용에 대해 보여 준다.
// create the rest client instance RestClient client = new RestClient(); // create the resource instance to interact with Resource resource = client.resource("http://localhost:8080 "); // issue the request String response = resource.contentType("text/plain"). accept("text/plain"). post(String.class, "foo"); |
이와 같이 POST
요청을 발행하는 것은 GET
요청을 발행하는 것과 비슷하다. GET
요청 예제와 마찬가지로 RestClient
를 통해 Resource
의 새 인스턴스를 작성한다. 유일한 차이점은 요청 및 응답 매체 유형과 응답 엔티티 유형을 지정한 후 POST
문자열 자체가 메소드 매개변수로 resource.post
메소드에 전달되는 것이다. 다시 한번 응답이 문자열로 리턴된다.
위에서 언급했듯이 Apache Wink 클라이언트 프레임워크는 여러 컨텐츠 유형의 요청을 발행하는 기능도 제공한다. Listing 8에는 Atom 항목을 송수신하는 HTTP POST
요청의 발행에 대해 보여 주는 예제가 제공된다.
// create the rest client instance RestClient client = new RestClient(); // create the resource instance to interact with Resource resource = client.resource("http://services.co"); AtomEntry request = getAtomEntry(); // issue the request AtomEntry response = resource.contentType("application/atom+xml"). accept("application/atom+xml"). post(AtomEntry.class, request); |
Apache Wink 클라이언트는 Atom 피드 및 항목을 송수신할 수 있도록 하는 Atom의 오브젝트 모델을 제공하기 때문에 AtomEntry
오브젝트를 사용하여 Atom 요청을 발행하고 응답을 구문 분석하는 것은 단순하다.
이 기사에서는 어노테이션, 관리 보기 및 WebDAV 지원을 포함한 Apache Wink 1.0 프레임워크 관련 고급 주제 중 일부에 대해 간단하게 살펴봤다. 또한 Apache Wink가 내장 확장 모듈을 통해 Spring 통합을 지원하는 방법에 대해 살펴봤으며 Apache Wink 클라이언트 프레임워크 및 해당 기본 아키텍처에 대해 자세히 살펴봤다. 이 시리즈의 Part 3에서는 Apache Wink와 기타 JAX-RS 준수 프레임워크의 비교 연구에 대해 설명하고 이들의 상대적인 장점과 단점에 대해 설명한다. REST, JAX-RS 또는 Apache Wink 1.0 프레임워크에 대해 자세히 살펴보려면 참고자료를 참조한다.