2008년 3월 31일 월요일

SAKAI 설치중...

Moodle과 LAMS를 설치후 Scorm콘텐츠와 LD콘텐츠를 돌려 보았고~

이제..

SAKAI에 연동하는 과정이 남았는데..

이루어질까..

설치까지..

오래걸리고 어렵군..

Source로 설치하니까 생소하다..쳇.!

지금까지 deploy시간이...3시간 가까이 되는데...훔...

오늘 꼭 성공해봐야지..

ㅠㅠ

2008년 3월 5일 수요일

SSL로 JAX-WS 기반 웹 서비스 이용하기

Java EE 5에서는 JAX-WS에 기반을 둔 웹 서비스를 EJB 엔드포인트나 서블릿 엔드포인트로 구현할 수 있다. EJB 엔드포인트로 구현된 JAX-WS 기반 웹 서비스의 예는 테크 팁 EJB 3.0을 이용하여 웹 서비스 개발하기에서 찾아볼 수 있으며, 서블릿 엔드포인트로 구현된 JAX-WS 기반 웹 서비스에 대한 예는 테크 팁 JAX-WS를 이용하여 웹 서비스 개발하기에 나와 있다.
웹 서비스 구현 방식과 관계없이, 웹 서비스를 이용하는 경우를 포함한 대부분의 엔터프라이즈 애플리케이션은 반드시 안전한 환경에서 실행되어야 한다. TSL(Transport Layer Security)/SSL(Secure Sockets Layer)은 인증, 메시지 무결성 및 비밀 유지를 위해 사용할 수 있는 point-to-point 보안 전송 메커니즘으로, 이 TLS/SSL (본 팁에서는 간단히 ‘SSL’로 표기)은 대부분의 엔터프라이즈 애플리케이션 환경의 보안 요구사항을 충족할 뿐 아니라 실제로 널리 채택되어 사용되고 있다.
본 테크 팁은 SSL로 실행되는 JAX-WS 기반 웹 서비스를 구성하는 방법과 애플리케이션 클라이언트에서의 웹 서비스 액세스 방법을 다룬다. 첨부된 예제 패키지에서는 SSL을 이용하여 JAX-WS 웹 서비스에 액세스하는 자바 클라이언트를 예시하고 있다. 이와 더불어 EJB 및 서블릿 엔드포인트로 구현되는 웹 서비스의 예제가 제공되며, 예제는 GlassFish라고 불리는 Java EE 5의 오픈 소스 레퍼런스 구현을 사용한다. GlassFish는 GlassFish 커뮤니티 다운로드 페이지에서 다운로드할 수 있다.
웹 서비스 엔드포인트를 위한 클래스 작성
먼저 웹 서비스를 위한 자바 클래스를 작성해 보기로 하자. SSL은 웹 서비스 엔드포인트의 자바 코드에 영향을 미치지 않으며, SSL을 이용하거나 이용하지 않는 웹 서비스 모두에 동일한 코드가 적용된다.
Java EE 5에서는 주석을 이용하여 손쉽게 JAX-WS 웹 서비스를 구성할 수 있다. 다음은 EJB 엔드포인트로 구현된 웹 서비스의 예제이다.
   package ejbws;

   import javax.annotation.Resource;
   import javax.ejb.Stateless;
   import javax.jws.WebService;
   import javax.xml.ws.WebServiceContext;

   @Stateless
   @WebService
   public class HelloEjb {
       @Resource WebServiceContext wsContext;

       public String hello(String msg) {
           return "Ejb WS: " + wsContext.getUserPrincipal() 
           + ": " + msg;
       }
   }
The @Stateless 주석은 클래스를 stateless 세션 빈으로 마크하고 @WebService 주석은 클래스를 웹 서비스로 마크한다. @Resource 주석은 클래스가 지니는 리소스 의존성—본질적으로, 클래스에 어떤 리소스가 필요한가—을 선언하는 데 사용되며, 이어서 이 리소스들은 엔드포인트 구현에 삽입된다. 이 예제에서 주석은 WebServiceContext에 대한 리소스 의존성을 식별한다. 한편 클래스는 관련 보안 정보와 같은 요청에 관한 컨텍스트 정보를 얻기 위해 WebServiceContext를 필요로 한다.
다음은 동일한 웹 서비스가 서블릿 엔드포인트로 구현된 예제이다.
   package servletws;

   import javax.annotation.Resource;
   import javax.jws.WebService;
   import javax.xml.ws.WebServiceContext;

   @WebService
   public class HelloServlet {
       @Resource WebServiceContext wsContext;

       public String hello(String msg) {
           return "Servlet WS: " + wsContext.getUserPrincipal() 
           + ": " + msg;
       }
   }
배포 서술자에 보안 정보 명시
EJB 엔드포인트로 구현된 웹 서비스에서 SSL을 이용하려면 벤더별 배포 서술자(본 팁의 경우에는 sun-ejb-jar.xml)에 보안 정보를 명시해야 한다. 단, 서블릿으로 구현된 웹 서비스의 경우에는 web.xml 서술자에 보안 정보를 명시하도록 한다.
SSL을 통한 보안 통신에 있어서 중요 사항 중 한 가지는 서버 인증, 즉 서버의 아이덴티티를 클라이언트에 확인시키는 일이다. 또 중요한 측면은 바로 클라이언트 인증인데, 이 경우에는 서버가 클라이언트의 아이덴티티를 확인하게 된다. SSL에서는 서버 인증이나 서버와 클라이언트가 결합된 인증이 허용된다(클라이언트 인증만은 허용되지 않음). 본 팁에서는 서버와 클라이언트가 결합된 인증에 대해 ‘상호 인증’이라는 용어를 사용하기로 한다. (단, 타 문서에서는 상호 인증이 다른 의미로 사용될 수 있다는 점에 유의할 것. 예를 들어, 어떤 문서에서는 클라이언트 인증이 상호 인증과 동의어로 사용되기도 한다.)
SSL 서버 인증을 인에이블하려면 <transport-guarantee> 엘리먼트를 CONFIDENTIAL로 설정해야 하는데, EJB 엔드포인트로 구현된 웹 서비스의 경우에는 sun-ejb-jar.xml 배포 서술자 내의 엘리먼트를 설정한다. 또 서블릿으로 구현된 웹 서비스의 경우에는 web.xmll 배포 서술자 내의 엘리먼트를 설정한다. 예를 들어, HelloEjb 웹 서비스에서는 sun-ejb-jar.xml 배포 서술자 내의 <transport-guarantee> 엘리먼트가 다음과 같은 형태를 띠어야 한다.
   <ejb>
     <ejb-name>HelloEjb</ejb-name>
     <webservice-endpoint>
       <port-component-name>HelloEjb</port-component-name>
       <transport-guarantee>CONFIDENTIAL</transport-guarantee>
     </webservice-endpoint>
   </ejb>
HelloServletService 서비스의 경우에는 web.xml 배포 서술자 내의 <transport-guarantee> 엘리먼트는 다음과 같은 형태를 띠어야 한다.
   <security-constraint>
     <web-resource-collection>
       <web-resource-name>Secure Area</web-resource-name>
       <url-pattern>/HelloServletService/HelloServlet
       </url-pattern>
       <http-method>POST</http-method>
     </web-resource-collection>
     <auth-constraint>
       <role-name>EMPLOYEE</role-name>
     </auth-constraint>
     <user-data-constraint>
       <transport-guarantee>CONFIDENTIAL</transport-guarantee>
     </user-data-constraint>
   </security-constraint>
web.xmlPOST<http-method> 엘리먼트 값에 특히 유의할 것. JSR-109 "Implementing Enterprise Web Services"에는 서비스 엔드포인트 인증이 반드시 POSThttp-method 엘리먼트 값을 이용해서 정의되어야 한다고 명시되어 있다.
GlassFish에서 WSDL 파일은 SSL나 SSL 상호 인증을 통해 엔드포인트의 SSL에 의해 보호된다. SSL 상호 인증의 경우에는 <login-config> 엘리먼트의 <auth-method> 서브엘리먼트를 CLIENT-CERT로 설정해야 하고, 아울러 <transport-guarantee> 엘리먼트를 CONFIDENTIAL로 설정해야 한다. 예를 들어 sun-ejb-jar.xml의 경우는 다음과 같다.
   <ejb>
     <ejb-name>HelloEjb</ejb-name>
     <webservice-endpoint>
       <port-component-name>HelloEjb</port-component-name>
       <login-config>
         <auth-method>CLIENT-CERT</auth-method>
         <realm>certificate</realm>
       </login-config>
       <transport-guarantee>CONFIDENTIAL</transport-guarantee>
     </webservice-endpoint>
  </ejb>
   <security-constraint>
     <web-resource-collection>
       <web-resource-name>Secure Area</web-resource-name>
       <url-pattern>/HelloServletService/HelloServlet
       </url-pattern>
       <http-method>POST</http-method>
     </web-resource-collection>
     <auth-constraint>
       </role-name>EMPLOYEE</role-name>
     </auth-constraint>
     <user-data-constraint>
       <transport-guarantee>CONFIDENTIAL</transport-guarantee>
     </user-data-constraint>
   </security-constraint>
   <login-config>
     <auth-method>CLIENT-CERT</auth-method>
     <realm-name>certificate</realm-name>
   </login-config>
클라이언트 프로그램에는 배포 서술자가 필요하지 않다.
웹 서비스 애플리케이션의 패키징 및 배포
SSL을 이용하는 웹 서비스 애플리케이션의 패키징 및 배포는 SSL을 이용하지 않는 웹 서비스 애플리케이션의 경우와 동일하다. 하지만, 웹 서비스가 엔터프라이즈 아카이브(즉, .ear 파일) 내의 서블릿 엔드포인트로 구현되는 경우에는 웹 애플리케이션에 대해 context-root를 명시하기 위한 application.xml 파일을 포함시켜야 한다는 점을 유념해야 한다.
클라이언트 작성
웹 서비스를 배포한 후에는 클라이언트 프로그램으로 액세스할 수 있다. SSL을 이용하는 웹 서비스 애플리케이션을 위한 클라이언트 프로그램은 SSL을 이용하지 않는 경우와 사실상 동일하다. 주된 차이점은 인터넷 프로토콜로 HTTP를 사용하는 대신 HTTPS를 사용해야 한다는 사실이다. 클라이언트에서 @WebServiceRef 주석을 이용하여 웹 서비스에 대한 레퍼런스를 선언한다. 이 때, @WebServiceRef 내의 wsdlLocation 파라미터 값은 레퍼런스된 서비스를 위한 WSDL 파일의 위치를 가리키는 URL이다. 따라서 SSL을 이용하는 웹 서비스 클라이언트의 경우, @WebServiceRef 주석 내의 wsdlLocation 파라미터는 HTTPS URL을 명시해야 한다. 예:
   @WebServiceRef(wsdlLocation=
       "https://serverName:8181/HelloEjbService/HelloEjb?WSDL")
   private static HelloEjbService helloEjbService;
