Version 1.0.2
저작권 © 2007-2011 삼성SDS
웹 서비스 구현을 위해 많이 사용하고 있는 오픈소스 프레임워크에는 Apache CXF, Apache Axis/Axis2, Spring Web Services 등등 여러가지가 존재한다. cxf plugin은 이 중 Apache CXF를 활용하는데 필요한 참조 라이브러리들과 JAXB Databinding 수행시 요구되는 Map 타입에 대한 기본 XmlAdapter 클래스를 제공하는 CXF Service로 구성되어 있다.
Installation
Command 창에서 다음과 같이 명령어를 입력하여 cxf plugin을 설치한다.
mvn anyframe:install -Dname=cxf
installed(mvn anyframe:installed) 혹은 jetty:run(mvn clean jetty:run) command를 이용하여 설치 결과를 확인해볼 수 있다.
Dependent Plugins
| Plugin Name | Version Range |
|---|---|
| Core | 2.0.0 > * |
Anyframe은 Apache CXF 2.3.0 버전을 이용하여 웹 서비스 기능을 제공하고 있다.
웹 서비스란 인터넷 네트워크를 통하여 다수의 기존 어플리케이션 시스템을 표준화된 기술로서 상호 작용 시키고, 이러한 표준 기술을 이용하여 모든 비즈니스를 가능하게 한다.
웹 서비스는 언제, 어디에서나 원하는 정보나 서비스를 제공해 주는 역할을 하며 기존의 다른 소프트웨어처럼 완벽한 정의를 지정하여 구성하는 것이 아니라 서로 주고받는 데이터 표준에 대한 정의를 규정함으로써 매우 유연하고 이질적인 운영시스템, 이질적인 프로그램 언어 간의 커뮤니케이션 차이를 극복해 주는 연결고리 역할을 수행한다.
Web Service Architecture Working Group. W3C (Web Services Glossary, Web Services Architecture 등 자료 조회 가능)에서는 Web Services를 다음과 같이 정의하고 있다.
"A Web service is a software system designed to support interoperable machine-to-machine interaction over a network. It has an interface described in a machine-processable format (specifically WSDL). Other systems interact with the Web service in a manner prescribed by its description using SOAP-messages, typically conveyed using HTTP with an XML serialization in conjunction with other Web-related standards."
위의 영문 정의를 해석해보면, 다음과 같다. 네트워크를 통해 상호 운용성있는 기계 대 기계 상호작용을 지원하기 위해 설계된 소프트웨어 시스템으로, WSDL이라는 형태로 정의된 인터페이스를 가지며, SOAP 메시지를 사용하여 타 시스템들은 웹 서비스와 상호 작용할 수 있다. 웹 관련 표준들과 협력하며 전형적으로 HTTP를 사용한 XML 직렬화를 통해 전송한다.
기본적으로 웹 서비스(Web Services)는 3가지 역할(Service Provider, Service Broker, Service Consumer)로 구성된 아키텍처 모델에 따라 구현된 기술이다.

웹 서비스의 3가지 역할
| Role | 설명 |
|---|---|
| Service Provider | 특정 서비스 스펙을 구현한 서비스를 제공한다. |
| Service Broker (Service Registry) | 서비스 등록 및 검색, 저장, 관리를 통해 Service Provider가 제공하는 서비스를 Service Consumer에게 연결한다. |
| Service Consumer (Service Requester) | Service Broker를 통해 특정 서비스를 찾고, Service Provider에게 해당 서비스를 요청하고 사용한다. |
웹 서비스 시나리오
| 순서 | Role | 설명 |
|---|---|---|
| 1 | 서비스 제공자(Service Provider) | 자신의 비즈니스 정보 및 제공할 서비스 정보, 그리고 이를 이용할 수 있는 방법 등에 대한 정보를 WSDL 파일로 작성한다. |
| 2 | 서비스 제공자(Service Provider) | 자신의 서비스 WSDL을 UDDI 레지스트리에 등록한다. 이때 등록되는 서비스는 UUID에 기반한 고유 ID를 부여받게 된다. |
| 3 | 서비스 요청자(Service Consumer) | UDDI 레지스트리에서 분류 및 식별 체계와 같은 여러 검색 조건을 통해 필요한 서비스를 검색하여 찾는다. 해당 서비스가 찾아지면, 그 서비스에 대한 WSDL 파일을 받게 된다. |
| 4 | 서비스 요청자(Service Consumer) | WSDL 정보를 이용해 Service Provider와 연결하여 서비스를 제공받게 된다. 이때 실행 결과는 SOAP을 이용한 XML 문서 형태로 받는다. |
웹 서비스의 3가지 기본 기술요소
| 기술요소 | 설명 |
|---|---|
| WSDL | 웹 서비스를 표현하고 기술하는 언어 (서비스 표현) |
| SOAP | 웹 서비스에서 사용되는 보편적이며 확장성 있는 메시지 프로토콜 (데이터 통신 프로토콜) |
| UDDI | 필요한 서비스를 찾을 수 있는 웹 서비스 레지스트리 (서비스 등록, 검색) |
SOAP(Simple Object Access Protocol)은 HTTP, HTTPS, SMTP등을 사용하여 XML 기반의 SOAP 메시지를 컴퓨터 네트워크 상에서 교환하는 형태의 프로토콜로써 웹 서비스의 기본적인 메시지 전송 수단 이다. XML-RPC와 WDDX에서 envelope/header/body로 이루어진 구조, 전송(transport), 상호 중립성(interaction neutrality)의 개념을 도입하였다.
SOAP 메시지 구조
SOAP 메시지는 루트 요소로 Envelope를 가지며, SOAP Header와 Body를 하위 요소로 가지고 있다. SOAP의 메시지 구조는 XML을 근간으로 Header와 Body를 조합하는 디자인 패턴으로 설계되었고, Body(필수사항)에는 전송될 메시 지의 내용을 기술한다. (Header는 선택사항)

