스프링과 아파치 CXF를 이용해 POJO 웹 서비스를 디자인하고 구현하기, Part 1: CXF와 스프링을 사용하는 웹 서비스 만들기 소개
JAVA/JEE 2011. 7. 22. 08:53이번 글에서는 CXF와 스프링을 사용해 주문 처리 웹 서비스를 구축하고 개발한다. 이 웹 서비스는 고객에게 주문을 받아 처리하고, 유효한지 점검해 유일한 주문 ID를 반환한다. 이 글을 읽은 후에 웹 서비스를 구축하고, 개발하는 데 CXF의 개념과 특징을 적용할 수 있을 것이다.
이번 글에 나오는 예제를 실행하려면 컴퓨터에 다음 소프트웨어가 설치, 구성되어 있는지 확인해야 한다.
- 자바(Java) 5 이상
- 톰캣(Tomcat) 5 이상
- 앤트(Ant) 빌드 툴
- CXF 바이너리 배포판 2.1
위 배포판을 설치한 다음에는 다음 환경 변수를 구성하자.
- JAVA_HOME(자바)
- CATALINA_HOME(톰캣)
- ANT_HOME(앤트)
- CXF_HOME(CXF)
예제를 위해 CXF_HOME=C:\apache-cxf-2.1로 설정하고, PATH 환경 변수에 다음 내용을 추가하자.
- JAVA_HOME\bin
- CATALINA_HOME\bin
- ANT_HOME\bin
아파치 CXF(Apache CXF)는 웹 서비스를 편리하게 구축하고, 개발하는 데 필요한 견고한 기반을 제공하는 오픈 소스 프레임워크다. 이를 이용해 성능과 확장성이 높은 서비스를 만들 수 있다. 만든 서비스는 JBoss, IBM® WebSphere®나 BEA WebLogic 톰캣과 같은 좀 더 진보된 서버 인프라뿐만 아니라 톰캣과 스프링 기반 경량급 컨테이너에 배포할 수도 있다.
프레임워크는 다음과 같은 특징을 제공한다.
- 웹 서비스 표준 지원: CXF는 다음 웹 서비스 표준을 지원한다.
- JAX-WS(Java API for XML Web Services)
- SOAP
- WSDL(Web Services Description Language)
- MTOM(Message Transmission Optimization Mechanism)
- WS-Basic Profile
- WS-Addressing
- WS-Policy
- WS-ReliableMessaging
- WS-Security
- 프론트엔드 모델링(front-end modeling): CXF는 다양한 프론트엔드 API를 사용해 웹 서비스를 생성하도록 해주는 프론트엔드 모델링 개념을 제공한다. 이 API는 간단히 팩토리 빈(factory beans)을 사용하고, JAX-WAS 구현을 통해 웹 서비스를 생성하도록 해준다. 또한 동적 웹 서비스 클라이언트도 생성할 수 있게 해준다.
- 도구 지원: CXF는 자바 빈, 웹 서비스, WSDL 간에 변환을 해주는 다양한 도구를 제공한다. 메이븐(Maven)과 앤트(Ant)에 대한 통합 지원 기능을 제공하며, 스프링과의 자연스러운(seamlessly) 통합도 지원한다.
- RESTful 서비스 지원: CXF는 RESTful(Representational State Transfer) 개념을 지원하며, 자바 플랫폼에 대한 JAX-RS 구현을 지원한다(이번 연재의 Part 2에서 RESTful 서비스에 대한 더 많은 정보를 제공하겠다).
- 다양한 전송과 바인딩(binding) 지원: CXF는 XML에서 CSV(Comma Separated Value)에 이르기까지 여러 종류의 전송을 지원한다. 또한 JAXB(Java Architecture for XML Binding)와 SOAP과 HTTP 프로토콜 바인딩 외에 AEGIS 데이터 바인딩도 지원한다.
- XML 이외의 바인딩 지원: CXF는 JSON(JavaScript Object Notation)과 CORBA(Common Object Request Broker Architecture) 같은 XML 이외의 바인딩을 지원한다. JBI(Java Business Integration) 아키텍처와 SCA(Service Component Architecture) 또한 지원한다.
JAX-WS 프론트엔드를 사용해 주문 처리 웹 서비스를 만들어 이를 스프링 빈(bean)으로 등록하는 방법을 확실하게 살펴보자. 자바 클래스를 먼저 개발하고, 이 클래스에 웹 서비스를 의미하는 애노테이션을 붙이는 코드 우선 접근법을 사용한다. 이를 위해서는 대체로 다음 단계를 따르면 된다.
- 서비스 종단 인터페이스(SEI: Service Endpoint Interface)를 만들고 웹 서비스로 노출되는 메서드를 정의한다.
- 구현 클래스를 만들고 웹 서비스 애노테이션을 붙인다.
- beans.xml을 만들고 JAX-WS 프론트엔드를 사용해 스프링 빈으로 서비스 클래스를 정의한다.
- 스프링과 CXF를 통합하는 web.xml을 만든다.
먼저 주문 처리 웹 서비스 SEI를 만들어보자.
OrderProcess
라는 이름으로 SEI를 만들자. 이 SEI는 order 빈을 받아 문자열을 반환하는 processOrder
메서드를 갖게 된다.processOrder
메서드의 목적은 고객에게 주문을 받아 유일한 주문 ID를 반환하도록 처리하는 것이다.
Listing 1. OrderProcess SEI
package demo.order; import javax.jws.WebService; @WebService public interface OrderProcess { String processOrder(Order order); } |
Listing 1에서 볼 수 있는 것처럼, OrderProcess
SEI는 웹 서비스 애노테이션이 붙은 단순한 표준 자바 인터페이스다. @WebService
애노테이션은 간단하게 인터페이스를 웹 서비스 인터페이스로 만들어준다. OrderProcess
SEI는 하나의 processOrder
메서드를 갖는다. 이 메서드는 매개변수로 Order
를 받아 문자열로 주문 ID를 반환한다.
Listing 2. OrderProcess 서비스 구현
package demo.order; import javax.jws.WebService; @WebService(endpointInterface = "demo.order.OrderProcess") public class OrderProcessImpl implements OrderProcess { public String processOrder(Order order) { return order.validate(); } } |
이전 절에서 SEI 구현을 작성하면서 구현 클래스인 OrderProcessImpl
이 웹 서비스가 되도록 애노테이션을 더해 붙였고, 이전 단계에서 만들었던 SEI의 완전한 클래스 이름(fully qualified name)을 값으로 갖는 endpointInterface
속성을 제공했다. 이 값은 이 클래스가OrderProcess
SEI를 구현했다는 것을 의미한다. SEI를 구현했으므로 주문 ID를 반환하는 processOrder
메서드 구현을 제공해야 한다.
우리는 SEI와 SEI의 구현체를 만들었다. 이제 CXF를 사용해 JAX-WS 프론트엔드를 사용하는 실제 서비스 컴포넌트를 만들 수 있다.
Listing 3. beans.xml 환경 구성 파일
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jaxws="http://cxf.apache.org/jaxws" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd"> <import resource="classpath:META-INF/cxf/cxf.xml" /> <import resource="classpath:META-INF/cxf/cxf-extension-soap.xml" /> <import resource="classpath:META-INF/cxf/cxf-servlet.xml" /> <jaxws:endpoint id="orderProcess" implementor="demo.order.OrderProcessImpl" address="/OrderProcess" /> </beans> |
CXF 환경 구성 파일은 실제로 빈 정의를 포함하는 스프링 환경 구성 파일이다. JAX-WS 프론트엔드 환경 구성을 사용해 OrderProcess
웹 서비스에 대한 빈 정의를 만들자. beans.xml에 나오는 <jaxws:endpoint>
태그는 OrderProcess
웹 서비스를 JAX-WS 엔드포인트로 지정해준다. 이 웹 서비스를 공개(publish)하는 데 CXF가 내부적으로 JAX-WS를 사용하는 건 매우 효과적인 방법이다.<jaxws:endpoint>
에 구현 클래스 이름인 OrderProcessImpl
과 주소를 제공해야 한다. 여기서 제공하는 주소는 웹 컨텍스트(web context)와 관련 있다.
Listing 4. web.xml 환경 구성 파일
<web-app> <context-param> <param-name>contextConfigLocation</param-name> <param-value>WEB-INF/beans.xml</param-value> </context-param> <listener> <listener-class> org.springframework.web.context.ContextLoaderListener </listener-class> </listener> <servlet> <servlet-name>CXFServlet</servlet-name> <display-name>CXF Servlet</display-name> <servlet-class> org.apache.cxf.transport.servlet.CXFServlet </servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>CXFServlet</servlet-name> <url-pattern>/*</url-pattern> </servlet-mapping> </web-app> |
마지막으로 다음 작업을 해야 한다.
- CXF 환경 구성 파일을 불러오는 web.xml 파일 만들기
- 환경 구성 파일을 불러오는 스프링 컨텍스트 로더(context loader) 사용하기
- 클라이언트 프로그램에서 오는 모든 요청을 제어하는 CXFServlet 등록하기
이제 서버측 컴포넌트가 필요로 하는 개발은 대충 마무리됐다. 이제 OrderProcess
서비스에 요청을 보내는 클라이언트 컴포넌트를 개발할 수 있다.
Listing 5에서 봤던 것처럼, 서버 종단 지점을 쉽게 만들 수 있는 것처럼 클라이언트 빈을 만드는 것도 매우 쉽다. JaxWsProxyFactory
는OrderProcess
웹 서비스에 대한 클라이언트 빈을 만드는데 사용된다. 팩토리 빈은 서비스 클래스(OrderProcess
)와 서비스의 URL을 요구한다. 그러므로 클라이언트 빈 스텁(stub)이 되는 OrderProcess
는 팩토리 빈 참조를 사용해 생성된다.
Listing 5. client-bean.xml 클라이언트 웹 환경 구성 파일
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jaxws="http://cxf.apache.org/jaxws" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd http://cxf.apache.org/jaxws http://cxf.apache.org/schema/jaxws.xsd"> <bean id="client" class="demo.order.OrderProcess" factory-bean="clientFactory" factory-method="create"/> <bean id="clientFactory" class="org.apache.cxf.jaxws.JaxWsProxyFactoryBean"> <property name="serviceClass" value="demo.order.OrderProcess"/> <property name="address" value="http://localhost:8080/orderapp/OrderProcess"/> </bean> </beans> |
스프링 컨텍스트(context)를 사용해 정의한 클라이언트 빈을 받아온 다음, processOrder
메서드를 호출하는 자바 메인 프로그램을 만들어보자.
Listing 6. 클라이언트 코드
public final class Client { public Client() { } public static void main(String args[]) throws Exception { ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(new String[] {"demo/order/client/client-beans.xml"}); OrderProcess client = (OrderProcess)context.getBean("client"); Order order = new Order(); String orderID = client.processOrder(order); System.out.println("Order ID: " + orderID); System.exit(0); } } |
프로그램을 실행하기 전에, 루트 C:\ 폴더 밑에 그림 1에서 보는 것처럼 디렉터리 구조를 만들고, 이번 글의 앞에서 다뤘던 컴포넌트를 넣어두자.
- 자바 코드는 패키지 폴더에 포함
- beans.xml과 web.xml은 web\web-inf 폴더에 포함
- client-beans.xml은 demo\order\client 폴더에 포함
그림 1. 코드 디렉터리 구조
![코드 디렉터리 구조](http://www.ibm.com/developerworks/kr/library/ws-pojo-springcxf/folder_structure.jpg)
OrderProcess
웹 서비스와 클라이언트를 구축하고, 배포하고, 실행하는 데 앤트(Ant) 도구를 사용한다. 코드는 톰캣 서버에 배포된다. c:\orderapp 폴더 아래 ant deploy
커맨드를 사용해 코드를 배포하자.
애플리케이션 폴더(c:\orderapp)는 앤트 빌드 파일을 갖고 있다. 위 명령을 실행한 후에 orderapp
코드는 orderapp.war 파일로 톰캣 서버 환경에 배포된다. 이제 CATALINA_HOME\bin 폴더에서 catalina start
명령을 입력해 톰캣 웹 서버를 시작하자.
톰캣의 webapps 폴더에 orderapp 폴더가 생성된다. 서버가 시작된 후에 ant client
명령을 입력해 애플리케이션을 시작하자. 주문 ID가 화면에 출력된다(그림 2).
그림 2. 프로그램이 출력한 화면
![프로그램이 출력한 화면](http://www.ibm.com/developerworks/kr/library/ws-pojo-springcxf/code_output.jpg)
이번 글에서는 간단한 CXF 프레임워크의 특징과 코드를 작성해야 하는 별다른 노력 없이도 웹 서비스를 만들 수 있는 방법을 설명했다. 빈 컨텍스트 파일을 사용하는 CXF와 스프링 통합에 대해서도 배웠다. 또한 프레임워크가 실제로 웹 서비스 인프라스트럭처 컴포넌트를 만드는 의미를 추상화한 방법과, 오로지 웹 서비스를 생성하는 데만 집중할 수 있도록 어떤 전문적이면서 간편한 셸 API를 제공하는지를 알아 봤다
이제 CXF를 사용하는 웹 서비스 생성의 기본을 살펴봤으니, Part 2에서는 CXF와 스프링을 사용해 RESTful 서비스를 POJO로 노출하는 방법을 살펴볼 생각이다.
'JAVA > JEE' 카테고리의 다른 글
[펌] Web Services with Spring 2.5 and Apache CXF 2.0 (0) | 2008.12.01 |
---|---|
Sitemesh 에서 Struts2 액션 사용하기 (0) | 2008.11.26 |
Invoking Web Services Without Using the WSDL File (0) | 2008.08.05 |
weblogic 6.1 웹서비스 문제.(xmlns 가 1999 로 된다 ㅠㅠ) (0) | 2008.07.23 |
[java mail] javax.mail.internet.ParseException 발생... (0) | 2007.07.06 |