이어서 웹 서비스에 대한 포트에 액세스하여 웹 서비스를 호출할 수 있다.
   HelloEjb helloEjbPort = helloEjbService.getHelloEjbPort();
   helloEjbPort.hello("Hello World");
클라이언트 측 artifacts는 HTTPS를 통해 WSDL 파일에 액세스함으로써 생성되는데, 이를 위해서는 환경 변수 VMARGS 내에 서버와 해당 비밀번호를 위한 truststore 파일의 위치를 명시해야 한다. SSL에서는 인증서를 이용하여 서버를 인증하거나 서버 및 클라이언트 양자의 상호 인증을 수행할 수 있다. 서버의 truststore 파일에는 서버에 대한 신뢰할 수 있는 인증서와 키가 포함되어 있다.
서버의 truststore 파일과 그 비밀번호를 명시하기 위한 여러 가지 방법들이 있는데, 예를 들어 다음과 같이 ant 스크립트에서 이를 명시할 수도 있다.
   <exec executable="wsimport">
     <env key="VMARGS" 
         value="-Djavax.net.ssl.trustStore=${truststore.location} 
         -Djavax.net.ssl.trustStorePassword=${ssl.password}"/>
    <arg line="-keep -d ${client.build} 
    https://serverName:8181/HelloEjbService/HelloEjb?WSDL"/>
   </exec>
클라이언트 Truststore 및 Keystore 설정
서버를 위한 truststore 파일 외에 클라이언트를 위한 truststore 파일도 필요하다. 클라이언트는 truststore 내의 인증서들과 대조하여 서버 인증서를 검증하는데, SSL을 이용한 안전한 접속이 이루어지려면 클라이언트 측 truststore가 서버 인증서를 신뢰해야 한다. SSL 상호 인증을 위해서는 서버 측 truststore 역시 클라이언트 인증서를 신뢰해야 한다. 또한 서버 측 truststore를 수정할 경우에는 서버를 재시작해야 한다(이로써 새 인증서를 사용할 수 있게 된다). 생산 증명은 공동 인증 기관(CA, Certificate Authority)에서 승인하기 때문에 생산 환경에서는 상기 과정이 필요치 않을 수 있다. GlassFish 빌드에는 몇 가지의 공동 루트CA에 대한 인증서가 포함되어 있다.
SSL 상호 인증의 경우에는 클라이언트 keystore(클라이언트의 키와 인증서가 포함된 파일)에 자체 키를 제공해야 하고, keystore는 JDK 5.0에 포함된 키와 인증서 관리 유틸리티인 keytool을 이용하여 생성할 수 있다.
클라이언트 실행
SSL을 통해 웹 서비스에 액세스하는 클라이언트를 실행하기에 앞서 먼저 환경 변수 VMARGS의 값을 설정해야 한다. 그런 다음에야 평소처럼 애플리케이션을 실행할 수 있다. SSL의 경우에는 VMARGS의 값을 다음과 같이 설정한다.
   -Djavax.net.ssl.trustStore=${truststore.location} 
   -Djavax.net.ssl.trustStorePassword=${ssl.password}
SSL 상호 인증의 경우에는 VMARGS의 값을 다음과 같이 설정한다.
   -Djavax.net.ssl.trustStore=${truststore.location} 
   -Djavax.net.ssl.trustStorePassword=${ssl.password} 
   -Djavax.net.ssl.keyStore =${keystore.location} 
   -Djavax.net.ssl.keyStorePassword=${ssl.password}
예제 코드 실행하기
본 팁에 첨부된 예제 코드를 실행하려면 다음 단계를 수행한다.
  1. GlassFish를 아직 구하지 못했다면 GlassFish 커뮤니티 다운로드 페이지에서 다운로드하여 설치한다.
  2. 아래의 환경 변수를 설정한다:

    • GLASSFISH_HOME. GlassFish의 설치 장소를 표시해야 한다.
    • ANT_HOME. ant의 설치 장소를 표시해야 한다. Ant는 다운로드한 GlassFish 번들에 포함되어 있다. (Windows에서는 libant 서브디렉토리에 있음.)
    • JAVA_HOME. 사용자 시스템에서의 JDK 5.0 위치를 표시해야 한다.
    PATH 환경 변수에 $JAVA_HOME/bin, $ANT_HOME/bin$GLASSFISH_HOME/bin을 추가한다.
  3. 예제 패키지를 다운로드하여 압축을 푼다. 새로 압축이 풀린 디렉토리는 <sample_install_dir>/ttmay2006ws-ssl로 표시되어야 하는데, 이 때 <sample_install_dir>은 예제 패키지가 설치된 디렉토리를 나타낸다. ttmay2006ws-ssl 아래의 ws-ssl 디렉토리에는 예제용 소스 파일과 기타 지원 파일이 포함되어 있다.
  4. ws-ssl 디렉토리로 이동하여 build.properties 파일을 적절히 편집한다. 예를 들어 admin 호스트가 원격인 경우에는 admin.host의 값을 기본값localhost에서 해당 원격 호스트로 변경한다. 아울러, 아래의 속성들이 올바르게 명시되어 있는지 확인한다.

    • server.cert.cn. server.cert.cn. 서버 인증서의 CN 이름. 이는 호스트명 또는 호스트명과 도메인명을 합한 FQDN이어야 한다. GlassFish의 기본값 설치에서 서버 인증서에는 alias name s1as가 포함된다. 다음 명령어를 통해 CN을 디스플레이할 수 있다.
              keytool -list -v -alias s1as -keystore 
              $GLASSFISH_HOME/domains/domain1/config/cacerts.jks
      
      다음으로 keystore 비밀번호가 프롬프트되면 기본값 비밀번호 changeit를 입력한다. 이 때, 비밀번호는 변경이 가능하다.
    • admin.user. 도메인을 시작/중단하는 관리자의 ID.
    • admin.port. 관리 서버의 http 포트 번호.
    • https.port. 서버의 https 포트 번호.
  5. passwd 파일 내의 AS_ADMIN_PASSWORD 값을 관리자 비밀번호로 업데이트한다.
  6. 다음 명령어를 입력하여 클라이언트 키 및 인증서를 설정한다.
          ant setup
    
    이렇게 하면 로컬 keystore에 개인 키가 생성되고 인증서가 익스포트되어 이를 공통 truststore에 임포트하게 된다. 이때 자체 서명 인증서가 truststore에 설치된다는 점에 유의할 것. 이는 단지 테스트용일 뿐 실제 제작 상황에서 권장할 만한 사항은 아니다.
  7. GlassFish가 실행 중이면 아래와 같이 중단시킨다.
          $GLASSFISH_HOME/bin/asadmin stop-domain domain1
    
    그런 다음 작업을 시작한다.
       
          $GLASSFISH_HOME/bin/asadmin start-domain domain1
    
    이렇게 하면 truststore에서 새로운 인증서를 불러오게 된다.
  8. 예제를 구축하고 배포한다. 먼저 다음의 명령어를 입력한다.
          ant build
    
    이로써 EJB와 Servlet Web Services 클래스가 컴파일되고 ear 파일이 생성된다.

    이어서 아래 명령어를 입력한다.
          ant deploy
    
    이제 GlassFish에 ear 파일이 배포된다.

    마지막으로 아래 명령어를 입력한다.
          ant build-client
    
    이 명령어는 artifacts를 생성하고 클라이언트 측 코드를 컴파일하는데 사용된다.
  9. 클라이언트 애플리케이션을 실행하여 SSL을 통해 웹 서비스에 액세스하고, 다음 명령어를 입력한다.
          ant run
    
    아래와 유사한 결과가 표시되어야 한다.
          [exec] Retrieving port from the service 
          ejbws.HelloEjbService@4e21db
          [exec] Invoking hello operation on the 
          HelloEjbService port
          [exec] Ejb WS: CN=serverName, OU=SSLClient, O=EJTechTips, 
          L=Santa Clara, ST=California, C=US: Hello World
          [exec] Retrieving port from the service 
          servletws.HelloServletService@ea7549
          [exec] Invoking hello operation on the 
          HelloServletService port
          [exec] Servlet WS: CN=serverName, OU=SSLClient, 
          O=EJTechTips, L=Santa Clara, ST=California, 
          C=US: Hello World
    
    jvm 옵션-Djavax.net.debug=ssl,handshake를 추가하여 SSL handshake에 관한 정보를 비롯한 추가 정보를 볼 수 있다. 예제의 경우에는 아래 명령어를 입력하면 된다.
           ant run-debug
    
    handshake 과정에서 CertificateRequest를 살펴보면 이것이 SSL 상호 인증인지 확인할 수 있다.

    디버깅 정보를 더 보고 싶으면 jvm 옵션 -Djavax.net.debug=all을 이용한다.
  10. 아래 명령어를 입력하여 웹 서비스 ear 파일을 배포 해제할 수 있다.
           ant undeploy
    
  11. 애플리케이션을 배포 해제한 후에는 keystores에서 생성된 클라이언트 인증서를 제거하여 메모리에서 인증서가 제거되도록 한다. 이를 위해서는 다음 명령어를 실행한다:
           ant unsetup
           $GLASSFISH_HOME/bin/asadmin stop-domain domain1
           $GLASSFISH_HOME/bin/asadmin start-domain domain1 
    

JAX-RPC Vs JAX-WS

JAX-WS 2.0은 JAX-RPC 1.1의 후속 제품입니다. 이 두 가지 웹 서비스 프로그래밍 모델을 비교합니다.