SOAP 특징
| 장점 | 설명 |
|---|---|
| 1 | SOAP은 기본적으로 HTTP 기반 위에서 동작하기 때문에, HTTP와 같이 프록시와 방화벽에 구애받지 않고 쉽게 통신 가능하다. |
| 2 | SOAP은 표준 전송 프로토콜인 HTTP 이외의 다른 전송 프로토콜들을 사용할 수 있다. |
| 3 | 플랫폼 및 프로그래밍 언어에 독립적이다. |
| 4 | 간단하고 확장 가능하며, (멀티파트 MIME 구조를 사용하여) 첨부를 통합하는 SOAP XML 메시지를 지원한다. |
| 단점 | 설명 |
|---|---|
| 1 | XML 포맷은 태그 형태로 구성되기 때문에 CORBA와 같은 미들웨어 기술과 비교해서 상대적으로 느리다. (최근 네트워크 속도의 비약적인 발전과 성능 최적화 기술의 발전으로 대부분 해결됨) |
WSDL(Web Services Description Language)이란, 웹 서비스로 제공되는 서비스에 대한 정보를 기술하기 위한 XML 기반의 마크업 언어이다.
즉, 원하는 서비스가 어디(Where)에 존재하며, 웹서비스로 무엇(What)을 할 수 있고, 또 이를 실행하기 위해서는 어떻게 (How) 해야 하는가를 XML 형식으로 기술하여 제공하는 웹 서비스 기술 언어이다.
WSDL 문서 구조
<definitions></definitions>를 루트로 하여 추상적 정의(types/message/portType)와 구체적 정의(binding/service)로 나뉜다. 추상적 정의와 구체적 정의를 분리하여 기술함으로써, 서로 다른 서비스 구현시 서비스의 추상적 정의를 재사용할 수 있다.

WSDL 문서 구조 상세
WSDL의 주요 기술 내용에는 웹 서비스의 이름과 URI 정보, SOAP 메시지의 인코딩 방법, SOAP 메시지 전송을 위한 프로토콜 정보, 웹 서비스를 이용하는데 필요한 인터페이스 정보가 있다. WSDL의 구성 요소를 상세히 살펴보면 아래와 같다.

WSDL 상세 구성 요소에 대한 설명은 다음과 같다.
| 요소 | 설명 |
|---|---|
| <service> | Endpoint(실제 웹 서비스로 구현된 어플리케이션)의 물리적 위치를 정의하고 각 바인딩에 대한 포트 주소를 기술한다. |
| <port> | binding 정보와 address location을 정의한다.(WSDL 2.0에서는 <endpoint> 로 변경됨) |
| <binding> | portType과 네트워크 프로토콜 매핑 정보를 정의한다. 즉, 어떤 통신 프로토콜을 통해서 통신을 할 것인지를 정의한다. |
| <portType> | 인터페이스의 메소드들을 정의한다. Interface(WSDL 2.0에서 <interface>로 변경됨) |
| <operation> | 서비스의 메소드에서 사용되는 요청(Request)/ 응답(Response) 메시지 정의 |
| <message> | 서비스가 사용하는 메시지를 정의한다. 메소드의 인자와 리턴 값을 선언한다. (WSDL 2.0에서는 <types>를 통해 XML 스키마 타입을 사용하여 기술) |
| <types> | 문서에서 사용되고 있는 데이터 타입을 정의한다. |
웹 서비스는 SOAP, WSDL, UDDI를 중심으로 한 기본 기술 표준을 제공하며 서비스의 품질을 높이기 위해 보안, 트랜잭션 처리, 신뢰성 있는 메시지 처리 등에 대한 다양한 확장 표준을 제공한다.

