내용 목차
본 장에서는 JAX-WS 웹 서비스를 Java 클래스와 WSDL 파일로부터 생성하고 deploy하여 패키징하는 방법에 대해 설명한다. 또한 JAX-WS 웹 서비스를 JEUS 7에서 동작시키는 방법에 대해 설명한다.
기본적으로 웹 서비스를 Java 클래스로부터 구현하든 WSDL로부터 구현하든 배치하는 과정은 거의 동일하다. JAX-WS 웹 서비스는 POJO 방식의 웹 서비스 구현을 지향하므로 이러한 DD의 개수는 JAX-RPC 웹 서비스에 비해 대폭적으로 줄어든다.
JEUS 5 JAX-RPC 방식 웹 서비스의 구현에서 일반적으로 사용되었던 DD 없이 프로그래밍할 수 있고, 이것은 웹 서비스 개발자가 매우 쉽고 빠르고 편리하게 웹 서비스를 개발하도록 도와준다(Description-free programming).
Java 클래스로부터 구현한 웹 서비스를 WAR 파일로 구성하는 것은 서비스 Endpoint 구현 클래스와 그 밖의 Java 클래스들(Portable Artifact들)을 여러 DD 파일과 함께 WAR 포맷으로 묶는 것을 의미한다.
다음은 이전 장에서 Java 클래스로부터 구현한 웹 서비스를 WAR 형태로 구성하는 모습을 디렉터리별로 나타낸 것이다.
META-INF/MANIFEST.MF WEB-INF/classes/AddNumbersImplService_schema1.xsd WEB-INF/classes/AddNumbersImplService.wsdl WEB-INF/classes/fromjava/server/AddNumbersImpl.class WEB-INF/classes/fromjava/server/jaxws/AddNumbers.class WEB-INF/classes/fromjava/server/jaxws/AddNumbersResponse.class
위의 WAR 파일은 서비스 Endpoint 구현 클래스와 Portable Artifact 클래스들과 함께 유일한 DD인 web.xml로 구성된다. 사실 JAX-WS 웹 서비스의 구현에는 web.xml 파일조차 필요가 없으나 여기서는 원하는 Endpoint 주소를 얻기 위해 web.xml을 사용하였다. Endpoint 주소에 대한 보다 자세한 사항은 “4.5. Endpoint 주소 결정 방식”을 참고한다.
이와 같이 생성된 웹 서비스 WAR 파일은 JEUS 7에서 제공하는 방식으로 deploy되어 접근할 수 있다. 생성된 WAR 파일을 JEUS 7에 deploy하기 위해 콘솔에서 다음의 명령을 실행한다.
$ ant build deploy
정상적으로 deploy되면 실제 이 서비스에 접근할 수 있는 실제 주소는 다음과 같다.
http://host:port/AddNumbers/AddNumbersImplService
Java 클래스로부터 구현한 웹 서비스를 JAR 파일로 구성하는 것은 서비스 Endpoint 구현 클래스와 그 밖의 Java 클래스(Portable Artifact)들을 여러 DD 파일과 함께 JAR 포맷으로 묶는 것을 의미한다.
다음은 이전 장에서 EJB Stateless Session Bean으로부터 구현한 웹 서비스를 JAR 형태로 구성하는 모습을 디렉터리별로 나타낸 것이다.
META-INF/MANIFEST.MF fromejb/server/AddNumbersImpl.class fromejb/server/jaxws/AddNumbers.class fromejb/server/jaxws/AddNumbersResponse.class
위의 JAR 파일은 서비스 Endpoint 구현 클래스와 Portable Artifact 클래스들로 이루어진다. Endpoint 주소에 대한 보다 자세한 사항은 “4.5. Endpoint 주소 결정 방식”을 참고한다.
이와 같이 생성된 웹 서비스 JAR 파일은 JEUS 7에서 제공하는 방식으로 deploy되어 접근할 수 있다. 생성된 JAR 파일을 JEUS 7에 deploy하기 위해 콘솔에서 다음과 같은 명령을 실행한다.
$ ant build deploy
정상적으로 deploy되면 이 서비스에 접근할 수 있는 실제 주소는 다음과 같다.
http://host:port/AddNumbersImplService/AddNumbersImpl
WSDL로부터 구현한 웹 서비스를 WAR 파일을 구성하는 것은 서비스 Endpoint 인터페이스와 그것을 구현한 서비스 Endpoint 클래스 그리고 그 밖의 Portable Artifact들을 여러 DD 파일과 함께 WAR 포맷으로 묶는 것을 의미한다.
다음은 이전 장에서 WSDL로부터 구현한 웹 서비스를 WAR 형태로 구성하는 모습을 디렉터리별로 나타낸 것이다.
META-INF/MANIFEST.MF WEB-INF/wsdl/AddNumbers.wsdl WEB-INF/classes/fromjava/server/AddNumbers.class WEB-INF/classes/fromjava/server/AddNumbersImpl.class WEB-INF/classes/fromjava/server/AddNumbersPortType.class WEB-INF/classes/fromjava/server/AddNumbersResponse.class WEB-INF/classes/fromjava/server/AddNumbersService.class WEB-INF/classes/fromjava/server/ObjectFactory.class WEB-INF/classes/fromjava/server/package-info.class
위의 WAR 파일은 서비스 Endpoint 인터페이스인 AddNumbersPortType과 이를 구현하는 AddNumbersImpl 그리고 여러 가지 Portable Artifact 클래스들과 함께 유일한 DD인 web.xml 파일들로 구성된다. 사실 JAX-WS 웹 서비스의 구현에는 web.xml 파일조차 필요가 없으나 여기서는 원하는 Endpoint 주소를 얻기 위해 web.xml을 사용하였다. Endpoint 주소에 대한 보다 자세한 사항은 “4.5. Endpoint 주소 결정 방식”을 참고한다.
이와 같이 생성된 웹 서비스 WAR 파일은 JEUS 7에서 제공하는 방식으로 deploy되어 웹 서비스로 공개될 수 있다. 생성된 WAR 파일을 JEUS 7에 deploy하기 위해 콘솔에서 다음과 같은 명령을 실행한다.
$ ant build deploy
정상적으로 deploy되면 실제 이 서비스에 접근할 수 있는 실제 주소는 다음과 같다.
http://host:port/AddNumbers/AddNumbersService
JAX-WS 웹 서비스는 web.xml을 비롯한 webservices.xml 등의 기존 JEUS 5의 JAX-RPC 웹 서비스에서 필요했던 DD 파일이 없어도(Descriptor-free) JEUS 7에 deploy가 가능하다.
본 절에서는 서블릿 기반의 웹 서비스와 EJB 기반의 웹 서비스에 대해 이러한 JAX-WS가 JEUS 7에 deploy될 때 실제로 이 서비스에 접근할 수 있는 각각의 주소 결정 방식을 설명한다.
서블릿 Endpoint의 경우 URL 결정 우선순위는 다음과 같다.
web.xml 파일의 <url-pattern>을 사용하는 경우
web.xml 파일의 <url-pattern>을 사용하는 경우 입력된 값이 실제 이 웹 서비스에 접근할 수 있는 URL 주소이다. 이는 @EndpointDescription Endpoint 주소의 기본값을 overwrite한다.
다음은 web.xml 파일과 AddNumbersImpl과 같은 Endpoint 클래스의 예이다.
[예 4.1] web.xml 파일의 <url-pattern> 사용 (1) : << web.xml >>
<web-app>
<display-name>fromwsdl</display-name>
<description>fromwsdl</description>
<servlet>
<servlet-name>fromwsdl</servlet-name>
<display-name>fromwsdl</display-name>
<servlet-class>fromwsdl.server.AddNumbersImpl</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>fromwsdl</servlet-name>
<url-pattern>/addnumbers</url-pattern>
</servlet-mapping>
</web-app>
[예 4.2] Endpoint 클래스 : << AddNumbersImpl.java >>
@WebService(serviceName="AddNumbers") @EndpointDescription(endpointUrl="MyService") public class AddNumbersImpl { public int addNumbers(int number1, int number2) { return number1 + number2; } }
이 웹 서비스에 접근할 수 있는 실제 URL 주소는 다음과 같다.
http://server:port/context/addnumbers
@EndpointDescription Annotation을 사용하는 경우
@EndpointDescription라는 Annotation에 endpointUrl이라는 변수값이 정해져 있을 경우에는 이 값이 실제 이 웹 서비스에 접근할 수 있는 URL 주소이다. 이는 @WebService Annotation의 serviceName Endpoint 주소값을 overwrite한다.
다음은 Endpoint 클래스의 예이다.
[예 4.3] @EndpointDescription Annotation 사용 : << AddNumbersImpl.java >>
@WebService(serviceName="AddNumbers") @EndpointDescription(endpointUrl="MyService") public class AddNumbersImpl { public int addNumbers(int number1, int number2) { return number1 + number2; } }
이 웹 서비스에 접근할 수 있는 실제 URL 주소는 다음과 같다.
http://server:port/context/MyService
@WebService Annotation의 serviceName 속성을 사용하는 경우
@WebService라는 Annotation에 serviceName이라는 변수값이 정해져 있을 경우에는 이 값이 실제 이 웹 서비스에 접근할 수 있는 URL 주소이다. 이는 Endpoint 주소의 기본값을 overwrite한다.
다음은 Endpoint 클래스의 예이다.
[예 4.4] @WebService Annotation의 serviceName 속성 사용 : << AddNumbersImpl.java >>
@WebService(serviceName="AddNumbers") public class AddNumbersImpl { public int addNumbers(int number1, int number2) { return number1 + number2; } }
이 웹 서비스에 접근할 수 있는 실제 URL 주소는 다음과 같다.
http://server:port/context/AddNumbers
Endpoint 주소의 기본값 + "Service" 사용
@WebService라는 Annotation 이외에 아무런 설정이 없다면 기본값으로 'Endpoint 클래스 이름 + Service'가 이 웹 서비스의 Endpoint 주소의 기본값이다.
다음은 Endpoint 클래스의 예이다.
[예 4.5] Endpoint 클래스 : << AddNumbersImpl.java >>
@WebService public class AddNumbersImpl { public int addNumbers(int number1, int number2) { return number1 + number2; } }
이 웹 서비스에 접근할 수 있는 실제 URL 주소는 다음과 같다.
http://server:port/context/AddNumbersImplService
EJB Endpoint의 경우 Endpoint URL 결정 우선순위는 서블릿 Endpoint의 경우와 같고, 컨텍스트의 결정 방식만 다르다.
컨텍스트의 결정 우선순위는 다음과 같다.
@EndpointDescription Annotation을 사용하는 경우
Endpoint
@EndpointDescription라는 Annotation에 endpointUrl이라는 변수값이 정해져 있을 경우에는 이 값이 실제 이 웹 서비스에 접근할 수 있는 URL 주소이다. 이는 @WebService Annotation의 name Endpoint 주소값을 overwrite한다.
다음은 Endpoint 클래스의 예이다.
[예 4.6] @EndpointDescription Annotation 사용 (1) : << AddNumbersImpl.java >>
@WebService(name="AddNumbersService") @EndpointDescription(endpointUrl="MyService") @Stateless public class AddNumbersImpl { public AddNumbersImpl() { } public int addNumbers(int number1, int number2) { return number1 + number2; } }
이 웹 서비스에 접근할 수 있는 실제 URL 주소는 다음과 같다.
http://server:port/context/MyService
Context
@jeus.webservices.annotation.EndpointDescription Annotation에 contextPath 속성을 사용하는 경우 컨텍스트 기본값을 overwrite한다.
다음은 Endpoint 클래스에 대한 예이다.
[예 4.7] @EndpointDescription Annotation 사용 (2) : << AddNumbersImpl.java >>
@WebService(name="Hello", serviceName="AddNumbersService") @jeus.webservices.annotation.EndpointDescription(contextPath="EJBService", endpointUrl="MyEndpoint") @Stateless public class AddNumbersImpl { public AddNumbersImpl() { } public int addNumbers(int number1, int number2) { return number1 + number2; } }
이 웹 서비스에 접근할 수 있는 실제 URL 주소는 다음과 같다.
http://server:port/EJBService/MyEndpoint
@WebService Annotation의 serviceName 속성을 사용하는 경우
Endpoint
@WebService라는 Annotation에 name이라는 변수값이 정해져 있을 경우에는 이 값이 실제 이 웹 서비스에 접근할 수 있는 URL 주소이다. 이는 Endpoint 주소의 기본값을 overwrite한다.
다음은 Endpoint 클래스의 예이다.
[예 4.8] @WebService Annotation의 serviceName 속성 사용 (1) : << AddNumbersImpl.java >>
@WebService(name="AddNumbersService") @Stateless public class AddNumbersImpl { public AddNumbersImpl() { } public int addNumbers(int number1, int number2) { return number1 + number2; } }
이 웹 서비스에 접근할 수 있는 실제 URL 주소는 다음과 같다.
http://server:port/context/AddNumbersService
Context
@WebService Annotation에 serviceName 속성을 사용하는 경우 컨텍스트 기본값을 overwrite한다.
다음은 Endpoint 클래스의 예이다.
[예 4.9] @WebService Annotation의 serviceName 속성 사용 (2) : << AddNumbersImpl.java >>
@WebService(name="Hello", serviceName="AddNumbersService") @Stateless public class AddNumbersImpl { public AddNumbersImpl() { } public int addNumbers(int number1, int number2) { return number1 + number2; } }
이 웹 서비스에 접근할 수 있는 실제 URL 주소는 다음과 같다.
http://server:port/AddNumbersService/Hello
컨텍스트의 기본값
Endpoint
@WebService라는 Annotation 이외에 아무런 설정이 없다면 기본값으로 Endpoint 클래스 이름이 이 웹 서비스의 Endpoint 주소의 기본값이다.
다음은 Endpoint 클래스의 예이다.
[예 4.10] 컨텍스트의 기본값 사용 Endpoint 클래스 : << AddNumbersImpl.java >>
@WebService @Stateless public class AddNumbersImpl { public AddNumbersImpl() { } public int addNumbers(int number1, int number2) { return number1 + number2; } }
이 웹 서비스에 접근할 수 있는 실제 URL 주소는 다음과 같다.
http://server:port/context/AddNumbersImpl
Context
컨텍스트(context) 기본값은 그 웹 서비스의 WSDL 문서의 ServiceName이다. 또한, 이 ServiceName은 Endpoint 클래스 이름에 Service를 붙힌 값이 기본값으로 설정된다.
따라서 위의 Endpoint 클래스의 웹 서비스에 대해 다음과 같은 주소로 접근할 수 있다.
http://server:port/AddNumbersImplService/AddNumbersImpl