머리말
웹 서비스는 긴 역사를 갖고 있다. 처음에는 SOAP 이 있었다. 하지만 SOAP 은 메시지가 어떻게 보이는지를 기술만 할 뿐이었다. 그 다음에는 WSDL이 등장했다. 하지만 WSDL은 자바™로 웹 서비스를 작성하는 방법을 알려주지 않았다. 그 뒤를 JAX-RPC 1.0이 이었다. 몇 달 사용하고 난 후에, 그 스팩을 작성했던 Java Community Process (JCP) 멤버들은 약간의 조정이 필요하다는 것을 깨달았고, 그 결과로 JAX-RPC 1.1이 탄생했다. 이 스팩을 사용하고 1년 정도가 지난 후에, JCP 멤버들은 더 나은 버전을 구현하고 싶었다. 바로 JAX-RPC 2.0이다. 주요 목표는 산업 방향에 맞추어 조합하는 것이었지만, 업계는 RPC 웹 서비스를 좀처럼 수행하지 않았고, 여전히 메시지 지향 웹 서비스를 사용하고 있었다. 따라서 “RPC”가 명칭에서 빠지고, "WS"(물론, Web Services를 의미한다.)로 대체되었다. 따라서 JAX-RPC 1.1의 후계자는 JAX-WS 2.0(Java API for XML-based Web services)인 것이다.
JAX-RPC 1.1과 JAX-WS 2.0간 차이점을 조목조목 따지기 전에, 변하지 않은 것은 무엇인지부터 짚고 넘어가자.
  • JAX-WS는 여전히 SOAP 1.1 over HTTP 1.1을 지원하기 때문에 상호 운용 성은 문제 없다. 같은 메시지가 여전히 와이어를 타고 흐른다.
  • JAX-WS는 여전히 WSDL 1.1을 지원하기 때문에, 여러분이 알고 있는 스팩이 여전히 유효하다. WSDL 2.0 스팩은 거의 완성 단계에 다다랐지만, JAX-WS 2.0 이 완성되었을 당시에는 여전히 작업 중이었다.
  • SOAP 1.2
    JAX-RPC와 JAX-WS는 SOAP 1.1을 지원한다. JAX-WS 역시 SOAP 1.2를 지원한다.
  • XML/HTTP
    WSDL 1.1 스팩은 HTTP 바인딩을 정의했는데, 이는 SOAP 없이 HTTP를 통해 XML 메시지를 전송할 수 있는 수단이 된다. JAX-RPC는 HTTP 바인딩을 무시했다. JAX-WS는 여기에 대한 지원을 추가했다.
  • WS-I's Basic Profiles
    JAX-RPC는 WS-I의 Basic Profile (BP) version 1.0을 지원한다. JAX-WS는 BP 1.1을 지원한다. (WS-I는 웹 서비스 상호 운용성 기구이다.)
  • 새로운 자바 기능
    • JAX-RPC는 자바 1.4로 매핑된다. JAX-WS는 Java 5.0과 매핑된다. JAX-WS는 Java 5.0의 새로운 많은 기능들에 의존한다.
    • J2EE 1.4의 후속인 Java EE 5는 JAX-WS에 대한 지원을 추가했지만, JAX-RPC도 여전히 지원한다. 이것 때문에, 웹 서비스 풋내기들이 혼란을 겪는다.
  • 데이터 매핑 모델
    • JAX-RPC는 고유의 데이터 매핑 모델이 있는데, 모든 스키마 유형의 90 퍼센트를 커버한다. 커버되지 않는 것들은 javax.xml.soap.SOAPElement로 매핑된다.
    • JAX-WS의 데이터 매핑 모델은 JAXB이다. JAXB는 모든 XML 스키마에 대한 매핑을 약속한다.
  • 인터페이스 매핑 모델
    JAX-WS의 기본 인터페이스 매핑 모델은 JAX-RPC 모델과는 크게 다르지 않다. 하지만:
    • JAX-WS의 모델은 새로운 Java 5.0 기능을 사용한다.
    • JAX-WS의 모델은 비동기식 기능을 도입했다.
  • 동적 프로그래밍 모델
    • JAX-WS의 동적 클라이언트 모델은 JAX-RPC의 그것과는 매우 다르다. 업계의 필요에 맞춰 많은 변화가 생겼다.
      • 메시지 지향 기능을 도입한다.
      • 동적 비동기식 기능을 도입한다.
    • JAX-WS는 동적 서버 모델도 추가한다. 이것은 JAX-RPC에는 없다.
  • MTOM (Message Transmission Optimization Mechanism)
    JAXB를 통한, JAX-WS는 새로운 어태치먼트 스팩인 MTOM에 대한 지원을 추가한다. Microsoft는 SOAP with Attachments 스팩을 전혀 채택하지 않았다. 하지만 누구나 MTOM을 지원하기 때문에, 어태치먼트 상호 운용성은 현실이 되었다.
  • 핸들러 모델
    • 핸들러 모델은 JAX-RPC와 JAX-WS가 매우 다르다.
    • JAX-RPC 핸들러는 SAAJ 1.2에 기반하고 있다. JAX-WS 핸들러는 새로운 SAAJ 1.3 스팩에 기반하고 있다.
이제는 SOAP 1.2, XML/HTTP, WS-I Basic Profiles, Java 5에 대해 설명하도록 하겠다.
SOAP 인코딩
SOAP 인코딩은 웹 서비스 커뮤니티의 관심사에서 멀어지고 있다. WS-I 기본 프로파일에서 지원되지 않는다. 따라서, 자바 웹 서비스의 최신판인 JAX-WS는 SOAP 인코딩을 허용하지 않는다. JAX-RPC는 SOAP 인코딩을 지원하므로, SOAP 인코딩 메시지를 사용해야 한다면, JAX-RPC를 고수하라.
프로그래밍 모델 관점에서 볼 때, SOAP 1.1과 SOAP 1.2 사이에는 큰 차이는 없다. 자바 프로그래머로서 느끼게 되는 유일한 차이라면, 핸들러를 사용할 때이다. SAAJ 1.3이 업데이트 되어 SOAP 1.2를 지원한다.
SOAP 1.2의 변화와 마찬가지로, SOAP/HTTP와 XML/HTTP 메시지들 간에는 프로그래밍 모델 관점에서 볼 때 큰 차이가 없다. 유일한 차이는 핸들러를 사용할 때이다. 앞으로의 글에서 설명하겠다. HTTP 바인딩은 고유의 핸들러 체인과 메시지 콘텍스트 속성들을 갖고 있다.
JAX-RPC 1.1은 WS-I Basic Profile (BP) 1.0을 지원한다. 이후에, WS-I 멤버들은 BP 1.1을 개발했다. (관련 AP 1.0과 SSBP 1.0도 개발했다.) 이 새로운 프로파일은 소소한 문제들을 명확히 했고, 어태치먼트에 대해서 보다 명확히 정의를 내렸다. JAX-WS 2.0은 이 새로운 프로파일을 지원한다. 대부분의 경우, 이들의 차이점은 자바 프로그래밍 모델에는 영향을 미치지 않는다. 예외는 어태치먼트이다. WS-I는 어태치먼트에 대한 몇 가지 의문점을 해결하지 않은 채, 고유의 XML 어태치먼트 유형인 wsi:swaRef를 정의했다.
많은 사람들은 이 모든 프로파일들에 혼란을 겪는다. 혼란을 막으려면 히스토리가 필요하다.
WS-I의 첫 번째 기본 프로파일(BP 1.0)은 다양한 스팩들을 명확히 했다. 하지만, 완벽하지는 못했다. 특히 SOAP with Attachments (Sw/A)에 대한 지원은 여전히 혼란스럽다. WS-I 멤버들은 기본 프로파일을 기반으로 어태치먼트를 만들었고(BP 1.1), 그들이 놓쳤던 부분들을 픽스했다. 또한 기본 프로파일에 독자적인 보충을 직접 추가했다. AP 1.0 과 SSBP 1.0이다. AP 1.0은 Attachment Profile로서 Sw/A의 사용법을 기술하고 있다. SSBP 1.0 은 Simple SOAP Binding Profile이고, (Microsoft의 .NET 처럼) Sw/A를 지원하지 않는 웹 서비스 엔진을 기술하고 있다. WS-I가 보유하고, 작업 중인 나머지 프로파일들은 기본 프로파일들을 바탕으로 만들어지고 있다.
자바 언어에도 많은 변화가 있었다. JAX-WS는 다음에 의존한다. 주석, 제너릭, executor. JAX-WS가 이 새로운 기능에 어떻게 의존하는지를 다음 글에서 설명하겠다. 자바의 새로운 특징은 참고자료섹션에서 Java 5 링크를 참조하기 바란다.
JAX-WS 2.0은 JAX-RPC 1.1의 후속이다. 변하지 않은 부분들도 있지만, 프로그래밍 모델 대부분은 어느 정도는 변했다. 이 글에서 다룬 주제들은 후속 시리즈에서 계속 설명해 나갈 것이다. 다음 글에서는 JAX-RPC에서 JAX-WS로 옮겨야 하는 이유 또는 옮기지 말아야 하는 이유를 상세하게 비교 분석하겠다.
JAX-RPC 1.1을 고수해야 하는 이유:
  • 당분간 계속 유지하고 싶다면, 당분간은 JAX-RPC도 지원된다.
  • Java 5로 전향하기 싫을 경우
  • SOAP 인코딩 메시지를 보내거나 RPC/encoded 스타일의 WSDL을 보내야 하는 경우
JAX-WS 2.0으로 전향해야 하는 이유:
  • 새로운 메시지 지향 API를 사용해야 할 경우
  • MTOM을 사용하여 어태치먼트 데이터를 보내야 하는 경우
  • JAXB를 통해 XML 스키마를 더욱 잘 지원하기 위해
  • 웹 서비스 클라이언트에 비동기식 프로그래밍 모델을 사용하고 싶을 경우
  • SOAP 1.2 메시지를 핸들 할 수 있는 클라이언트나 서비스가 있어야 하는 경우
  • 웹 서비스에서 SOAP을 배제하고 XML/HTTP 바인딩만 사용하고 싶을 경우
  • 최신 기술을 사용하고 싶을 때


교육

제품 및 기술 얻기


Russell Butek은 IBM의 SOA 및 웹 서비스 컨설턴트이다. 한때는 IBM WebSphere 웹 서비스 엔진 개발자로서, 또한 JAX-RPC Java Specification Request (JSR) 전문가 그룹의 멤버로 활동했었다. Apache의 AXIS SOAP 엔진 구현에도 참여했다.

Nick Gallardo는 IBM 소프트웨어 엔지니어이다. 웹 서비스의 다양한 측면들을 연구하고 있다. 최근에는 JAX-WS 지원도 하고 있다. 이전에는, WebSphere와 Tivoli 플랫폼에서 작업했다.

Eclipse 3.0 TIP

TIP 01. 코드 형식화

팀 프로젝트를 진행할때 개발자별로 Coding Style이 달라서 고생하는 경우가 많습니다.
이를 위해 Eclipse는 코드 형식화를 지원하는데요, 아래와 같이 코딩 규칙을 위해바는 코드가 있다고 가정합시다

해당 코드 위에서 [ Ctrl+Shift+F ] 키만 누르면 아래와 같이 코드가 이쁘게 정리됩니다.