Security
| 표준 | 설명 |
|---|---|
| WS-Security | 무결성(Integrity)과 기밀성(Confidentiality), 인증(Authentication) 등을 강화하기 위한 SOAP 메시지 확장 메커니즘 규정. 크게는 WS-Policy, WS-Trust, WS-SecureConversation, WS-Federation, WS-Authorization을 포함한다. |
| WS-Trust | 상호간에 웹 서비스가 안전하게 작동할 수 있도록 하기 위한 신용 관계의 유지 및 해지를 설정하는 신뢰 모델에 대한 표준이다. |
| WS-SecureConversation | 메시지 교환시 보안이 어떤 방식으로 관리되는지를 명시한 security context에 대한 관리 표준이다. |
Transaction
| 표준 | 설명 |
|---|---|
| WS-Coordination | 분산되어 있는 다양한 웹 서비스들이 트랜잭션에 참여할 수 있도록 액티비티를 생성 및 관리, 조정, 완료하는 메커니즘에 대한 표준 (Coordination Framework)이다. |
| WS-Transaction | Atomic 또는 Business 트랜잭션 프로토콜에 대한 표준 (Coordination Protocols)이다. |
Reliable Messaging
| 표준 | 설명 |
|---|---|
| WS-ReliableMessaging | 목적지까지 메시지가 확실하게 도착하는 메시징 신뢰도를 보장하기 위해, 분산된 웹 서비스들 간에 주고 받는 ACK (acknowledge) 메시지 등을 정의하는 표준이다. |
| WS-Addressing | 웹 서비스 간 메시지를 전달하는 메커니즘을 제공하는 표준이다. |
Java로 Web Services를 작성하는 방법을 제공하는 자바 API로는 JAX-RPC와 JAX-WS가 있으며, 이외에 여러 가지 구현 기술들이 요구된다.
JAX-WS 2.0이 JAX-RPC 1.1의 차후 버전으로 Web Services 구현 시 사용되는 표준 자바 API이다.
* JAX-WS : Java API for XML-Based Web Services
* JAX-RPC : Java API for XML-Based RPC(Remote Procedure call)
JAX-RPC와 JAX-WS 비교표
JAX-RPC 1.1의 다음 버전인 JAX-RPC 2.0이 나오면서, RPC라는 용어 대신 메시지 지향 웹서비스인 WS로 대체되어 JAX-WS 2.0으로 불리게 되었다.
| JAX-RPC 1.1 | JAX-WS 2.0 | |
|---|---|---|
| Java 환경 | JDK 1.4/ J2EE 1.4 환경에서 사용되는 Web Services API | Java EE 5/Java SE 6 환경(탑재)에서 사용되는 Web Services API |
| SOAP | SOAP 1.1 | SOAP 1.1, SOAP 1.2 |
| XML/HTTP | HTTP 바인딩 지원 안함 (SOAP 바인딩만 지원) | HTTP 바인딩 지원 (SOAP없이 HTTP를 통해 XML 전송) |
| WS-I Basic Profile | WS-I Basic Profile 1.0 | WS-I Basic Profile 1.1 |
| 데이터 매핑 모델 | 고유의 데이터 매핑 모델이 있음 (스키마 유형의 90% 커버) 커버되지 않는 것들은 javax.xml.soap.SOAPElement로 매핑 | JAXB (모든 XML 스키마를 100% 매핑함) |
| 인터페이스 매핑 모델 | 지원 안함 | Java 5.0 기능 사용 및 비동기식 기능 도입 |
| 동적 프로그래밍 모델 | 지원 안함 | 메시지 지향 및 동적 비동기식 기능 도입 |
| MTOM | 지원 안함 | JAXB를 통한 새로운 Attachment 스펙인 MTOM에 대한 지원을 추가 |
| 핸들러 모델 | SAAJ 1.2에 기반 | SAAJ 1.3에 기반 |
JAX-RPC 1.1을 사용해야 하는 경우
| Case | 설명 |
|---|---|
| 1 | JDK 1.4를 계속 사용해야 하는 경우 |
| 2 | SOAP 인코딩 메시지를 보내거나 RPC/encoded 스타일의 WSDL을 보내야 하는 경우 |
JAX-WS 2.0을 사용하는 경우
Layered Programming Model을 제공한다. 상위계층은 Annotation을 활용한 쉬운 개발이 가능하게 하며, 하위계층 의 경우 API 기반의 섬세한 조정이 가능하다.
| Case | 설명 |
|---|---|
| 1 | 새로운 메시지 지향 API를 사용해야 할 경우 |
| 2 | MTOM을 사용하여 첨부 데이터를 보내야 하는 경우 |
| 3 | JAXB를 통해 XML 스키마를 더욱 잘 지원하기 위한 경우 |
| 4 | 웹 서비스 클라이언트에 비동기식 프로그래밍 모델을 사용하고 싶을 경우 |
| 5 | SOAP 1.2 메시지를 처리할 수 있는 클라이언트와 서비스가 있어야 하는 경우 |
| 6 | 웹 서비스에서 SOAP을 배제하고 XML/HTTP 바인딩만 사용하고 싶을 경우 |
JAX-RPC 단점
구버전인 JAX-RPC에는 다음과 같이 몇가지 단점이 존재한다.
| 단점 | 설명 |
|---|---|
| 1 | 제한된 XML Schema를 지원한다. |
| 2 | Java와 WSDL간의 매핑 지원이 부족하다. |
| 3 | 어플리케이션 이식성이 낮다. |
| 4 | 런타임(Runtime) 크기가 비대하다. |
| 5 | 개발 방법이 매우 복잡하다. |
XML 문서의 구조와 컨텐츠를 정의하는 파일을 가리키는 일반적인 용어로 DTD와 마찬가지로 문서의 구조를 정의하며, 문법, 어휘, 구조, 데이터 타입 등을 규정하는 모든 규칙들을 제공한다.
* XML Schema Definition (XSD) : XML Schema를 작성하기 위한 XML Schema language
XML Schema vs. DTD
DTD의 문제점을 해결하기 위한 목적으로 XML Schema가 나왔다. XML Schema는 DTD보다 더 표현력이 풍부하고, 정확한 자료 구조를 제공하는 새로운 구조 정의 언어로, Web Services는 XML Schema를 사용한다.
| XML Schema | DTD |
|---|---|
| XML 문법으로 작성 | XML 문법 아님 (EBNF 문법 사용) |
| namespace 지원 | namespace 지원 안함 |
| 다양한 데이터 타입 지원, 데이터 타입 확장 가능 | 제한적인 데이터 타입 |
| 상속과 같은 객체 지향 개념 지원 | 객체 지향 개념 없음 |
| 개방적 컨텐츠 모델 | 폐쇄적 컨텐츠 모델 |
XML Schema element 정의
<element name="element 명" type="데이터형" ref="" form=""
minOccurs="" maxOccurs="" default="" fixed="" > 각 속성 값에 대한 설명은 다음과 같다.
| 속성 | 설명 |
|---|---|
| name | element의 명칭 |
| type | element의 데이터 타입 |
| ref | 전역 element 선언을 참조하기 위해 사용 |
| minOccurs | element의 최소 반복 횟수, default 값은 1 |
| maxOccurs | element의 최대 반복 횟수, default 값은 1 |
| default | element의 값이 정의되지 않았을 때 할당되는 기본값 |
| fixed | element에 들어갈 고정값 |
XML Schema attribute 정의
<attribute name="" type="" ref="" form="" use="" default="" fixed="">
각 속성 값에 대한 설명은 다음과 같다.
| 속성 | 설명 |
|---|---|
| name | attribute의 명칭 |
| type | attribute의 데이터 타입 |
| ref | 전역 attribute 선언을 참조하기 위해 사용 |
| form | 한정된 이름인지의 여부 (qualified/unqualified) |
| use | 사용 조건 (optional/prohibited/required) |
| default | attribute의 값이 정의되지 않았을 때 할당되는 기본값 |
| fixed | attribute에 들어갈 고정값 |
JAXB(Java Architecture for XML Binding)
XML 스키마를 자바 클래스로 바인딩하기 위한 자바 API로 크게 2가지 기능을 제공한다. 그 기능은 바로 자바 객체를 XML로 마샬링(marshalling)하는 기능과 반대로 XML에서 자바 객체로 언마샬링(unmarshalling)하는 기능이다. 더욱 자세한 내용은 여기 를 참고하도록 한다.
MTOM(Message Transmission Optimization Mechanism)
SOAP 메시지와 함께 큰 바이너리 첨부 파일을 원시 바이트로 전송하여 메시지 크기를 줄이는 메커니즘으로 바이너리 데이터를 포함한 XML에 대한 메시지 전송을 최적화시킨다. 더욱 자세한 내용은 여기 를 참고하도록 한다.
SAAJ(SOAP with Attachments API for Java)
SOAP 메시지를 생성하고 파일 첨부하고 전송하는 방법을 제공하는 자바 API이다. 더욱 자세한 내용은 여기 를 참고하도록 한다.
많이 사용되는 웹 서비스 오픈 소스 프레임워크로는 Apache CXF, Apache Axis/Axis2, Spring Web Services 등이 존재하며 여러 프레임워크 중 사용하고자 하는 목적에 적합한 웹 서비스 프레임워크를 선정한다. Anyframe에서는 Apache CXF를 선정하였다.
Web Service 구현 스타일은 크게 Contract-Last와 Contract-First가 있다. Contract-Last 스타일은 Java 소스 코드를 먼저 작성한 후에 WSDL을 자동생성하여 구현하는 방식(Code-First라고 불리기도 함)이고, Contract-First 스타일은 WSDL 파일을 먼저 작성한 후 Java 소스 코드를 작성하는 방식이다.
Web Services Open Source Framework에는 여러 가지가 있는데 이 중 현재 가장 많이 쓰이고 있는 4가지에 대해서 소개한다.
Apache CXF
Contract-First 스타일과 Contract-Last 스타일 모두를 지원한다. 자세한 내용은 http://cxf.apache.org/ 를 참조한다.
Apache Axis
Axis2의 구버전으로 웹 서비스 개발 방식이 복잡하다. 자세한 내용은 http://ws.apache.org/axis/ 를 참조한다.
Apache Axis2
Apache Axis의 업그레이드 버전으로 구조 등이 새롭게 변경되었다. 기능적인 면에서 Apache CXF와 유사하다. 자세한 내용은 http://ws.apache.org/axis2/ 를 참조한다.
Spring Web Services
Contract-First 스타일의 웹 서비스 개발 방식만 지원한다. 자세한 내용은 http://static.springsource.org/spring-ws/site/ 를 참조한다.
여러가지 Web Services Framework 중 Apache CXF를 선정하게 된 이유는 다음과 같은 특징 때문이다.
| 특징 | 설명 |
|---|---|
| JAX-WS 지원 | CXF에서는 JAX-WS API를 구현하고 있어서 웹 서비스 구현을 쉽게 하고 있다. |
| Spring Integration | CXF는 Spring 2.X 이상을 지원하며 endpoint 설정이나 client injection 등 Spring과의 통합을 용이 하게 한다. |
| Aegis Databinding | CXF는 JAXB, Aegis Databinding을 모두 지원한다. JAXB의 경우와 다르게 Annotation 방식으로 사용할 필요가 없으며, List/Map/Date 등의 다양한 데이터 타입 사용이 매우 쉽다. Anyframe에서는 표준 방식인 JAXB Databinding을 채택하여 사용하도록 권고하고 있으므로 Aegis Databinding에 관한 상세한 내용은 매뉴얼에서 언급하고 있지 않다. |
| RESTful services | Annotation 설정 방식으로 RESTful 서비스 구현을 용이하게 한다. Apache CXF를 이용하여 RESTful services를 개발하는 방법에 대한 자세한 내용은 Anyframe CXF-JAXRS Plugin 매뉴얼을 참고하도록 한다. |
| WS-* Support | CXF는 다양한 웹 서비스 스펙(WS-Addressing, WS-Policy, WS-ReliableMessaging, WS-Security)을 지원한다. |
| Apache Licensed | 아파치 라이센스 사용으로 활용에 자유롭다. |
| Celtix와 X-Fire 프로젝트의 합작품 | 기능 보강 및 사용 편의성 면에서 새롭게 재구성된 부분이 많이 존재한다. |
| 웹 서비스 표준 지원 | SOAP, the Basic Profile, WSDL, WS-Addressing, WS-Policy, WS-ReliableMessaging, WS-Security |
| Frontend 모델 제공 | JAX-WS Frontend와 Simple Frontend를 제공한다. Anyframe에서는 표준 API인 JAX-WS를 사용하는 JAX-WS Frontend 모델을 채택하여 사용하도록 권고하고 있으므로 Simple Frontend에 관한 상세한 내용은 매뉴얼에서 언급하고 있지 않다. |
| 사용 편의성 | 간단한 API 사용으로 서비스 구현 가능, Tool(ANT Task 등)을 제공한다. |
| 바이너리와 기존 프로토콜 지원 | XML/비-XML 타입 바인딩(JSON, CORBA)을 제공, 여러 전송 프로토콜을 지원할 수 있는 조립식 아키텍처를 제공한다. |
| 비동기 방식 호출 가능 | 비동기 방식의 호출이 가능(Asynchronous Invocation Model 제공)하다. |
| JDK 1.5 이상 지원 | Annotation 기능 등 여러 가지 이유 때문에 JDK 1.5 이상만 지원한다. |
Apache CXF에서 여러가지 Tool을 제공함으로써 웹 서비스 구현 시 개발 편의성을 높여주고 있다. 아래에 언급된 Tool 이외에 Eclipse Plugin과 Maven Plugin 형태의 Tool도 제공되고 있다. Apache CXF를 다운로드 페이지 에서 Binary distribution을 내려 받고 압축을 풀면 루트 폴더 하위의 bin 폴더 내에 Tool이 존재한다. 자세한 사항은 이곳 을 참고하도록 한다.
| tool | 설명 |
|---|---|
| Ant Tasks | wsdl2java, java2ws를 위한 ant task를 제공한다. |
| Java to WS | SEI 클래스와 관련 타입 클래스들로부터 WSDL document, wrapper bean 클래스, server/client side 소스 코드들을 생성한다.(CXF 2.1) |
| Java to WSDL | SEI 클래스와 관련 타입 클래스들로부터 WSDL document를 생성한다.(CXF 2.0.x) |
| Maven Integration and Plugin | 관련 라이브러리를 배포해주는 Maven Repository들과 함께 빌드 툴로써 Maven을 사용할 수 있도록 Maven Plugin 을 제공한다. |
| XSD to WSDL | XSD(Schema 파일)를 통해서 WSDL document를 생성한다. |
| WSDL to Java | WSDL document로부터 서비스 구현에 필요한 annotation으로 작성된 Java 소스 코드와 어플리케이션을 빌드할 수 있는 ANT 기반 XML 파일을 생성한다. |
| WSDL to Service | WSDL document로부터 HTTP 혹은 JMS 서비스 정의를 갖는 새로운 WSDL document를 생성한다. |
| WSDL to SOAP | WSDL document로부터 SOAP binding 정보를 갖는 새로운 WSDL document를 생성한다. |
| WSDL to XML | WSDL document로부터 XML binding 정보를 갖는 새로운 WSDL document를 생성한다. |
| WSDLValidator | WSDL document나 WSDL URL이 well-formed document이고 Schema에 맞게 작성된 것인지 확인해주는 일을 한다. |
XML 문서의 XSD Schema를 기준으로 XML문서와 JavaBeans 객체를 매핑하는 것을 Databinding이라고 하며, Web Services에서 서버와 클라이언트 간의 XML 문서를 주고 받아서 일을 수행하려고 할때 사용 되는 기술이다. Apache CXF는 Databinding을 위해 JAXB를 디폴트로 사용하며 Aegis, MTOM을 추가적으로 지원한다. Databinding의 종류는 다음과 같다.
JAXB
Java Architecture for XML Binding의 약자로 XML Schema로부터 클래스 데이터를 바인딩하여 XML로부터 객체를 Unmarshalling 하거나, 반대로 객체를 XML로 저장하는 Marshalling을 수행할 수 있도록 해 준다.
Aegis
Aegis는 JAXB와 다르게 표준(Spec.)이 아니며, Apache CXF에서만 제공되는 기능으로 JAXB와 역할이 동일하다. Xfire 프로젝트의 일부로 시작되었으나 Celtix와 Xfire의 합체로 현재 Apache CXF에 포함되어 발전되고 있다. Anyframe에서는 JAXB Databinding 방식을 채택하여 사용하도록 권고하고 있으므로 Aegis Databinding에 관한 상세한 내용은 매뉴얼에서 언급하고 있지 않다.
MTOM
Message Transmission Optimization Mechanism의 약자로 SOAP 메시지 통신 최적화 메커니즘이다. 웹 서비스를 통해 바이너리 데이터를 효과적으로 편리하게 전송할 수 있도록 하는 표준이다.
Databinding 기술 종류를 그림으로 살펴보면 다음과 같다. 보통 JAXB, JAXB+MTOM, Aegis, Aegis+MTOM의 형태로 Databinding 기술이 사용된다. 그림에서 JAXB와 Aegis의 공통 영역이 존재하는 이유는 Aegis를 사용하면서 몇가지 JAXB Annotation을 함께 사용할 수 있기 때문이다.