이는 Eclipse에서 설정된 Code Formatter의 설정에 따른 것입니다.
프로젝트에서 개발된 모든 코드에 같은 코딩 규칙을 적용하고 싶다면..
결정된 Coding Convention에 따라 Code Formatter의 설정을 바꾼 다음,
그것을 XML 파일로 Export하고, 개발자에게 Import 시켜 적용하도록 하면 된답니다.

아래 그림은 Windows - Preferences 에서 "Java - Code Style - Code Formatter"를
선택했을 때 나오는 그림입니다.
Eclipse 3.0은 기본적으로 2가지 코드 형식을 기본적으로 내장하고 있습니다.

Java Conventions를 선택하고, Show.. 버튼을 누르면 해당 설정을 커스터마이징 할 수 있습니다.
탭 사이즈와 괄호의 위치 등 모든 것을 변경할 수 있습니다.


TIP 02. import문 정리

개발할 때 어떤 기능을 구현하기 위해 특정 라이브러리를 import 시켜놓고,
그 기능이 필요없어져서 삭제한 다음에도 import문은 그대로 두는 경우가 많습니다.

그때 Eclipse가 제공하는 Organize import 기능은 아주 유용한데요..
아래와 같이 사용되지 않는 라이브러리를 import한 경우 Eclipse는 앞에 전구를 키고 표시해줍니다.

이때 [ Ctrl+Shift+O ] 버튼을 누르면 사용하지 않는 모든 import 문이 정리됩니다. 아래와 같이 깨끗하게 말이죠.

또 한가지 유용한 기능은 같은 패키지 내에서 여러 개의 클래스를 import할 경우입니다.
예를 들어 한 패키지 내에서 4개 이상의 클래스를 import 한다면,
그것을 *로 합쳐서 표시하도록 하고 싶을 때가 있습니다.
그럴 때는 window - preference 로 가서 java - code style - organize import에서
Number of imports needs for .*의 수를 4로 해놓으면,
같은 패키지에서 4개이상의 클래스가 임포트되면 *로 합쳐서 표시해줍니다.
(Apply 버튼 바로 위에 그 항목이 있습니다.)

TIP 03. 영역별로 주석처리하기

아래 25~36 라인과 같이 여러 줄에 걸쳐 있는 코드를 주석 처리하고 싶은데,
주석 처리하고자 하는 영역 내에 /* */가 있을 경우 참 곤란하시죠?

일일이 // 를 앞에 붙이려니 얼마나 손가락이 빠른지를 테스트하는거 같구.. ^^*
그럴 때 주석처리할 영역을 선택 한 다음 [ Ctrl+/ ] 를 눌러보세요.
아래와 같이 자동으로 해당 영역을 주석으로 만들어줍니다.
주석을 해제하고 싶다면 다시 한번 더 [ Ctrl+/ ]를 눌러주면 됩니다.

TIP 04. 에디터간 이동하기

실제 프로젝트를 작업하다 보면 한번에 열어놓은 파일이 30개가 넘는 것은 기본이죠?
그때 해당 파일들 사이를 열려진 윈도우를 [ Alt+Tab ] 을 이용해서 이동하는 것 같은 기능이 있다면 편할겁니다.
그러한 단축키가 [ Ctrl+F6 ] 입니다.
그 키를 누르면 화면 중앙에 아래와 같은 에디터 이동 화면이 뜹니다.

바로 이전으로 이동할 때는 [ Ctrl+F6 ]이 편하지만,
여러 개 중 하나를 이동할 때는 [ Ctrl+F6 ]을 누른 후, [Ctrl+화살표] 를 이용해서 원하는 에디터로 이동하는 것이 편합니다.


TIP 05. 잘모르는 메소드 JavaDoc 설명 확인하기

예를 들어 Vector를 이용하는데 iterator()라는 메소드를 사용했다고 합시다.
그런데 iterator()라는 메소드가 뭔지 잘 몰라서 API 문서를 확인하고 싶을 때가 있지요?
그때 코드 위에서 바로 [ F2 ] 버튼만 누르면 JavaDoc 주석에 있는 API 설명을 확인할 수 있습니다.
아래 그림처럼 말이죠. 일일이 API 문서를 찾아다닐 필요가 없으니 정말 편리하겠지요?

TIP 06. 줄번호 표시 및 줄 이동하기

Eclipse의 기본 설정에 라인 번호는 표시되지 않도록 되어 있습니다.
디버깅할 때 특정 라인에 에러가 있음을 확인했는데, 일일이 줄을 세어가면서 이동할 수도 없구..
그때 해당 라인으로 이동하기 위한 단축키가 [ Ctrl+L ] 입니다.
윈도우와 같이 Ctrl+G 로 단축키를 변경해서 쓰시는 것도 좋을 듯 합니다.

아예 줄번호가 항상 표시되도록 하고 싶다면 window - preference 에서,
Java - Editor로 이동한 다음 "Show line numbers"를 체크해두시면 됩니다.

TIP 07. 변경사항 추적하기

변경 사항을 추적하고자 하는 파일을 PackageExplorer에서 선택 후,
오른쪽 버튼을 눌러 컨텍스트 메뉴에서 [ compare with Local History ] 선택합니다.

위와 같은 그림이 뜨면서 시간대 별로 이전의 작업 결과를 보실 수 있습니다.
만일 이전의 코드로 되돌아가고 싶다면, 같은 방법으로 파일의 컨텍스트 메뉴에서
[ Replace with ] 를 선택하고, [ Local History ]에서 변경하면 됩니다.

TIP 08. Javadoc 문서생성

JavaDoc 형태의 주석으로 소스코드 문서화가 된 상태라고 가정하겠습니다.
Project 메뉴의 [ Generate Javadoc... ] 기능을 실행하면
간편한 마법사의 지원을 통해 Javadoc 문서를 생성할 수 있습니다.

일반적으로 프로젝트 루트 밑에 doc 이란 폴더 안에 JavaDoc으로 생성된 API 문서를 포함합니다.

생성될 API 문서에 포함시킬 정보를 선택하는 것이 마법사의 다음 단계입니다.
Finish 버튼을 누르면 Package Explorer에 아래와 같이 API 문서가 생성된 것을 확인할 수 있습니다.

TIP 09. 전체프로젝트 ZIP 백업

전체 프로젝트를 백업하기 위해 압축을 해야 할때 유용한 기능입니다.
File 메뉴의 Export 기능을 실행하면 아래와 같은 윈도우가 뜹니다.

선택요소 중에서 ZIP 파일을 선택합니다.
다음 화면은 백업할 요소들을 선택하는 것입니다.
일반적으로 자동 생성되는 JavaDoc 문서나 Classes 파일들은 백업하지 않습니다.
적당한 백업 파일 이름과 위치를 결정하고 Finish 버튼을 누르면 백업이 완료됩니다.










Maven을 지원하는 JAX-WS 사용

JAX-WS(Java API for XML-Based Web Services)는 SOAP 기반 및 RESTful 자바 웹 서비스 개발의 바탕이 되는 기술로서, GlassFish의 웹 서비스 기술 스택인 Metro 프로젝트의 핵심 요소입니다. JAX-WS는 고성능 런타임을 제공할 뿐 아니라 웹 서비스 및 웹 서비스 클라이언트를 만들 수 있는 도구인 wsimportwsgen을 제공합니다. wsimport 도구는 WSDL(Web Services Definition Language) 파일을 입력으로 받아 SEI(Service Endpoint Interface)와 같은 이동 가능한 JAX-WS 아티팩트를 생성합니다. wsgen 도구는 웹 서비스 엔드포인트 클래스를 읽고 웹 서비스 배포 및 호출에 필요한 모든 아티팩트를 생성합니다.

wsimportwsgen 도구는 GlassFish CLI(Command Line Interface)를 통해 액세스할 수 있습니다. 또는 Ant 태스크나 Maven 플러그인을 통해서도 액세스할 수 있습니다. 이 팁에서는 JAX-WS Maven 플러그인을 사용하여 웹 서비스를 개발하는 방법에 대해 설명합니다.


Maven

Maven은 구성 가능성이 매우 우수한 프레임워크로서, 애플리케이션 빌드 및 배포에서부터 문서 생성 및 프로젝트 관리에 이르는 프로젝트 수명 주기의 다양한 측면을 관리하는 데 사용할 수 있습니다. Maven은 Ant처럼 프로젝트 레이아웃과 의존성 관리 체계가 표준화되어 있어 매우 널리 사용되고 있는 개발 도구입니다. 프로젝트 레이아웃에 대해 표준 규약을 따르고 컴파일 및 패키징과 같은 수명 주기 단계에서 표준 기본값을 사용하면 이해하기 쉽고 관리하기 쉬운 프로젝트를 만들 수 있습니다.

Maven은 POM(Project Object Model)을 사용하여 프로젝트와 관련된 정보를 기술합니다. 프로젝트 빌드 및 배포 방법을 정의해야 하는 Ant와 달리 모든 Maven 프로젝트는 빌드 및 패키징과 같은, 명확하게 정의된 태스크를 수행하는 데 있어 일련의 플러그인을 항상 공유합니다. 또한 이러한 플러그인은 기본 동작 및 빌드 순서를 필요한 대로 변경하여 구성할 수도 있습니다.

Maven에 대한 자세한 내용은 Welcome to MavenBuilding Web Applications with Maven 2를 참조하십시오.


JAX-WS Maven 플러그인

앞에서 언급했듯이 JAX-WS는 웹 서비스 배포를 위해 wsimportwsgen이라는 두 개의 도구를 제공합니다. JAX-WS Maven 플러그인은 이러한 도구를 위한 Maven 어댑터를 제공합니다. 이 플러그인은 도구 기능에 jaxws:wsimportjaxws:wsgen이라는 작업을 추가합니다. Maven에서 작업은 쉽게 말해 Ant 태스크와 같은 것입니다. 두 가지 작업 각각에 대해 플러그인은 해당 CLI 또는 Ant 태스크에 전달될 수 있는 모든 구성 옵션을 허용합니다.

jaxws:wsimport 작업을 위해 플러그인은 WSDL 파일을 읽고 웹 서비스 생성, 배포 및 호출에 필요한 자바 클래스를 생성합니다. jaxws:wsimport 작업은 수명 주기 단계 생성 소스 내에서 자동으로 실행됩니다. 이 플러그인은 기본적으로 ${basedir}/src/wsdl 디렉토리에서 WSDL 파일을 찾습니다. 그러나 wsdlLocation 매개변수를 구성하여 WSDL 파일의 위치를 지정할 수도 있습니다. 모든 jaxws:wsimport 구성 매개변수에 대한 설명은 jaxws:wsimport에 대한 JAX-WS commons 페이지에서 볼 수 있습니다.

jaxws:wsgen 작업의 경우 플러그인은 SEI 클래스를 읽고 JAX-WS 웹 서비스에 필요한 모든 이동 가능 아티팩트를 생성합니다. jaxws:wsgen 작업은 수명 주기 프로세스 클래스 내에서 자동으로 실행됩니다. 이 플러그인을 사용하려면 jaxws:wsgen 작업에 대해 sei 매개변수를 설정하여 서비스 엔드포인트 구현 클래스 이름을 지정해야 합니다. 또는 genWsdl 매개변수를 지정할 경우 서비스 엔드포인트 구현 클래스에서 WSDL 파일의 형태로 서비스 설명을 생성할 수도 있습니다. 그러나 genWsdl 매개변수는 선택적인 매개변수이며 JAX-WS 런타임은 배포 후에 WSDL을 동적으로 생성할 수 있습니다. 모든 jaxws:wsgen 매개변수에 대한 설명은 jaxws:wsgen에 대한 JAX-WS commons 페이지에서 볼 수 있습니다.

jaxws:wsimportjaxws:gen 작업은 해당 수명 주기 단계가 실행될 때 자동으로 실행됩니다. 또는 jaxws-maven-plugin:wsimport와 같이 작업을 지정하여 명시적으로 플러그인을 실행할 수도 있습니다. Maven 빌드 수명 주기 단계 및 실행에 대한 자세한 내용은 Introduction to the Build Lifecycle을 참조하십시오.


Ant
대신 JAX-WS Maven 플러그인을 사용하는 이유

Ant 태스크 대신 JAX-WS Maven 플러그인을 사용하면 Ant 태스크에서 요구되는 JAX-WS 의존 관계 구성, 클래스 경로 설정, 컴파일 및 패키징을 위한 도구 태스크 호출 등을 수행할 필요가 없다는 장점이 있습니다. Maven은 모든 의존 관계를 자동으로 다운로드하여 해당 애플리케이션에서 사용할 수 있도록 하며 빌드 수명 주기 단계에 이를 추가합니다. 그러나 플러그인 동작을 원하는 방식으로 지정할 수 있도록 일부 구성을 미설정 상태로 두어야 할 수 있습니다.

JAX-WS Maven 플러그인 및 기타 JAX-WS 도구에 대한 자세한 내용은 Metro Tools 페이지를 참조하십시오.


JAX-WS Maven 샘플

지금까지 JAX-WS Maven 플러그인에 대한 기본적인 내용을 일부 설명했습니다. 이제 이 플러그인을 사용하여 웹 서비스와 웹 서비스 클라이언트를 생성하는 샘플 애플리케이션을 살펴보겠습니다. NetBeans IDE는 플러그인을 통해 Maven 2(Maven 최신 버전) 프로젝트 관리를 지원합니다. IDE에서 플러그인을 사용하면 Maven 기반의 프로젝트를 만들고, IDE 액션을 Maven 작업에 연결하여 Maven 명령을 실행할 수 있으며, 리포지토리 찾기, 의존 관계 추가, 웹 애플리케이션의 즉석 배치 등을 쉽고도 간편하게 수행할 수 있습니다.

이러한 작업의 일부는 Maven을 실행한 후 POM 파일에서 구성을 편집하여 수동으로 수행할 수도 있습니다. 그러나 NetBeans IDE는 POM을 자동으로 생성하고 구성할 수 있는 보다 간편한 방법을 제공합니다. 따라서 이 팁의 샘플에서는 NetBeans IDE 6.0을 사용하겠습니다.

본 팁에는 샘플 애플리케이션 코드가 수록된 패키지가 함께 제공됩니다. 아래의 설명을 사용하여 샘플 애플리케이션을 빌드할 때 사용자가 직접 작성하는 파일과 패키지에서 제공하는 파일을 비교할 수 있습니다.


초기 설정

샘플을 설치하고 실행하기 전에 다음과 같이 몇 가지 초기 설정을 수행해야 합니다.

  1. 다음 도구를 설치하지 않았을 경우 이를 다운로드하여 설치합니다.  


    또한 JDK 6 업데이트 4 릴리스 이전 버전의 JDK 6에서 샘플을 실행하려면 jaxb-api.jarjaxws-api.jar 파일을 <java-home>/lib/endorsed로 복사하여 EOM(Endorsed Override Mechanism)을 사용해야 합니다. 이 경로에서 <java-home>은 런타임 소프트웨어가 설치된 디렉토리로서 자바 SE 런타임 환경의 최상위 디렉토리이거나 JDK의 jre 디렉토리입니다. JDK 6 업데이트 4 이상에서 이 샘플을 실행할 경우 Override Mechanism을 사용할 필요가 없습니다.  

  2. GlassFish v2를 별도로 다운로드했을 경우 다음과 같이 NetBeans에 등록합니다.  

    • Services 창에서 Servers 노드를 마우스 오른쪽 버튼으로 클릭합니다.
    • Add Server를 선택합니다.
    • Server를 Sun Java System Application Server로 유지합니다.
    • Next 버튼을 클릭합니다.
    • Browse 버튼을 클릭한 후 GlassFish V2가 설치된 위치로 이동합니다.
    • Choose 버튼을 클릭합니다.
    • Next 버튼을 클릭합니다.
    • GlassFish v2에 대해 다른 비밀번호를 선택하지 않았다면 Admin Password를 기본값인 adminadmin으로 설정합니다.
    • Finish 버튼을 클릭합니다.

  3. 다음과 같이 Mevenide2-Netbeans 플러그인을 설치합니다. 이 플러그인은 Maven 2 프로젝트에 대해 NetBeans를 지원합니다.  

    • Tools 메뉴에서 Plugins를 선택합니다.
    • Plugins 창에서 Available 플러그인을 선택합니다.
    • Maven 플러그인을 선택합니다.
    • Install 버튼을 클릭합니다.


프로젝트 및 하위 프로젝트 생성

이 샘플에서는 jaxws-maven-sample이라는 주 프로젝트(상위 프로젝트)를 작성합니다. 이 상위 프로젝트에는 웹 서비스용의 HelloService 하위 프로젝트와 웹 서비스 클라이언트용의 HelloClient 하위 프로젝트가 있습니다. 다음은 프로젝트의 구조를 보여 줍니다.

   jaxws-maven-sample (POM Project)
     helloservice (WAR project)
     helloclient (JAR Project)