다음은 각각의 Databinding 기술 별로 어떻게 사용하는지에 대한 사용법이다.
JAXB는 Java Architecture for XML Binding의 약자로 XML Schema로부터 클래스 데이터를 바인딩하여 XML로부터 객체를 Unmarshalling 하거나, 반대로 객체를 XML로 저장하는 Marshalling을 수행할 수 있도록 해 준다.
JAXB의 특징 을 살펴보면 다음과 같다.
Apache CXF 사용 시 디폴트 Databinding 방식이 JAXB이므로, JAXB 사용을 위한 추가 설정이 필요없다.
JavaBeans 코드에 @XmlElement와 같은 Annotation을 설정하여 element 명을 변경시킬 수 있다.
JavaBeans 코드에 Annotation 설정 없이도 JAXB를 사용할 수 있다.
List 형태의 타입은 지원하나 Map 형태의 타입에 대해서는 Databinding을 기본적으로 지원하지 않으므로 Map 형태의 타입을 이용하여 Databinding 하기 위해서는 XmlAdapter 클래스를 추가로 작성해줘야 한다.
JavaBeans 객체와 XML Schema 간의 매핑 관계 를 보면 다음과 같다.

JAXB의 역할 수행 모습을 그림을 통해 살펴보면 다음과 같다.