리던던시를 피하기 위해 상위 프로젝트 POM에는 HelloServiceHelloClient에서 공통되는 구성 매개변수가 들어 있습니다. 프로젝트와 하위 프로젝트를 만들려면 다음과 같이 합니다.

  1. 상위 POM 프로젝트인 jaxws-maven-sample을 작성합니다.  

    • File 메뉴에서 New Project를 선택합니다.
    • Maven 범주를 선택한 다음 Maven 프로젝트를 선택합니다.
    • Next 버튼을 클릭합니다.
    • Maven Quickstart Project 세대 유형(기본값)을 선택합니다.
    • 이어서 표시되는 화면에서 Maven 프로젝트 코오디네이트라고 하는 다음과 같은 프로젝트 설정을 지정합니다.  

          - ProjectName: jaxws-maven-sample
          - ProjectLocation: 프로젝트를 포함할 디렉토리를 지정합니다(예: Users/ramapulavarthi).
          - Version: 1.0-SNAPSHOT
          - GroupId: com.example.maven.jaxws
          - Package: com.example.maven.jaxws  

    • Finish 버튼을 클릭하여 프로젝트를 작성합니다.

    NetBeans Projects 창에 해당 프로젝트가 표시되어야 합니다.  

  2. 프로젝트 등록 정보를 jar에서 pom으로 변경합니다.  

    • Projects 창에서 jaxws-maven-sample을 마우스 오른쪽 버튼으로 클릭합니다.
    • 메뉴에서 Properties 옵션을 선택합니다.
    • General 범주에서 Packaging 값을 jar에서 pom으로 변경합니다.
    • OK 버튼을 클릭합니다. Projects 창에 jaxws-maven-sample (pom)이라는 항목이 표시되는 것을 확인합니다.

  3. 기본적으로 생성된 의존 관계와 파일 중에서 필요 없는 것을 삭제합니다. 이 프로젝트는 POM 프로젝트이기 때문에 소스/테스트 대신 하위 모듈을 사용합니다. 따라서 프로젝트에서 소스를 제거해야 합니다. 또한 이 프로젝트에는 유닛 테스트가 없으므로 JUnit 의존 관계를 삭제해야 합니다.  

    • Projects 탭 옆에 있는 Files 탭을 클릭합니다.
    • Files 창에서 jaxws-maven-sample 아래에 있는 src 디렉토리를 마우스 오른쪽 버튼으로 클릭하고 Delete를 선택합니다.
    • Projects 창에서 jaxws-maven-sampleTestLibraries 노드를 확장하고 junit-3.8.1.jar를 마우스 오른쪽 버튼으로 클릭한 후 Remove Dependency를 선택합니다.

  4. 소스를 자바 5로 변경합니다. 웹 서비스를 만들기 위해서는 자바 5가 필요합니다. 그러나 기본값은 자바 1.4입니다.  

    • Projects 창에서 jaxws-maven-sample을 마우스 오른쪽 버튼으로 클릭합니다.
    • 메뉴에서 Properties 옵션을 선택합니다.
    • Sources 범주에서 Source/Binary Format 값을 1.4에서 1.5로 변경합니다.
    • OK 버튼을 클릭합니다.
     

    jaxws-maven-sample 아래의 Project Files에서 pom.xml 파일을 보면 구성 소스 및 대상 값이 1.5로 변경되어 있을 것입니다.
     
  5. 하위 프로젝트(WAR 프로젝트) helloservice를 작성합니다.  

    1단계, "상위 프로젝트(POM 프로젝트) jaxws-maven-sample 만들기"의 절차를 반복하되 Maven Quickstart Project 세대 유형 대신 Maven WebApp 세대 유형을 선택합니다. 또한 다음과 같이 설정을 지정합니다.  

           - ProjectName: helloservice
           - ProjectLocation: jaxws-maven-sample 프로젝트를 포함할 디렉토리를 지정합니다(예: /Users/ramapulavarthi/jaxws-maven-sample).
           - Version: 1.0-SNAPSHOT
           - GroupId: com.example.maven.jaxws
           - Package: com.example.maven.jaxws.helloservice  

    • Finish 버튼을 클릭하여 프로젝트를 작성합니다.
      NetBeans Projects 창에 helloservice Maven Webapp(war)가 표시되어야 합니다. helloservice용의 pom.xml 파일에는 상위 프로젝트 jaxws-maven-sample에 대한 참조가 들어 있으며, jaxws-maven-sample용의 pom.xml 파일은 이제 helloservice용 모듈을 지정합니다.

  6. helloservice용의 의존 관계와 파일 중에서 필요 없는 것을 삭제합니다.  

    • Projects 탭 옆에 있는 Files 탭을 클릭합니다.
    • Files 창에서 helloservice Maven webapp 아래의 src 디렉토리를 확장하고 test 디렉토리를 마우스 오른쪽 버튼으로 클릭한 후 Delete를 선택합니다.
    • Projects 창에서 helloservice Maven webapp의 TestLibraries 노드를 확장하고 junit-3.8.1.jar를 마우스 오른쪽 버튼으로 클릭한 후 Remove Dependency를 선택합니다.

  7. 하위 프로젝트(WAR 프로젝트) helloservice를 작성합니다.  

    1단계, "상위 프로젝트(POM 프로젝트) jaxws-maven-sample 만들기"의 절차를 반복하되 설정을 다음과 같이 지정합니다.  

           - ProjectName: helloclient
           - ProjectLocation: jaxws-maven-sample 프로젝트를 포함할 디렉토리를 지정합니다(예: /Users/ramapulavarthi/jaxws-maven-sample).
           - Version: 1.0-SNAPSHOT
           - GroupId: com.example.maven.jaxws
           - Package: com.example.maven.jaxws.helloclient  

    • Finish 버튼을 클릭하여 프로젝트를 작성합니다.
      NetBeans Projects 창에 helloclient(jar)가 표시되어야 합니다. helloclient용의 pom.xml 파일에는 상위 프로젝트 jaxws-maven-sample에 대한 참조가 들어 있으며, jaxws-maven-sample용의 pom.xml 파일은 이제 helloclient용 모듈을 지정합니다.

  8. helloclient용의 의존 관계와 파일 중에서 필요 없는 것을 삭제합니다.  

    • Projects 탭 옆에 있는 Files 탭을 클릭합니다.
    • Files 창에서 helloclient 아래의 src 디렉토리를 확장하고 test 디렉토리를 마우스 오른쪽 버튼으로 클릭한 후 Delete를 선택합니다.
    • 하위 프로젝트(WAR 프로젝트) helloservice를 작성합니다.  

      1단계, "상위 프로젝트(POM 프로젝트) jaxws-maven-sample 만들기"의 절차를 반복하되 설정을 다음과 같이 지정합니다.  

             - ProjectName: helloclient
             - ProjectLocation: jaxws-maven-sample 프로젝트를 포함할 디렉토리를 지정합니다(예: /Users/ramapulavarthi/jaxws-maven-sample).
             - Version: 1.0-SNAPSHOT
             - GroupId: com.example.maven.jaxws
             - Package: com.example.maven.jaxws.helloclient  

      • Finish 버튼을 클릭하여 프로젝트를 작성합니다.
        NetBeans Projects 창에 helloclient(jar)가 표시되어야 합니다. helloclient용의 pom.xml 파일에는 상위 프로젝트 jaxws-maven-sample에 대한 참조가 들어 있으며, jaxws-maven-sample용의 pom.xml 파일은 이제 helloclient용 모듈을 지정합니다.

    • helloclient용의 의존 관계와 파일 중에서 필요 없는 것을 삭제합니다.  

      • Projects 탭 옆에 있는 Files 탭을 클릭합니다.
      • Files 창에서 helloclient 아래의 src 디렉토리를 확장하고 test 디렉토리를 마우스 오른쪽 버튼으로 클릭한 후 Delete를 선택합니다.  

      • OK 버튼을 클릭합니다.

      jaxws-maven-samplepom.xml 파일에 이제 jaxws-rt.jar에 대한 컴파일 타임 의존 관계가 포함되며 컴파일 범위를 지정하는 것을 볼 수 있습니다. jaxws-rt.jar 파일은 런타임 시 서비스 및 클라이언트에서 사용할 수 있어야 합니다.  

      GlassFish에는 JAX-WS가 포함되므로 GlassFish를 배포 컨테이너로 사용할 경우 Scope 값을 "provided"로 설정할 수 있습니다. 이 경우 Maven은 "skinny" WAR 파일을 만들며 WAR 파일에 jax-ws jar 파일이 번들로 포함되지 않습니다.  

    • JAX-WS JAR에 대한 리포지토리 정보를 추가합니다. Maven은 이 정보를 사용하여 jaxws-maven-plugin과 해당 의존 관계 아티팩트를 가져옵니다.  

      • jaxws-maven-sample에 대한 Project Files 노드를 확장하고 pom.xml 파일을 엽니다.
      • JAX-WS JAR를 다운로드하기 위한 다음 리포지토리 정보를 추가합니다.  

           <repositories>
             <repository>
               <id>maven-repository.dev.java.net</id>
               <name>Java.net Repository for Maven 1</name>
               <url>http://download.java.net/maven/1/</url>
               <layout>legacy</layout>
             </repository>
             <repository>
               <id>maven2-repository.dev.java.net</id>
               <name>Java.net Repository for Maven 2</name>
               <url>http://download.java.net/maven/2/</url>
             </repository>
           </repositories>  


      이 코드는 Maven 1 및 Maven 2 리포지토리 모두에 대한 정보를 추가합니다. 두 리포지토리에는 몇 가지 JAX-WS 의존 관계가 존재합니다.  

    • 다음과 같이 jaxws-maven-plugin에 대한 플러그인 리포지토리 정보를 pom.xml 파일에 추가합니다.  

         <pluginRepositories>
           <pluginRepository>
             <id>maven2-repository.dev.java.net</id>
             <url>http://download.java.net/maven/2/</url>
           </pluginRepository>
         </pluginRepositories>  

      모든 구성 사양은 상위 프로젝트의 pom.xml 파일에 있기 때문에 하위 프로젝트인 helloservicehelloclient는 구성을 공유합니다.


웹 서비스 구축

  1. helloservice에 로직을 추가합니다  

    • helloservice 프로젝트에서 SourcePackages 노드를 마우스 오른쪽 버튼으로 클릭합니다.
    • New를 선택한 다음 Java Class를 선택합니다.
    • New Java Class 창에서 다음과 같이 지정합니다.  

          - Class Name: Hello
          - Package: com.example.maven.jaxws.helloservice  

    • Finish 버튼을 클릭합니다.
    • Hello 클래스에 대한 소스 코드를 업데이트하여 WebService로 주석을 달고 sayHello를 포함합니다. 업데이트된 소스 코드는 다음과 같아야 합니다.  

         package com.example.maven.jaxws.helloservice;
         import javax.jws.WebService;
         @WebService
         public class Hello {
           public String sayHello(String param) {
           ;  return "Hello " + param;
           }
         }  


  2. SEI 클래스에서 jaxws-maven-plugin:wsgen을 실행합니다.  

    • helloservicepom.xml 파일을 엽니다.
    • pom.xml 파일의 빌드 섹션 아래에 다음 코드를 추가합니다.
       

            <plugins>      
              <plugin>
              <groupId>org.codehaus.mojo&lg;/groupId>
              <artifactId>jaxws-maven-plugin&lg;/artifactId>
                <executions>
                  <execution>
                    <goals>
                      <goal>wsgen</goal>
                    </goals>
                    <configuration>
                    <sei>com.example.maven.jaxws.helloservice.Hello
                    </sei>
                    <!--for demo purpose only, the webapp does not-->
                    <!--need the generated wsdl files-->
                    <genWsdl>true</genWsdl>          
                    <keep>true&lg;/keep>
                    </configuration>
                  </execution>
                </executions>
              </plugin>
            </plugins>
       


    앞에서 언급했듯이 jaxws-maven-plugin:wsgen 작업은 프로세스 클래스 수명 주기 단계 중에 자동으로 호출됩니다. <sei> 요소 값 com.example.maven.jaxws.helloservice.Hello는 작업에 매개변수로 전달됩니다.


웹 서비스 배포

  1. 배포 정보를 지정합니다.  

    • GlassFish나 다른 Java EE 5 컨테이너를 사용하여 웹 서비스를 배포할 경우 "2.5" 버전을 사용하도록 기본 web.xml 파일을 변경합니다. 이를 수행하려면 다음과 같이 합니다.  

          - helloservice 프로젝트에서 Web Pages 노드를 확장합니다.
          - WEB-INF 노드를 확장하고 web.xml 파일을 선택합니다.
          - 소스 편집기 창 상단에 있는 XML 보기 버튼을 눌러 파일의 XML 컨텐츠를 표시합니다.
          - web.xml 파일의 컨텐츠를 다음과 같이 바꿉니다.  

         <web–app version="2.5"
             xmlns="http://java.sun.com/xml/ns/javaee"
             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/web–app_2_5.xsd">
           <welcome–file–list>
           <welcome–file>index.jsp</welcome–file>
           </welcome–file–list>
         </web–app>  

      파일 시작 부분의 <!DOCTYPE> 요소를 반드시 삭제해야 합니다.  

          - 파일을 저장합니다.  


  2. GlassFish에 아티팩트를 배포합니다.  

    • helloservice 프로젝트를 마우스 오른쪽 버튼으로 클릭한 후 Properties를 선택합니다.
    • Run 범주에서 다음과 같이 지정합니다.  

          - Server: GlassFish v2
          - Context Path: /helloservice
          - OK 버튼을 클릭합니다.  

    Display Browser on Run 확인란을 선택하고 Relative URL 필드에 HelloService?wsdl을 입력할 수도 있습니다. 이러한 선택적 사양을 지정할 경우 NetBeans는 helloservice 서비스가 배포된 후 helloservice WSDL을 보여 주는 브라우저를 엽니다.
    설정이 적용되어 helloservicepom.xml 파일은 아티팩트를 GlassFish에 배포하도록 업데이트됩니다.


서비스 실행

  • helloservice를 마우스 오른쪽 버튼으로 클릭하고 Run을 선택합니다.  

    NetBeans에서 Maven이 실행되어 웹 애플리케이션이 빌드되고 GlassFish에 WAR 파일이 자동으로 배포됩니다. NetBeans Output 창에서 진행 과정을 볼 수 있습니다. 서비스의 WSDL에 액세스하여 서비스가 성공적으로 배포되었는지를 확인할 수 있습니다. 이전 단계에서 설명한 대로 Display Browser on Run 확인란을 선택했을 경우 NetBeans는 배포된 웹 서비스의 WSDL을 보여 주는 브라우저를 엽니다. Display Browser on Run 확인란을 선택하지 않았을 경우에는 브라우저에서 http://localhost:8080/helloservice/HelloService?wsdl을 직접 열어서 웹 서비스의 WSDL을 볼 수 있습니다.


클라이언트를 만들어 웹 서비스 호출하기

  1. helloservice WSDL에서 jaxws-maven-plugin:wsimport를 실행합니다.  

    • helloclientpom.xml 파일을 엽니다.
    • pom.xml 파일에 다음 코드를 추가합니다.  

         <build>
           <plugins>
             <plugin>
               <groupId>org.codehaus.mojo</groupId>
                 <artifactId>jaxws-maven-plugin</artifactId>
                 <executions>
                   <execution>
                     <goals>
                       <goal>wsimport</goal>
                     </goals>
                     <configuration>
                       <wsdlUrls>
                         <wsdlUrl>
               http://localhost:8080/helloservice/HelloService?wsdl
                         </wsdlUrl>
                       </wsdlUrls>
                   <packageName>com.example.maven.jaxws.helloclient
                   </packageName>
                     </configuration>
                   </execution>
                 </executions>
             </plugin>
           </plugins>
         <bulid>
     

    jaxws-maven-plugin:wsimport 작업은 수명 주기 단계 생성 소스 중에 실행됩니다. 위의 구성에서 볼 수 있듯이 wsimporthttp://localhost:8080/helloservice/HelloService?wsdl에 있는 WSDL에서 실행되어 com.example.maven.jaxws.helloclient 패키지에 자바 클래스를 생성합니다.  

  2. 클라이언트를 빌드합니다.  

    • helloclient 프로젝트를 마우스 오른쪽 버튼으로 클릭한 후 Build를 선택합니다. Maven은 프로젝트를 빌드하고 wsimport를 실행하여 대상 폴더에 모든 웹 서비스 아티팩트를 생성합니다. 생성된 파일을 보려면 Files 창을 열고 helloclient/target을 확장합니다.
    • helloclient 프로젝트에서 Source packages 노드를 확장하고 com.example.maven.jaxws.helloclient를 마우스 오른쪽 버튼으로 클릭합니다.
    • New를 선택한 다음 Java class를 선택합니다.
    • 클래스 이름을 HelloClient로 지정합니다.
    • Finish 버튼을 클릭합니다.
    • HelloClient 클래스를 다음 소스 코드와 같이 업데이트합니다.  

         package com.example.maven.jaxws.helloclient;
         public class HelloClient {
           public static void main(String[] args) {
           HelloService service = new HelloService();
           Hello port= service.getHelloPort();
           System.out.println(port.sayHello("Duke"));
           }
         }  

  3. NetBeans IDE 액션 "Run"을 연결하여 jar 파일을 빌드하고 HelloClient를 실행합니다.  

    • helloclient를 마우스 오른쪽 버튼으로 클릭하고 Properties를 선택합니다.
    • Run 범주에서 Maincom.example.maven.jaxws.helloclient.HelloClient를 입력합니다.
    • OK 버튼을 클릭합니다.


클라이언트 실행

  • helloclient를 마우스 오른쪽 버튼으로 클릭하고 Run을 선택합니다.  

    Maven은 WSDL 파일에서 wsimport를 실행하고 자바 클래스를 생성한 후 HelloClient를 컴파일하여 실행합니다. NetBeans Output 창에 다음과 같은 웹 서비스 호출 결과가 표시되어야 합니다.  

       Hello Duke

요약

Maven을 사용하여 JAX-WS 기반의 웹 서비스를 손쉽게 만들 수 있습니다. 이 팁에서는 NetBeans를 사용하여 웹 서비스를 생성하는 방법을 설명했지만 NetBeans를 사용하지 않고 Maven을 사용하여 수동으로 JAX-WS 기반의 웹 서비스를 생성할 수도 있습니다. 이렇게 하려면 mvn CLI를 사용하여 pom 파일을 필요한 대로 편집합니다. 그러나 NetBeans를 사용하면 프로젝트에서 Maven을 보다 손쉽게 사용할 수 있으며 구성 구문을 몰라도 간단히 수행할 수 있습니다.

Maven을 사용하여 JAX-WS 기반의 웹 서비스를 작성하는 것에 대한 자세한 내용은 Metro User's Guide를 참조하십시오.


저자 정보

Rama Pulavarthi는 썬마이크로시스템즈 자바 웹 서비스 그룹의 기술 스탭 중 한 명으로서, 현재 JAX-WS 참조 구현 개발에 참여하고 있습니다. 이전에는 JAX-RPC의 소프트웨어 품질 공학 연구를 주도했습니다.

이 글의 영문 원본은
http://blogs.sun.com/enterprisetechtips/entry/using_jax_ws_with_maven
에서 보실 수 있습니다.

Project Sample..(Server)

import java.io.*;

public class HelloWorldService{


 public String HelloWorld(String data)throws Exception
  {
   
   BufferedReader in = new BufferedReader(new FileReader(new File("c:\\temp\\sample.rdf" )));
   String read_data = "";
   String t="";
   while((t =in.readLine()) != null ) read_data += t;
   
   return read_data;
  }
}


서버에 접속이 되게 되면. 파일을 읽어서 그냥 리턴해 주는 역할.

Project Sample..(Client)

import java.net.MalformedURLException;
import java.net.URL;
import java.rmi.RemoteException;
import javax.xml.namespace.QName;
import javax.xml.rpc.ServiceException;
import org.apache.axis.client.Call;
import org.apache.axis.client.Service;

public class HelloWorldClient
{
public static void main(String[] args) throws ServiceException, MalformedURLException, RemoteException
{
Service service = new Service();
Call call = (Call)service.createCall();
call.setTargetEndpointAddress(new URL("http://debianbox:8080/axis/HelloWorldService.jws"));
call.setOperationName(new QName("http://soapinterop.org/", "HelloWorld"));
String returnValue = (String)call.invoke(new Object[]{"My name is okjsp."});
System.out.println(returnValue);
}
}

AXIS User Guide..

Apache AXIS를 이용한 웹서비스




Apache Axis is an implementation of the SOAP ("Simple Object Access Protocol") submission to W3C.

아래의 내용은 중요하므로 기본 개념이 분명이 있어야 한다.
본 강좌()은 사용법을 위주로 아주 기초적인 예제를 다룰것이므로 자세한 내용은 생략한다.

SOAP (Simple Object Access Protocol)
WSDL (Web Service Description Langauge)
WSDD (Web Service Deployment Descriptor)

1. Apache Tomcat 4.1 이상 , Full Version으로 설치

·         톰캣 5.5.4 버젼을 사용하였다. (참고로 Windows환경이다.)
설치후 http://localhost:8080으로 확인해서 동작이 되면 정상이다
.
이것이 톰캣설치의 전부이고, jsp servlet이 동작이되면 준비는 되었다
.
필요에 따라 jdbc등 기타 드라이버를 c:\tomcat\common\lib\ 에 복사 한다.

·         set CATALINA_HOME=c:\tomcat

2. 자바 개발툴킷 설치 : JDK 1.4 버젼 이상이면 된다.

·         참고로 jdk 1.5 버젼을 설치하였다.

·         설치 후에 classpath를 설정한다.
set CLASSPATH=.;c:\jdk15\lib\tools.jar;c:\tomcat\common\lib\servlet-api.jar;
추가적으로 필요한 jdbc 및 기타 라이브러리들을 추가한다.

·         set JAVA_HOME=c:\jdk15
set PATH=c:\jdk15\bin;
을 기존 PATH에 추가한다.

3. ANT 설치 (옵션) : ant에 대해서는 다른 문서나 커뮤니티 사이이트에서 참고할것.

·         http://ant.apache.org에서 ant 1.6.2 버젼을 받아서 설치한다.
설치는 다운 받은 파일을 압축을 풀어서 일정한 디렉토리에 옮겨놓으면 된다.

·         set ANT_HOME=c:\ant
set PATH=c:\ant\bin;
을 기존 PATH에 추가한다.

·         C:\tomcat\server\lib\catalina-ant.jar 파일을 c:\ant\lib\ 디렉토리로 복사한다.

·         추가적으로 junit 이나 xml관련 라이브러리등을 c:\ant\lib\ 에 복사하여 사용하면 된다.

4. AXIS 설치 : http://ws.apache.org/axis/ , http://ws.apache.org/axis/releases.html

·         axis 사이트에서 최신 릴리즈를 다운받아서 압축을 푼후에, 원하는 디렉토리에 옮겨놓으면 된다.
참고로 1.1 final version를 다운 받아서 사용중이다.

·         set AXIS_HOME=c:\axis

·         set AXIS_LIB=%AXIS_HOME%\lib

·         set AXISCLASSPATH=%AXIS_LIB%\axis.jar;%AXIS_LIB%\commons-discovery.jar;
%AXIS_LIB%\commons-logging.jar;%AXIS_LIB%\jaxrpc.jar;%AXIS_LIB%\saaj.jar;
%AXIS_LIB%\log4j-1.2.8.jar;%AXIS_LIB%\xml-apis.jar;%AXIS_LIB%\xercesImpl.jar;
%AXIS_LIB%\wsdl4j.jar

·         set CLASSPATH=%CLASSPATH%;%AXISCLASSPATH% 으로 기존 CLASSPATH 에 추가한다.

·         참고 :
CLASSPATH
에 있는 xml-apis.jar 파일과 xercesImpl.jar 파일은

http://xml.apache.org/
에서 받으면 된다.
또한, 아래에서 보게 될 라이브러리 테스트를 통하여 추가 라이브러리를 확인할수 있고

확인후에 필요한 다운 사이트 정보까지 나오게 되므로 정보를 확인후 다시 설정해주면 된다.

5. axis를 톰캣에 연동하기

·         연동에 있어서 특별한 것은 없고 단지, c:\axis\webapps\axis\ 에서 axis디렉토리를
c:\tomcat\webapps\axis
로 복사하면 된다. , 톰캣 webapps디렉토리에 axis 컨텍스트가
추가 되었다고 이해해도 되겠다.

6. 테스트 해보기

·         톰캣을 실행하고

·         연결테스트를 해본다.
http://localhost:8080/axis

·         라이브러리 테스트
http://localhost:8080/axis/happyaxis.jsp
에서 필요하거나 필수적인 추가 라이브러리를
설치하라는 경고 메시지를 보여주기 때문에 이때 필요한 라이브러리를 다운받아서
c:\tomcat\webapps\axis\lib\
에 복사해주고 다시 테스트를 해본다.
필요에 따라서 다운받은 라이브러리를 CLASSPATH에 설정해주어서 jdk로 컴파일할때 이용하자.

7. SOAP 테스트