다음은 JAXB 기능을 Server와 Client 단에서 어떻게 사용해야 하는지에 대한 사용법이다.
Movie Service를 JAX-WS Frontend를 사용하여 Web Services로 노출시킬 때 인터페이스 메소드의 파라인터 인자와 리턴 값의 타입을 다양한 타입으로 선언하여 테스트해보도록 한다.
다음은 Movie Service의 인터페이스 클래스 정의와 Map 타입 사용을 위한 XmlAdapter 클래스 정의에 대한 예제이다.
Interface Class
다음은 Movie Service의 인터페이스 클래스를 작성한 MovieService.java의 일부이다.
이때 유의할 사항은 @XmlSeeAlso annotation인데, JAXB Databinding 수행 시 Map 객체 내에 저장된 Movie 클래스 타입을 알아야 하기 때문에 @XmlSeeAlso annotation을 설정하고 있는 것에 유의하도록 한다. 만약 이 웹서비스의 다른 메소드에서 Movie 객체를 Input 혹은 Output parameter 클래스 타입으로 사용하고 있다면 @XmlSeeAlso annotation을 설정할 필요가 없다.
@WebService
@XmlSeeAlso(Movie.class)
public interface MovieFinder {
@XmlJavaTypeAdapter(CXFMapAdapter.class)
Map<String, Movie> get(String movieId) throws Exception;
중략...XmlAdapter Class [Anyframe 제공 클래스]
Movie Service의 인터페이스 메소드 중 리턴 타입이 Map인 경우, XmlAdapter 클래스가 추가 작성되어야 한다. Map 타입을 사용하지 않는 경우 작성할 필요 없다. 다음은 XmlAdapter 클래스를 상속받아 구현한 CXFMapAdapter.java 의 일부이다. 개발자들은 따로 구현할 필요없이 Anyframe에서 제공하는 org.anyframe.cxf.adapter.CXFMapAdapter 클래스를 사용한다.
public class CXFMapAdapter extends XmlAdapter<CXFMap, Map<String, Object>> {
public CXFMap marshal(Map<String, Object> v) throws Exception {
CXFMap map = new CXFMap();
for (Map.Entry<String, Object> e : v.entrySet()) {
CXFMap.CXFEntry iue = new CXFMap.CXFEntry();
iue.setValue(e.getValue());
iue.setKey(e.getKey());
map.getEntries().add(iue);
}
return map;
}
public Map<String, Object> unmarshal(CXFMap v) throws Exception {
Map<String, Object> map = new LinkedHashMap<String, Object>();
for (CXFMap.CXFEntry e : v.getEntries()) {
map.put(e.getKey(), e.getValue());
}
return map;
}
}
중략...
XmlAdapter Class에서 사용하는 부가 클래스 [Anyframe 제공 클래스]
위에서 작성한 XmlAdapter 클래스 내에서 marshalling/unmarshalling 작업 시 사용되는 CXFMap 클래스 또한 추가 작성되어야 한다. Map 타입을 사용하지 않는 경우 작성할 필요 없다. 다음은 CXFMap 클래스를 작성한 CXFMap.java 의 일부이다. 개발자들은 따로 구현할 필요없이 Anyframe에서 제공하는 org.anyframe.cxf.adapter.CXFMap 클래스를 사용한다.
@XmlType(name = "CXFMap")
@XmlAccessorType(XmlAccessType.FIELD)
public class CXFMap {
@XmlElement(nillable = false, name = "entry")
private List<CXFEntry> entries = new ArrayList<CXFEntry>();
public List<CXFEntry> getEntries() {
return entries;
}
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "IdentifiedCXF")
static class CXFEntry {
// Map keys cannot be null
@XmlElement(required = true, nillable = false)
private String key;
private Object value;
public String getKey() {
return key;
}
public void setKey(String key) {
this.key = key;
}
public Object getValue() {
return value;
}
public void setValue(Object value) {
this.value = value;
}
중략...
JAXB Databinding 방식을 사용하여 Web Services로 노출된 메소드에 접근하여 사용 시 유의해야 하는 사항이다.
SEI 클래스에 정의된 메소드의 입력값이나 리턴값으로 참조되지 않은 Java Type 클래스의 경우, Runtime 시 Databinding이 일어날 때 다음과 같은 에러 메시지가 나오게 됩니다.
org.apache.cxf.interceptor.Fault: Marshalling Error: class org.anyframe.sample.domain.Movie nor any of its super class is known to this context.
아래 방법을 통해서 해결하도록 한다.
Interface Class
SEI(Service Endpoint Interface) 클래스의 메소드에서 List 형태의 결과값을 리턴하는 메소드가 존재하고 해당 List내에 저장된 Java Type 클래스에 대해서는 참조하지 않을 때, 클라이언트가 해당 메소드를 호출할 때 Runtime시에 JAXB Databinding을 시도하려고 하면서 Marshalling Error가 발생하게 된다. 이를 방지하기 위해서 @XmlSeeAlso Annotation 혹은 JDK1.5의 Generic Type을 설정하도록 한다.
@XmlSeeAlso 사용 예제
@WebService
@XmlSeeAlso({Movie.class})
public interface MovieService {
public List getMovieList(SearchVO searchVO);
중략...
JDK 1.5의 Generic Type 사용 예제
@WebService
public interface MovieService {
public List<Movie> getMovieList(SearchVO searchVO);
중략...
MTOM은 Message Transmission Optimization Mechanism의 약자로 SOAP 메시지 통신 최적화 메커니즘이다. 웹 서비스를 통해 바이너리 데이터를 효과적으로 편리하게 전송할 수 있도록 하는 표준이다. JAXB Databinding 혹은 Aegis Databinding과 함께 사용될 수 있다. 서비스를 통해 바이너리 데이터를 효과적으로 편리하게 전송할 수 있도록 하는 표준으로 XML 문서의 일부가 아닌 첨부파일(Attachment) 형태로 생성되어 전송되며 Schema Type 혹은 자바 코드에 Annotation으로 설정한다. Schema Type에 xmime:expectedContentTypes="application/octet-stream" 을 추가 설정하면 base64Binary element를 위한 byte[] array 형태를 생성하지 않고 데이터를 스트림하는데 쓰이는 DataHandler를 생성한다.
MTOM의 특징을 살펴보면 다음과 같다.
Apache CXF 사용 시 디폴트로 MTOM 기능이 동작하지 않으므로, MTOM 사용을 위한 추가 설정이 필요하다.
XML 문서의 일부가 아닌 첨부파일(Attachment) 형태로 생성되어 전송한다.
바이너리 데이터를 나타내는 JavaBeans의 attribute를 javax.activation.DataHandler type으로 정의하고, @XmlMimeType("application/octet-stream") Annotation 설정을 추가해주도록 한다.
다음은 MTOM 기능을 Server와 Client 단에서 어떻게 사용해야 하는지에 대한 사용법이다. 예제는 JAX-WS Frontend, JAXB, MTOM을 함께 사용하는 것으로 구성되어 있다.
Server Configuration
Client Configuration
참고 - MTOM에 관련된 내용
Movie Service를 JAX-WS Frontend를 사용하여 Web Services로 노출시키는 예제로, MTOM을 테스트하기 위해서 추가 작업한 부분을 중심으로 살펴본다. 또한 MTOM을 사용하지 않고 기존에 XML 문서의 일부로 바이너리 데이터를 전송하는 경우와 MTOM을 이용하여 XML 문서 일부가 아닌 첨부파일 형태로 전송하는 경우에 대해서 바이너리 데이터의 전송과 수신이 올바르게 동작하는지 알아본다.
다음은 Movie Service의 인터페이스 메소드를 통해 클라이언트와 서버 간 주고받는 데이터인 Movie 클래스 정의에 대한 예제이다.
JavaBeans Class
다음은 Movie Service의 인터페이스 메소드를 통해 클라이언트와 서버 간 주고받는 데이터인 Movie 클래스를 작성한 Movie.java 의 일부이다.
public class Movie implements Serializable {
private String movieId = "";
private String title = "";
private String director = "";
<!-- MTOM을 사용하지 않고 기존에 XML 문서의 일부로 바이너리 데이터를 전송하는 경우 -->
private byte[] posterImgByteArray = null;
<!-- MTOM을 이용하여 XML 문서 일부가 아닌 첨부파일 형태로 바이너리 데이터를 전송하는 경우 -->
@XmlMimeType("application/octet-stream")
private DataHandler posterImgDataHandler = null;
public byte[] getPosterImgByteArray() {
return posterImgByteArray;
}
public void setPosterImgByteArray(byte[] posterImgByteArray) {
this.posterImgByteArray = posterImgByteArray;
}
public DataHandler getPosterImgMTOM() {
return posterImgDataHandler;
}
public void setPosterImgDataHandler(DataHandler posterImgDataHandler) {
this.posterImgDataHandler = posterImgDataHandler;
}
중략...
Test case
Spring Configuration XML Server 설정 이용(JAX-WS Frontend)
Spring Configuration XML 설정을 통해 MTOM Databinding 사용을 정의할 수 있다.
<!-- JAX-WS Frontend to expose MovieService with MTOM Databinding -->
<jaxws:endpoint id="movieService" implementor="org.anyframe.sample.cxf.jaxws.movie.impl.MovieServiceImpl" address="/ws">
<jaxws:properties>
<entry key="mtom-enabled" value="true"/>
</jaxws:properties>
</jaxws:endpoint>
중략...
Web Services에 접근하기 위한 클라이언트 작성 방식 중 Spring Configuration XML 설정 방식을 사용하면 간편하고 편리하게 사용할 수 있다.
다음은 Web Services로 노출된 Movie Service에 접근하는 예제이다.
Test Case
MTOM을 이용하여 XML 문서 일부가 아닌 첨부파일 형태로 바이너리 데이터를 전송하는 경우에 MTOM Databinding 기능이 올바로 동작하여 Movie의 poster image 바이너리 파일을 조회하고 수정이 되는지 테스트한다.
Spring Configuration XML Client 설정 이용(JAX-WS Frontend)
Spring Configuration XML 설정을 통해 MTOM Databinding 사용을 정의할 수 있다.
<!-- JAX-WS Frontend to access MovieService with MTOM Databinding -->
<jaxws:client id="movieService" serviceClass="org.anyframe.sample.cxf.jaxws.movie.MovieService"
address="http://localhost:8080/myproject/cxf-jaxws/ws">
<jaxws:properties>
<entry key="mtom-enabled" value="true"/>
</jaxws:properties>
</jaxws:client>
중략...
Web Services 성능 향상을 위해 W3C에서 제시한 스펙
2005년 1월 W3C(World Wide Web Consortium)는 다음과 같이 3가지의 Web Services 스펙을 제시하였다. 이들은 SOAP 1.2 메시지를 참조하거나 포함하는 바이너리 데이터를 효율적으로 패키징하거나 송신하는 방법을 제공한다.
XOP (XML-binary Optimized Packaging), MTOM (SOAP Message Transmission Optimization Mechanism), RRSHB (Resource Representation SOAP Header Block)
바이너리 데이터 전송
XML 문서의 일부가 바이너리 데이터인 경우, base64로 인코딩 되어야 하는데 이는 CPU 점유 시간을 증가시키고 Payload 사이즈를 증가시키는 문제가 있다. Web Services의 특징 중 하나는 전송되는 메시지가 XML로 구성되어 이기종간의 통신을 원활하게 한 것이다. 이는 XML이 일종의 텍스트 문서이므로 이기종 사이에서 이식성이 좋기 때문이다. 하지만 텍스트인 XML 문서에 바이너리 데이터를 추가하기 위해서는 base64 방식으로 인코딩해야 하며 이러한 인코딩 과정에서 바이너리 데이터의 용량은 50%이상 증가하고, 인코딩과 디코딩을 처리하기 위해서 발생하는 CPU의 부하도 5~10% 정도 추가된다는 통계가 있다. 즉, 바이너리 데이터를 전송하는데 있어 Web Services를 이용하게 되면 성능이 저하되는 문제가 발생하게 된다.
MTOM을 사용하면 XML 문서의 일부가 아닌 첨부파일(SOAP-Attachment) 형태로 생성되어 전송되어지므로 위와 같은 문제를 해소시킬 수 있다.
Schema Type에 xmime:expectedContentTypes="application/octet-stream" 을 추가 설정하면 base64Binary element를 위한 byte[] 형태를 생성하지 않고 데이터를 스트림하는데 쓰이는 DataHandler를 생성한다.
대용량 바이너리 데이터의 송신을 위한 표준적인 수단과 방법 제공
XOP와 MTOM을 이용하여 보다 효율적인 SOAP 메시지의 직렬화와 송신이 가능해진다.
XOP는 바이너리 데이터를 그대로 통신 패킷에 포함되도록 하는 표준적인 수단을 제공함으로써 작은 데이터 저장공간이나 좁은 데이터 통신 대역에서도 효율적으로 동작하게 하며 XML Information Set(InfoSet)을 이용하여 다양한 방법으로 XML 문서를 직렬화시킨다.
XOP를 구현하는 MTOM은 XOP가 제공하는 기능을 활용하여 SOAP 통신을 처리한다. SOAP 바인딩과 송신을 최적화하는 전송 메커니즘을 정의하여 필요한 통신 대역을 축소하고 대용량 바이너리 데이터의 인코딩과 디코딩에 필요한 시간을 단축한다. 또한 다양한 바이너리 데이터 송신 시 MIME 첨부 형식으로 SOAP 통신을 한다.
RRSHB(Resource Representation SOAP Header Block)는 SOAP 메시지 수신자가 원격에 위치한 자원의 로컬 캐시에 접근하게 한다. MTOM과 함께 사용됨으로써 메시지 수신자는 원격에 위치한 데이터에 대한 로컬 캐시가 이미 존재하고 있다면 요청 처리 속도는 현격하게 향상될 것이다. 참고로, 메시지 수신자는 URI에 의해 식별된 파일과 SOAP 통신으로 함께 보내진 데이터에 대한 로컬 캐시 중 하나를 선택하여 이용할 수 있다.
다운로드
다음에서 sample 코드를 포함하고 있는 anyframe-sample-cxf-rest.zip 파일을 다운받은 후, 압축을 해제한다.
Maven 기반 실행
Command 창에서 압축 해제 폴더로 이동한 후, mvn clean test 라는 명령어를 실행시켜 결과를 확인한다.
Eclipse 기반 실행
Eclipse에서 압축 해제 프로젝트를 import한 후, src/test/java 폴더의 모든 Test 코드 각각에 대해 마우스 오른쪽 버튼을 클릭하고, 컨텍스트 메뉴에서 Run As > JUnit Test를 클릭한다. 그리고 실행 결과를 확인한다.