·         http://localhost:8080/axis/services/Version?method=getVersion
다음과 같이 출력되면 정상적으로 설치가 된것이다. (내용은 환경에 따라 약간 차이가 난다.)
<?xml version="1.0" encoding="UTF-8" ?>
- <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
- <soapenv:Body>
- <getVersionResponse soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<getVersionReturn xsi:type="xsd:string">Apache Axis version: 1.1 Built on Jun 13, 2003 (09:19:43 EDT)
</getVersionReturn>
</getVersionResponse>
</soapenv:Body>
</soapenv:Envelope>

8. AdminClient 테스트

·         C:\axis\samples\stock 디렉토리로 이동하여 예제로 테스트해보자.

·         java org.apache.axis.client.AdminClient
-lhttp://localhost:8080/axis/services/AdminService deploy.wsdd

·         deploy가 되었는지 확인하고, 에러가 나면 거의 대부분의 원인은 클래스패스에서 나온다.

·         deploy가 제대로 되었는지 확인해보자.
http://localhost:8080/axis/servlet/AxisServlet
아래처럼 추가된 부분이 웹에 보인다면 성공적으로 deploy된것이다
.
urn:xmltoday-delayed-quotes (wsdl)
test
getQuote

9. Client 수행 테스트

·         java samples.stock.GetQuote -lhttp://localhost:8080/axis/servlet/AxisServlet -uuser1 -wpass1 XXX
실행결과가 55.25가 출력되면 성공이다.~~!!!

·         실행시 클래스 패스 오류가 나면 GetQuote.java 파일을 편집기로 열어서 소스 윗부분의
package samples.stock
부분을 지우고 컴파일 하여
java GetQuote -lhttp://localhost:8080/axis/servlet/AxisServlet -uuser1 -wpass1 XXX
실행 해보면 정상적으로 나올것이다.

10. 프로그램 작성 순서

·         서버 Interface와 구현 Class를 작성한후 컴파일 한다.

·         구현 클래스로 부터 WSDL 파일을 생성한다.

·         WSDL 파일로 부터 deploy.wsdd 파일을 생성한다.

·         deploy.wsdd 파일을 이용해서 웹서비스를 deploy하고 server-config.wsdd 파일을 생성 수정한다.

·         구현클래스로 부터 client-side 클래스를 생성한다.

11. 프로그램 작성 플로우

·        

12. 예제 프로그램

·         자바 Interface와 자바 Implement 클래스 작성
c:\test\
에 아래 2개의 파일을 생성한다.

//begin - HelloIF.java
package webservice.hello;
public interface HelloIF extends java.rmi.Remote {
public String hello(java.lang.String name) throws java.rmi.RemoteException;
}
//end - HelloIF.java

//begin - HelloImpl.java
package webservice.hello;
public class HelloImpl implements HelloIF {
public HelloImpl() {
}
public String hello(String name) {
System.out.println(name);
return "hi " + name;
}
}
//end - HelloImpl.java

·         컴파일

javac -d . HelloImpl.java
컴파일 후 c:\test\webservice/hello 디렉토리밑에 HelloImpl.class HelloIF.class가 생성.
생성된 class파일을
C:\Tomcat\webapps\axis\WEB-INF\classes
디렉토리에 패키지 디렉토리를 포함해서 복사한다
.
참고: 컴파일이 되지 않을경우, HelloIF.java파일을 먼저 컴파일한후에
c:\test\webservice/hello
디렉토리에 HelloIF.class파일을 복사해놓고 다시 컴파일 해본다.

·         구현된 클래스로 부터 WSDL 생성 하기

java org.apache.axis.wsdl.Java2WSDL -o c:\test\webservice\hello\Hello.wsdl
-l http://localhost:8080/axis/services/Hello -n http://hello.webservice -pwebservice.hello
http://hello.webservice webservice.hello.HelloIF

Java2WSDL
인자 (http://ws.apache.org/axis/java/reference.html)

인 자

의 미

-o 파일경로

wsdl 생성 위치

-l URL

client가 접속할 URL

-n 네임스페이스

WSDL의 타켓 네임스페이스

-p패키지 네임스페이스

네임스페이스와 네임스페이스 매핑

Target

인터페이스 이름

·        

[
생성된 Hello.wsdl 파일]

<?xml version="1.0" encoding="UTF-8"?>
<wsdl:definitions targetNamespace="http://hello.webservice"
...
...
생략
...
...
<wsdl:service name="HelloIFService">
<wsdl:port name="Hello" binding="impl:HelloSoapBinding">
<wsdlsoap:address location="http://localhost:8080/axis/services/Hello"/>
</wsdl:port>
</wsdl:service>
</wsdl:definitions>

·         WSDL 파일로 부터 deploy.wsdd 파일 생성 및 client-side 자바 클래스 생성

java org.apache.axis.wsdl.WSDL2Java -o c:\test\webservice\hello\
-d Application -s c:\test\webservice\hello\Hello.wsdl

c:\test\webservice\hello
디렉토리 하위에 webservice/hello
새로운 디렉토리가 생성된것을 확인 할수 있다
.
그 디렉토리에 deploy.wsdd 파일과 새롭게 생성된 자바 파일이 존재해야 한다
.
또한, undeploy.wsdd 파일도 생성 된 것을 볼수 있는데 이파일은 서비스를

undeploy
할때 사용한다.

인 자

의 미

-o 디렉토리경로

wsdd 파일과 클래스파일이 생길 디렉토리

-d scope

설치 영역 - Application, Request , Session

-s

wsdd 파일 생성

Target

wsdl 파일 경로

·          

·         [deploy.wsdd 파일 수정]
wsdd
파일은 wsdl 파일만 가지고 생성되었기 때문에 실제 구현클래스가 무엇인지 제대로

설정이 안되어 있으므로 그부분을 수정해 주어야한다
.
붉은색 부분으로 해당 부분을 수정해주면 된다
.

<deployment
xmlns="http://xml.apache.org/axis/wsdd/"
xmlns:java="http://xml.apache.org/axis/wsdd/providers/java">
...
...
생략
...
...
<parameter name="className" value="
webservice.hello.HelloImpl"/>
...
...
생략...
...
<parameter name="allowedMethods" value="hello"/>
<parameter name="scope" value="Application"/>
</service>
</deployment>

·         서비스 디플로이먼트 하기

java org.apache.axis.client.AdminClient -lhttp://localhost:8080/axis/services/AdminService deploy.wsdd

[
디플로이먼트 확인하기
]
http://localhost:8080/axis/servlet/AxisServlet
'Hello'
라는 서비스가 설치된것을 확인할 수 있다.

·         서비스 언디플로이먼트 하기

java org.apache.axis.client.AdminClient -lhttp://localhost:8080/axis/services/AdminService undeploy.wsdd

[
언디플로이먼트 확인하기
]
http://localhost:8080/axis/servlet/AxisServlet
'Hello'
라는 서비스가 삭제 된것을 확인할 수 있다.

13. 클라이언트 구현하기

·         이제 생성된 서비스에 클라이언트로 접근해보는 예제를 생성하고 테스트 해보자.
아래와 같이 작성하고 c:\tomcat\webapps\axis\ 복사한다.

·         [HelloClient.jsp]
<%@ page contentType="text/html; charset=euc-kr" language="java"
import="java.net.MalformedURLException,
java.net.URL,
java.rmi.RemoteException,
javax.xml.namespace.QName,
javax.xml.rpc.ServiceException,
org.apache.axis.client.Call,
org.apache.axis.client.Service" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=euc-kr" />
<title>
웹서비스 테스트 : Hello World!</title>
</head>
<body>
<%
Service service = new Service();
Call call = (Call)service.createCall();
call.setTargetEndpointAddress(new URL("http://localhost:8080/axis/services/Hello?wsdl"));
call.setOperationName(new QName("http://soapinterop.org/", "hello"));
String returnValue = (String)call.invoke(new Object[]{"!
안녕하세요
.^^*"});
out.println(returnValue);
%>
</body>
</html>

·         http://localhost:8080/axis/hello.jsp

hi !
안녕하세요.^^*

·         위에서 처럼 나오면 성공이다. HelloClient.jsp부분하고 차이가 없는것 같지만
"!
안녕하세요" "hi ! 안녕하세요" 차이가 크다.(구현하는 프로그램적으로...)
, hi 라고 출력되어지는 String hello() 웹 메소드를 HelloImpl.class에서 가져와서 실행하는 것이다.

14. 두번째 예제

·         첫번째 방법 외에 빠른 방법이 있다.
자바 파일을 만들고 확장자를 java가 아닌 jws로 바꾸고 실행하는 방법이다
.
참고로 c:\tomcat\webapps\axis\WEB-INF\web.xml를 한번 검토해길 바란다.

·         [ HelloWorldService.jws]

public class HelloWorldService
{
public String HelloWorld(String data)
{
return "Hello World! You sent the string '" + data + "'.";
}
}

·         위의 파일을 c:\tomcat\webapps\axis\ 에 복사하고

http://localhost:8080/axis/HelloWorldService.jws

그 주소에 설치된 서비스가 있다는 HTML 페이지가 나온다. 여기서 더나가 HelloWorld 메서드를 호출해보자.

http://localhost:8080/axis/HelloWorldService.jws?method=HelloWorld&data=Hi+my+name+is+okjsp

메서드를 호출한 결과 XML을 받았다.

·         자바로 클라이언트 구현 하기

[ HelloWorldClient.java]

import java.net.MalformedURLException;
import java.net.URL;
import java.rmi.RemoteException;
import javax.xml.namespace.QName;
import javax.xml.rpc.ServiceException;
import org.apache.axis.client.Call;
import org.apache.axis.client.Service;

public class HelloWorldClient
{
public static void main(String[] args) throws ServiceException, MalformedURLException, RemoteException
{
Service service = new Service();
Call call = (Call)service.createCall();
call.setTargetEndpointAddress(new URL("http://localhost:8080/axis/HelloWorldService.jws"));
call.setOperationName(new QName("http://soapinterop.org/", "HelloWorld"));
String returnValue = (String)call.invoke(new Object[]{"My name is okjsp."});
System.out.println(returnValue);
}
}

·         HelloWorldClient.java 파일을 컴파일 하고 실행 해서 결과를 확인해 본다.
참고로 컴파일 에러가 나는 경우는 라이브러리등이 CLASSPATH에 잡혀있지 않아서 이다
.
본 문서의 처음 부분에 있는 설정 부분을 확인해 보고 다시 시도 해보자.

15. 마치며

XML, SOAP, WSDL, WSDD, UDDI 그리고,
닷넷과 자바...[웹서비스
]...

[참고 사이트 및 자료]
http://www.apache.org
에서 axis 에 포함된 관련 도큐먼트 및 기타 커뮤니티 참조
본 문서는 거의 대부분 인용 한 것 입니다.