1. 번역 : 이동국(fromm0_골뱅이_gmail.com)
  2. 번역시작 : 2005년 03월 17일

<!doctype html public "-//w3c//dtd html 4.0 transitional//ko"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=euc-kr"> <title>Axis 사용자설명서</title> <link href="axis.css" rel=stylesheet type=text/css> </head> <body >

<center> <h1> <img SRC="images/axis.jpg" height=96 width=176></h1></center>

<h1>Axis 사용자설명서</h1> <i>1.2 Version</i> <br><i>내용에 대한 Feedback: <a href="mailto:axis-dev@ws.apache.org">axis-dev@ws.apache.org</a></i> <br><i>번역에 대한 Feedback: <a href="mailto:fromm0@gmail.com">fromm0@gmail.com</a></i>

<h3>목차</h3>

<ul> <li> <a href="#Introduction">소개</a></li> <li> <a href="#Installation">Axis설치하기</a></li> <li> <a href="#ConsumingServices">Axis로 웹서비스 소비하기(consuming)</a></li> <li> <a href="#PublishingServices">Axis로 웹서비스 뱔행하기(Publishing)</a></li> <li> <a href="#DataMapping">Axis에서 XML <-> Java Data 로 맵핑하기</a></li> <li> <a href="#WSDL">Axis로 WSDL사용하기</a></li> <ul><li> <a href="#WSDL: Obtaining WSDL for deployed services">?WSDL: 배치된 서비스를 위한 WSDL획득하기</a></li> <li> <a href="#WSDL2Java: Building stubs, skeletons, and data">WSDL2Java: 스텁(stub), 스켈레톤(skeletons) 그리고 데이터 빌드하기.</a></li> <li> <a href="#Java2WSDL: Building WSDL from Java">Java2WSDL: 자바로 부터 WSDL빌드하기.</a></li> </ul> <li> <a href="#published interfaces">발행된(Published) 인터페이스</a></li> <li> <a href="#newbie">미숙련자를 위한 팁: 당신만의 방법을 찾아라.</a></li> <li> <a href="#tcpmon">부록 : TCPMon사용하기</a></li> <li> <a href="#soapmon">부록 : SOAP 모니터 사용하기</a></li> <li> <a href="#Glossary">해설</a></li> </ul>

<h2> <a NAME="Introduction"></a>소개</h2> Apache SOAP의 세번째 생성물인 Axis는 당신을 환영합니다. <h3> SOAP는 무엇인가.?</h3> SOAP는 애플리케이션간의 통신을 위한 통신프로토콜과 인코딩된 형태를 기반으로 하는 XML이다. 원래는 Microsoft 와 Userland software에 의해 제안되었다. 이것은 다양한 생성을 통해 발전하였고 현재의 스펙인 <a href="http://w3.org/TR/soap">SOAP 1.1</a>에 도달했다. 이것은 인기와 실용성에 의해 굉장히 빨리 성장했다. W3C의 <a href="http://www.w3.org/2000/xp/Group/">XML 프로토콜 작업그룹</a>은 SOAP를 실제의 오픈표준으로 전환할려고 시도중에 있고, SOAP 1.2의 작업초안을 만들고 있다. 이것은 SOAP 1.1버전에서 다소 혼란스러운 부분을 정리하는 버전이다. <p>SOAP은 넓게는 웹서비스의 개념에서 플랫폼에 종속되지 않고 언어에도 종속되지 않는 분산된 애플리케이션의 새로운 생성자를 위한 중추요소처럼 보여진다. <h3> Axis는 무엇인가.?</h3> Axis는 근본적으로 클라이언트, 서버, 게이트웨이같은 SOAP처리자를 생성하기 위한 프레임워크같은 <i>SOAP 엔진</i>이다. Axis의 최근버전은 자바로 쓰여져 있다. 하지만 Axis의 클라이언트측 C++구현물은 개발되어 있다. <p> 하지만 Axis는 다음을 포함하는 SOAP엔진이 아니다. <ul> <li>간단히 혼자 실행되는 서버 <li>톰캣같은 서블릿 엔진에 붙을수 있는 서버 <li><i>웹서비스 배치언어(Web Service Description Language - WSDL)</i>을 위한 확장된 지원, <li>WSDL로부터 자바클래스를 생성하는 배포자기능 <li>몇개의 같은 프로그램과 <li>TCP/IP패키지를 모니터링하기 위한 툴. </ul> <p> Axis는 2000년 말에 IBM의 "SOAP4J"에서 시작하는 Apache SOAP의 세번째 생성물이다. Apache SOAP v2의 커밋터(committers)는 엔진의 좀더 유연하고, 설정하능하고, W3C의 XML프로토콜과 SOAP를 모두 다룰수 있게 하는 방법에 대해 논의하기 시작했다. <p>얼마후 이것은 구조를 다시 만드는것으로 가게 되었다. 많은 v2커밋터는 매우 유연하고 구성할수 있는 방법으로 작은 단위의 기능을 구현하는 "handlers"메시지의 설정가능한 "chains"에 기초를 두는 매우 유사한 디자인을 제안했다. <p>이런 방향으로 지속적인 논의와 코딩노력후에 Axis는 다음의 핵심기능을 가지는 것으로 만들어졌다. <ul> <li> <b>속도.</b> Axis는 Apache SOAP의 기존 버전보다 좀더 빠른 속도를 달성할 수 있는 SAX(이벤트기반의) 파서를 사용한다. </li> <li> <b>유연성.</b> Axis구조는 변경된 헤더처리, 시스템관리 또는 당신이 가정할수 있는 다른것을 위해 엔진으로 확장된것을 추가할수 있는 완벽한 자유를 준다. </li> <li> <b>안정.</b> Axis는 Axis의 나머지에 비교적으로 천천히 비교되는 변경점을 가지는 <a href="#published interfaces">출판된 인터페이스(published interfaces)</a>의 세트를 정의한다. </li> <li> <b>컴포넌트 기반 배치.</b> 당신은 쉽게 당신의 애플리케이션이나 파트너에게 배포하기 위한 프로세스의 공통적인 패턴을 구현하기 위한 핸들러(Handlers)의 재사용가능한 네트워크를 정의한다. </li> <li> <b>프레임워크 옮기기.</b> 우리는 트랜스포트(transports - 예를 들면 SMTP, FTP, 메시지 기반 미들웨어와 같은 다양한 프로토콜위에서 SOAP를 위한 샌더(sender)와 리스너(listener))을 디자인 하기 위해 깔끔하고 간단한 추상화를 가진다. 그리고 엔진의 핵심은 완벽하게 트랜스포트(transport)에 비의존적이다. </li> <li><b>WSDL 지원.</b> Axis는 <a href="http://www.w3.org/TR/wsdl">웹서비스 서술언어(Web Service Description Language)</a> 1.1을 지원한다. 원격서비스에 접근하기 위한 스텁(stub)를 쉽게 빌드하도록 하고 Axis로부터 배치된 서비스의 기계가 읽을수 있는 서술을 자동적으로 보낼수 있다. </li> </ul> <p> 우리는 당신이 Axis를 사용해서 즐기길 바란다. 만약 당신이 이 코드가 새로운 기능이나 문제해결을 한다면 이것을 포함해서 보내달라. Axis개발자 커뮤니티는 당신의 참여를 환영한다. Axis는 <b>A</b>pache E<b>X</b>tensible <b>I</b>nteraction <b>S</b>ystem 를 의미한다. <h4> <b>당신이 생각하는것이 무엇인지 우리에게 알려달라.</b></h4> "<a href="mailto:axis-user@ws.apache.org">axis-user@ws.apache.org</a>"로 그 패키지에 대해서 피드백을 보내달라. 그리고 버그트랙킹 데이터베이스인 <a href="http://nagoya.apache.org/bugzilla">bugzilla</a>에 등록해 달라. <h3>이번 버전에는 무엇이 있는가.?</h3> 이번 버전은 다음을 포함한다. <ul> <li> SOAP 1.1/1.2 호환엔진.</li> <li> 유연한 설정 / 배치 시스템</li> <li> SOAP서비스(JWS)의 "drop-in" 배치를 지원한다. </li> <li> 모든 기본타입과 새로운 직렬자와 역직렬자를 정의하기 위한 타입맵핑시스템을 위한 지원</li> <li> XML요소및 속성에 커스터마이징된 맵핑을 포함하는 자바빈즈의 자동 직렬화와 역직렬화</li> <li> 자바 컬렉션(Collections)과 SOAP 배열(Array)사이에 두가지 방법의 자동변환</li> <li> SOAP서비스에 기반을 둔 RPC와 메시지 지원</li> <li> 배치된 서비스로 부터 WSDL 자동 생성</li> <li> WSDL문서로 부터 자바프록시와 스켈레톤(skeletons)을 위한 WSDL2Java툴</li> <li> 자바 클래스로부터 WSDL을 빌드하기 위한 Java2WSDL툴</li> <li> 서블릿 2.2 보안/롤과 함께 통합될수 있는 사전 준비된 보안 확장</li> <li> HTTP쿠키또는 트랜스포트에 비 의존적인 SOAP헤더를 통해 세션 기반서비스를 지원.</li> <li> <b>SOAP with Attachments</b>스펙을 위한 준비된 지원</li> <li> 웹서비스처럼 EJB에 접근하기 위한 EJB제공</li> <li> 트랜스포트에 기반한 HTTP 서블릿</li> <li> 트랜스포트에 기반한 JMS</li> <li> 서버의 Standalone버전</li> <li> 예를 들면 SoapBuilders커뮤니티 상호운용 테스트와 실험적인 TCP, JMS, 그리고 파일기반 트랜스포트를 위한 클라이언트와 서버를 포함한다. </li> </ul>

<h2> <a NAME="Installation"></a>Axis를 설치하고 설명서를 사용하기.</h2> 당신의 J2EE서버에 웹애플리케이션처럼 Axis를 설치하는 방법을 위해 <a href="install.html">Axis 설치설명서</a>를 보라. <p>이 설명서 안의 예제를 실행시키기 전에 당신은 다음을 포함하는 CLASSPATH를 만들 필요가 있다. <ul> <li>axis-1_1/lib/axis.jar</li> <li>axis-1_1/lib/jaxrpc.jar</li> <li>axis-1_1/lib/saaj.jar</li> <li>axis-1_1/lib/commons-logging.jar</li> <li>axis-1_1/lib/commons-discovery.jar</li> <li>axis-1_1/lib/wsdl4j.jar</li> <li>axis-1_1/ <i><font color="#9966FF">(예제코드를 위해)</font></i></li> <li>Xerces나 Crimson같은 JAXP-1.1 호환 XML파서</li> </ul> <h2> <a NAME="ConsumingServices"></a>Axis로 웹서비스 소비하기(Consuming)</h2>

<h3>기본 - 시작하기</h3> Apache에 Axis서버위에서 <b>echoString</b>메소드를 호출하는 웹서비스 클라이언트 예제를 보자. <pre class="example">1   import org.apache.axis.client.Call; 2   import org.apache.axis.client.Service; 3   import javax.xml.namespace.QName; 4    5   public class TestClient { 6      public static void main(String args) { 7          try { 8              String endpoint = 9                       "http://nagoya.apache.org:5049/axis/services/echo"; 10   11             Service  service = new Service(); 12             Call     call    = (Call) service.createCall(); 13   14             call.setTargetEndpointAddress( new java.net.URL(endpoint) ); 15             call.setOperationName(new QName("<font color="#009933">http://soapinterop.org/</font>", "<font color="#993333">echoString</font>")); 16   17             String ret = (String) call.invoke( new Object { "<font color="#CC00CC">Hello!</font>" } ); 18   19             System.out.println("Sent 'Hello!', got '" + ret + "'"); 20         } catch (Exception e) { 21             System.err.println(e.toString()); 22         } 23     } 24  }</pre> (당신은 <a href="../samples/userguide/example1/TestClient.java">samples/userguide/example1/TestClient.java</a>에서 이 파일을 찾을수 있을 것이다.) <p>당신이 네트워크연결이 활성화 되어 있다고 가정하자. 이 프로그램은 다음처럼 실행할수 있다. <pre class="example">% java samples.userguide.example1.TestClient Sent 'Hello!', got 'Hello!' %</pre> 여기서 무엇이 일어나는가.? 11과 12라인에서 우리는 새로운 서비스와 Call객체를 생성한다. 여기엔 호출할 서비스에 대한 메타데이터를 저장하기 위해 사용되는 표준적인 JAX-RPC객체가 있다. 14라인에서 우리는 우리의 SOAP메시지의 목적지인 endpoint URL을 설정한다. 15라인에서 우리는 웹서비스의 오퍼레이션(메소드) 이름을 정의한다. 그리고 17라인에서 우리는 요구하는 서비스를 호출하고 파라미터배열(이 경우엔 문자열)을 보낸다. <p>당신은 SOAP요청을 봄으로써 그 인자에 어떤일이 발생하는지 볼수 있다. <pre class="xml"><?xml version="1.0" encoding="UTF-8"?> <SOAP-ENV:Envelope xmlns:xsd="http://www.w3.org/2001/XMLSchema"                    xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"                    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">   <SOAP-ENV:Body>     <ns1:<b><font color="#993333">echoString</font></b> xmlns:ns1="<b><font color="#009933">http://soapinterop.org/</font></b>">       <arg0 xsi:type="xsd:string"><b><font color="#CC00CC">Hello!</font></b></arg0>     </ns1:echoString>   </SOAP-ENV:Body> </SOAP-ENV:Envelope></pre> <p>이 문자열 인자는 XML로 자동적으로 직렬화된다. 그리고 서버는 우리가 역직렬화하거 프린트하는 개별적인 문자열로 응답한다. </p> <p><i>주의: SOAP클라이언트와 서버사이에 따라오는 XML을 실질적으로 보기위해서 당신은 <a href="#tcpmon">tcpmon</a> 툴이나 <a href="#soapmon">SOAP monitor</a>를 사용할수 있다. </i></p> <h3>명명 파라미터</h3> 위 예제에서 당신은 SOAP메시지 "arg0", "arg1", 등등내에 XML인코딩 인자를 Axis가 자동적으로 명명하는 것을 볼수 있다. 만약 당신이 이것을 변경하고 싶다면 이것은 쉽다. <tt>invoke()</tt>를 호출하기 전에 각각의 파라미터를 위해 <tt>addParameter</tt>을 호출할 필요가 있다. 그리고 반환을 위해 <tt>setReturnType</tt>을 호출할 필요가 있다. <pre class="example">  call.addParameter("testParam",                      org.apache.axis.Constants.XSD_STRING,                     javax.xml.rpc.ParameterMode.IN);   call.setReturnType(org.apache.axis.Constants.XSD_STRING); </pre> 이것은 call을 호출하는데 첫번째 파라미터로 <b>testParam</b>라는 이름을 할당할것이다. 이것은 파라미터의 타입(<tt>org.apache.axis.Constants.XSD_STRING</tt>)과 그것이 input, output 또는 inout파라미터인지(지금의 경우는 input파라미터이다.)를 정의할 것이다. 지금 당신이 이 프로그램을 실행했다면 나오는 메시지는 다음처럼 보일것이다. <pre class="xml"><?xml version="1.0" encoding="UTF-8"?> <SOAP-ENV:Envelope xmlns:xsd="http://www.w3.org/2001/XMLSchema"                    xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"                    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">   <SOAP-ENV:Body>     <ns1:echoString xmlns:ns1="http://soapinterop.org/">       <<font color="#CC00CC">testParam</font> xsi:type="xsd:string">Hello!</<font color="#CC00CC">testParam</font>>     </ns1:echoString>   </SOAP-ENV:Body> </SOAP-ENV:Envelope></pre> param은 지금 "testParam"이라는 이름으로 되어있다는것에 주의해라. <h3>"untyped" 서버와 상호작동하기</h3> 위의 예에서 우리는 invoke()의 반환타입을 선호하는 "real" 타입으로 형변환할려고 한다. 예를 들면 우리는 client.invoke()로부터 기대할수 있는 것처럼 echoString가 문자열을 반환한다. 우리는 이것이 어떻게 발생하는지와 잠재적인 문제점에 대해서 알아보자. <p>echoString메소드처럼 보이는 전형적인 응답이 여기있다. </p> <pre class="xml"><?xml version="1.0" encoding="UTF-8"?><br> <SOAP-ENV:Envelope xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <SOAP-ENV:Body> <ns1:echoStringResponse xmlns:ns1="http://soapinterop.org/"> <result <font color="#FF0000">xsi:type="xsd:string"</font>>Hello!</result> </ns1:echoStringResponse> </SOAP-ENV:Body> </SOAP-ENV:Envelope></pre> <p><font color="#FF0000">red</font>로 강조된 부분을 보자. 그 속성은 Axis가 요소의 내용을 계산(이 경우엔 자바 문자열객체로 역직렬화하는)해내기 위해 사용하는 스키마 <b>타입선언</b>이다. 많은 툴킷은 "자기서술(self-describing)" 메시지를 만들기 위해서 XML내에 이런 종류의 명백한 타입정보를 둔다. 반면에 어떤 툴킷은 다음처럼 보이는 응답을 반환한다.</p> <pre class="xml"><?xml version="1.0" encoding="UTF-8"?> <SOAP-ENV:Envelope xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <SOAP-ENV:Body> <ns1:echoStringResponse xmlns:ns1="http://soapinterop.org/"> <result>Hello, I'm a string!</result> </ns1:echoStringResponse> </SOAP-ENV:Body> </SOAP-ENV:Envelope></pre> <p>이 메시지에는 어떠한 타입도 없다. 그러면 우리는 <result> 요소로 역직렬화되는 자바객체가 무엇인지 어떻게 아는가.? 그 답은 <b>metadata</b>(-데이터에 대한 데이터)이다. 이 경우에 우리는 기대되는 반환타입을 우리에게 말해주는 서비스의 <b>description</b>이 필요하다. Axis에서 클라이언트측에서 어떻게 해야하는지 보여주는것이 여기 있다. </p> <pre class="example">  call.setReturnType( org.apache.axis.Constants.XSD_STRING );</pre> <p>이 메소드는 만약 반환요소가 형태가 정의되어 있지 않다면 반환값이 미리정의된 SOAP문자열타입으로 셋팅되는 xsi:type속성셋을 가지는것처럼 작동할것이다라는것을 Axis클라이언트에게 말한다. (당신은 상호작동하는 echo-test클라이언트 - 예를 들면 sample/echo/TestClient.java 에서 이런 작동을 볼수 있다.)</p> <p>여기에 당신이 기대되는 반환타입의 자바클래스로 정의하도록 하는 유사한 메소드가 있다. </p> <pre class="example">call.setReturnClass(String.class);</pre> <p>OK - 당신은 클라이언트처럼 SOAP서비스에 접근하는 기본을 안다. 하지만 당신은 어떻게 자신만의 서비스를 배포하는가.? <h2> <a NAME="PublishingServices"></a>Publishing Web Services with Axis</h2> Let's say we have a simple class like the following: <pre class="example">public class Calculator {   public int add(int i1, int i2)   {     return i1 + i2;    }      public int subtract(int i1, int i2)   {     return i1 - i2;   } }</pre> (당신은 이 클래스를 <a href="../samples/userguide/example2/Calculator.java">samples/userguide/example2/Calculator.java</a>에서 찾을수 있을것이다.) <p>SOAP를 통해 유효한 이 클래스를 어떻게 만들까.? 이 물음에 대해 두가지 답변이 있지만 우리는 이것을 하기 위해 Axis가 제공하는 어떤 수고도 거의 필요없는 가장 쉬운방법으로 시작할것이다. <h3> JWS (Java Web Service) 파일들 - 즉석 배치</h3> 좋다.이것은 1단계이다. .java파일을 당신의 웹애플리케이션 디렉토리에 복사하고 Calculator.jws라는 이름으로 변경해라. 아마 당신은 다음과 같은 명령어를 실행할것이다. <pre>% copy Calculator.java <i><font color="#0000FF"><your-webapp-root></font></i>/axis/Calculator.jws</pre> 이제 2단계. 잠시기다려라. 당신은 다 했다. 당신은 다음의 URL로 서비스에 접근(여기서는 당신이 Axis를 8080포트에서 실행중이라고 가정한다)할수 있을것이다. <p><a href="http://localhost:8080/axis/Calculator.jws">http://localhost:8080/axis/Calculator.jws</a> <p>Axis는 자동적으로 파일을 위치시키고 클래스를 컴파일한다. 그리고 SOAP호출을 당신의 서비스 클래스의 자바 호출로 변환한다. 해보라. calculator클라이언트는 samples/userguide/example2/CalcClient.java에 있다. 아마 다음처럼 할수 있을것이다. <pre class="example">% java samples.userguide.example2.CalcClient -p8080 add 2 5 Got result : 7 % java samples.userguide.example2.CalcClient -p8080 subtract 10 9 Got result : 1 %</pre> ("-p8080"를 당신의 J2EE서버가 실행중인 포트로 변경할 필요가 있다는것에 주의하라.) <p> <i><b>중요:</b></i> JWS웹서비스는 간단한 웹서비스에 사용되는 경향이 있다. 당신은 이 페이지에서 패키지를 사용할수 없고 이 코드는 실시간으로 컴파일이 되기 때문에 배치 이후까지 에러에 대해서 찾아볼수 없다. 제품품질의 웹서비스는 커스텀배치와 함께 자바 클래스를 사용해야만 한다.

<h3>커스텀 배치 - WSDD소개하기</h3> JWS파일은 웹서비스처럼 당신의 클래스를 가져다 놓을수 있는 가장 빠른 방법이다. 하지만 이것이 가장 좋은 선택은 아니다. 하나는 당신이 소소코드가 필요하다(- 이는 소스없이 당신의 시스템에 이미 존재하는 클래스를 노출시키길 원하는 때이다.). 또는 접근하는 서비스가 어떤 제약을 가지는 것처럼 상당한 설정을 가질때 당신은 타입맵핑을 정의할수 없거나 사람들이 당신의 서비스를 사용할때 호출되는 핸들러를 제어할수 없다. </i> <h4> <a NAME="descriptors"></a>서술자를 통해 배치하기 </h4> <p>Axisㅇ서 당신을 위해 유효한 유연성을 사용하기 위해서 당신은 Axis <b>웹서비스 배치서술자(WSDD)</b>포맷과 친숙해져야 한다. 배치서술자는 당신이 Axis에 "배치"하고자 하는 꾸러미들을 포함한다. 배치하기위한 가장 공통적인것은 웹서비스이고 기본적인 서비스를 위해 배치서술자를 봄으로써 시작하자. (이 파일은 <a href="../samples/userguide/example3/deploy.wsdd">samples/userguide/example3/deploy.wsdd</a>이다.):</p> <pre class="example"><deployment xmlns="http://xml.apache.org/axis/wsdd/"             xmlns:java="http://xml.apache.org/axis/wsdd/providers/java">  <service name="MyService" provider="java:RPC">   <parameter name="className" value="samples.userguide.example3.MyService"/>   <parameter name="allowedMethods" value="*"/>  </service> </deployment></pre> 다소 간단하다. 가장 바깥의 요소는 WSDD deployment라고 엔진에게 말하고 "java"네임스페이스를 정의한다. 그 다음 service요소는 우리를 위한 서비스를 정의한다. 서비스는 요청 흐름(request flow), ("provider"라 불리는 service를 위한) 회전축 핸들러(pivot handler) 그리고 응답 흐름(response flow)의 어떤것이나 모든것을 의미하는 <b>목표된 체인(targeted chain)</b>이다. (<a href="architecture-guide.html">아키텍쳐 가이드</a>를 보라.). 이 경우에 우리의 프로바이더는 Axis에 내장되어 있고 자바 RPC서비스를 지향하는 "java:RPC"이다. 이것을 다루는 실제 클래스는 <b>org.apache.axis.providers.java.RPCProvider</b>이다. 우리는 서비스의 다른 스타일과 그들의 프로바이더에서 좀더 상세한 정보를 보게 될것이다. <p>우리는 초기화하고 <parameter> 태그들을 포함하고 클래스이름을 설정하기 위해 서비스에 하나의 파라미터를 주고 SOAP에 의해 호출("*"이 의미하는것은 우리는 유효한 메소드이름의 공백이나 콤마로 구분된 목록을 사용함으로써 SOAP접근가능한 메소드를 제한할수 있습니다.)되는 클래스의 어느 public메소드를 엔진에게 알림으로써 올바른 클래스(예를 들면 samples.userguide.example3.MyService)를 호출하는 것을 RPCProvider에게 알릴필요가 있다. <h4>향상된 WSDD - 좀더 다양한 옵션 명시하기</h4> <p>WSDD서술자는 서비스에 대한 다른 정보를 포함할수도 있고 "Handlers"라고 불리는 Axis의 다른 부분도 포함할수 있다. <h5>범위지정 서비스(Scoped Services)</h5> <p>Axis는 3가지 방법으로 범위지정 서비스객체(당신의 메소드를 구현하는 실제 자바객체)를 지원한다. "Request" 범위는 초기설정 기본값으로 당신의 서비스를 위해 들어오는 매번 SOAP요청에 새로운 객체를 생성할것이다. "Application" 범위는 <b>모든</b> 서비스 요청을 위한 하나의 공유객체를 생성할것이다. "Session" 범위는 당신의 서비스를 접근하는 세션가능한 클라이언트에 새로운 객체를 생성할것이다. 이 범위옵션을 명시하기 위해서 당신은 다음("<i><font color="#FF0000">value</font></i>" 가 request, session, 또는 application)처럼 당신의 서비스에 <parameter>를 추가한다. </p> <pre class="xml"><service name="MyService"...> <parameter name="scope" value="<font color="#FF0000"><i>value</i></font>"/> ... </service></pre> <h4>AdminClient 사용하기</h4> 우리가 이 파일을 가진다면 우리는 실제로 서술된 서비스를 배치하기 위해서 Axis서버에 그것을 보낼필요가 있다. 우리는 AdminClient, 또는 "org.apache.axis.client.AdminClient" 클래스를 가지고 수행한다. 만약 당신이 톰캣이 아닌 다른 서버에 Axis가 배치되었다면 당신은 -p <em><port></em>인자를 사용할 필요가 있다. 초기설정 포트는 8080이다. AdminClient의 전형적인 호출은 다음과 같다. <pre class="example">% java org.apache.axis.client.AdminClient deploy.wsdd <Admin>Done processing</Admin></pre> 이 명령은 SOAP를 통해 우리에게 서비스 접근가능하도록 해준다. Client 클래스를 실행함으로써 체크해보라. 그것은 다음과 같다. <pre class="example">% java samples.userguide.example3.Client -lhttp://localhost:8080/axis/services/MyService "test me!" You typed : test me! %</pre> 만약 당신이 배치가 실제로 작동하는지 스스로 입증하길 원한다면 배치된 서비스를 내리고 다시 해보라. deploy.wsdd파일을 사용할 수 있는 example3/ 디렉토리에 "undeploy.wsdd"파일이 있다. AdminClient를 실행시켜라. 그 다음 서비스 Client를 시도하고 무엇이 발생하는지 보라. <p>당신은 서버에 배치된 컴포넌트의 모든 목록을 얻기위해서 AdminClient를 사용할수 있다. <pre class="example">% java org.apache.axis.client.AdminClient list <big XML document returned here></pre> 당신은 서비스(services), 핸들러(handlers), 트랜스포트(transports) 등등을 볼것이다. 이 목록은 서버의 "server-config.wsdd"파일의 복사본이다. 나중에 좀더 다양한 상세정보를 볼것이다. <h4>상세한 배치 - 핸들러와 체인(Handlers and Chains)</h4> 지금 Axis엔진의 좀더 강력한 기능 몇가지를 보기 시작하자. 당신의 서비스가 얼마나 많이 호출되는지 추적하길 원한다고 하자. 우리는 이것을 수행하기 위해 samples/log 디렉토리에 샘플 핸들러를 포함한다. 이것처럼 핸들러 클래스를 사용하기 위해서 당신은 핸들러를 배치할 필요가 있다. 그리고 배치한 서비스내에 준 이름을 사용한다. 여기에 샘플 deploy.wsdd파일이 있다. (이것은 samples/userguide의 example 4이다.) <pre class="example"><deployment xmlns="http://xml.apache.org/axis/wsdd/"             xmlns:java="http://xml.apache.org/axis/wsdd/providers/java">   <!-- define the logging handler configuration -->  <handler name="track" type="java:samples.userguide.example4.LogHandler">   <parameter name="filename" value="MyService.log"/>  </handler>    <!-- define the service, using the log handler we just defined -->  <service name="LogTestService"<b> </b>provider="java:RPC">   <requestFlow>    <handler type="track"/>   </requestFlow>     <parameter name="className" value="samples.userguide.example4.Service"/>   <parameter name="allowedMethods" value="*"/>  </service> </deployment></pre> <p> The first section defines a Handler called "track" that is implemented by the class samples.userguide.example4.LogHandler. We give this Handler an option to let it know which file to write its messages into. <p>Then we define a service, LogTestService, which is an RPC service just like we saw above in our first example. The difference is the <requestFlow> element inside the <service> - this indicates a set of Handlers that should be invoked when the service is invoked, before the provider. By inserting a reference to "track", we ensure that the message will be logged each time this service is invoked. <h4> Remote Administration</h4> Note that by default, the Axis server is configured to only accept administration requests from the machine on which it resides - if you wish to enable remote administration, you must set the "enableRemoteAdmin" property of the AdminService to <b>true</b>. To do this, find the "server-config.wsdd" file in your webapp's WEB-INF directory. In it, you'll see a deployment for the AdminService. Add an option as follows: <pre class="xml"><service name="AdminService" provider="java:MSG">   <parameter name="className" value="org.apache.axis.util.Admin"/>   <parameter name="allowedMethods" value="*"/>   <b><parameter name="enableRemoteAdmin" value="true"/> </b></service></pre> <p><b>WARNING: enabling remote administration may give unauthorized parties access to your machine. If you do this, please make sure to add security to your configuration!</b> <h3>Service Styles - RPC, Document, Wrapped, and Message</h3> <p>There are four "styles" of service in Axis. <b>RPC</b> services use the SOAP RPC conventions, and also the SOAP "section 5" encoding. <b>Document</b> services do not use any encoding (so in particular, you won't see multiref object serialization or SOAP-style arrays on the wire) but DO still do XML<->Java databinding. <b>Wrapped</b> services are just like document services, except that rather than binding the entire SOAP body into one big structure, they "unwrap" it into individual parameters. <b>Message</b> services receive and return arbitrary XML in the SOAP Envelope without any type mapping / data binding. If you want to work with the raw XML of the incoming and outgoing SOAP Envelopes, write a message service.</p> <h4>RPC services</h4> RPC services are the default in Axis. They are what you get when you deploy services with <service ... provider="java:RPC"> or <service ... style="RPC">. RPC services follow the SOAP RPC and encoding rules, which means that the XML for an RPC service will look like the "echoString" example above - each RPC invocation is modeled as an outer element which matches the operation name, containing inner elements each of which maps to a parameter of the operation. Axis will deserialize XML into Java objects which can be fed to your service, and will serialize the returned Java object(s) from your service back into XML. Since RPC services default to the soap section 5 encoding rules, objects will be encoded via "multi-ref" serialization, which allows object graphs to be encoded. (See the SOAP spec for more on multi-ref serialization.) <h4>Document / Wrapped services </h4> <p>Document services and wrapped services are similar in that neither uses the SOAP encoding for data; it's just plain old XML schema. In both cases, however, Axis still "binds" Java representations to the XML (see the <a href="#DataMapping">databinding</a> section for more), so you end up dealing with Java objects, not directly with XML constructs.</p> <p>A good place to start in describing the difference between document and wrapped services is with a sample SOAP message containing a purchase order:</p> <pre class="xml"><soap:Envelope xmlns="http://xml.apache.org/axis/wsdd/"             xmlns:java="http://xml.apache.org/axis/wsdd/providers/java"> <soap:Body> <myNS:PurchaseOrder xmlns:myNS="http://commerce.com/PO"> <item>SK001</item> <quantity>1</quantity> <description>Sushi Knife</description> </myNS:PurchaseOrder> </soap:Body> </soap:Envelope> </pre> <p>The relevant schema for the PurchaseOrder looks like this:</p> <pre class="xml"><schema targetNamespace="http://commerce.com/PO"> <complexType name="POType"> <sequence> <element name="item" type="xsd:string"/> <element name="quantity" type="xsd:int"/> <element name="description" type="xsd:string"/> </sequence> </complexType> <element name="PurchaseOrder" type="POType"/> </deployment></pre> <p>For a <b>document</b> style service, this would map to a method like this:</p> <p class="example">public void method(PurchaseOrder po)</p> <p>In other words, the ENTIRE <PurchaseOrder> element would be handed to your method as a single bean with three fields inside it. On the other hand, for a <b>wrapped</b> style service, it would map to a method like this:</p> <p class="example">public void purchaseOrder(String item, int quantity, String description)</p> <p>Note that in the "wrapped" case, the <PurchaseOrder> element is a "wrapper" (hence the name) which only serves to indicate the correct operation. The arguments to our method are what we find when we "unwrap" the outer element and take each of the inner ones as a parameter.</p> <p>The document or wrapped style is indicated in WSDD as follows:</p> <p><span class="example"><service ... style="document"></span> for document style<br> <span class="example"><service ... style="wrapped"></span> for wrapped style</p> <p>In most cases you won't need to worry about document or wrapped services if you are starting from a WSDL document (<a href="#WSDL">see below</a>).</p> <h4>Message services</h4> <p>Finally, we arrive at "Message" style services, which should be used when you want Axis to step back and let your code at the actual XML instead of turning it into Java objects. There are four valid signatures for your message-style service methods:</p> <p><code>public Element method(Element bodies);</code><code><br> public SOAPBodyElement method (SOAPBodyElement bodies);</code><code><br> public Document method(Document body);<br> public void method(SOAPEnvelope req, SOAPEnvelope resp);</code> </p> <p>The first two will pass your method arrays of either DOM Elements or SOAPBodyElements - the arrays will contain one element for each XML element inside the <soap:body> in the envelope.</p> <p>The third signature will pass you a DOM Document representing the <soap:body>, and expects the same in return.</p> <p>The fourth signature passes you two SOAPEnvelope objects representing the request and response messages. This is the signature to use if you need to look at or modify headers in your service method. Whatever you put into the response envelope will automatically be sent back to the caller when you return. Note that the response envelope may already contain headers which have been inserted by other Handlers.</p> <p><b>Message Example</b></p> <p>A sample message service can be found in <a href="../samples/message/MessageService.java">samples/message/MessageService.java</a>. The service class, <code>MessageService</code>, has one public method, <code>echoElements</code>, which matches the first of the three method signatures above:</p> <pre class="example">public Element echoElements(Element elems) </pre> <p>The <code>MsgProvider</code> handler calls the method with an array<code></code> of <code>org.w3c.dom.Element</code> objects that correspond to the immediate children of the incoming message's SOAP Body. Often, this array will contain a single Element (perhaps the root element of some XML document conforming to some agreed-upon schema), but the SOAP Body can handle any number of children. The method returns an <code>Element</code> array to be returned in the SOAP body of the response message.</p> <p>Message services must be deployed with a WSDD file. Here is the full WSDD for the <code>MessageService</code> class:</p> <pre class="XML"> <deployment name="test" xmlns="http://xml.apache.org/axis/wsdd/" xmlns:java="http://xml.apache.org/axis/wsdd/providers/java" xmlns:xsi="http://www.w3.org/2000/10/XMLSchema-instance"> <service name="MessageService" <font color="#FF0000">style="message"</font>> <parameter name="className" value="samples.message.MessageService"/> <parameter name="allowedMethods" value="echoElements"/> </service><br></deployment></pre> <p>Note that the "style" attribute is different from the RPC deployment example. The "message" style tells Axis that this service is to be handled by <code>org.apache.axis.providers.java.MsgProvider</code> rather than <code>org.apache.axis.providers.java.RPCProvider</code>. </p> <p>You can test this service by deploying it, then running samples.message.TestMsg (look at the source to see what the test driver does).</p> <h2><a NAME="DataMapping"></a>XML <-> Java Data Mapping in Axis</h2> <h3>How your Java types map to SOAP/XML types</h3>

Interoperability, <i>interop</i>, is an ongoing challenge between SOAP implementations. If you want your service to work with other platforms and implementations, you do need to understand the issues. There are some <a href="reading.html#interop">external articles</a> on the subject that act as a good starting place. The basic mapping between Java types and WSDL/XSD/SOAP in Axis is determined by the JAX-RPC specification. Read chapters 4 and 5 of the <a href="http://java.sun.com/xml/jaxrpc/"> specification</a> to fully understand how things are converted. Here are some of the salient points.

<h4>Standard mappings from WSDL to Java</h4> <table> <tr><td>xsd:base64Binary </td><td><tt>byte</tt></td></tr> <tr><td>xsd:boolean </td><td><tt>boolean</tt></td></tr> <tr><td>xsd:byte </td><td><tt>byte</tt></td></tr> <tr><td>xsd:dateTime </td><td><tt>java.util.Calendar</tt></td></tr> <tr><td>xsd:decimal </td><td><tt>java.math.BigDecimal</tt></td></tr> <tr><td>xsd:double </td><td><tt>double</tt></td></tr> <tr><td>xsd:float </td><td><tt>float</tt></td></tr> <tr><td>xsd:hexBinary </td><td><tt>byte</tt></td></tr> <tr><td>xsd:int</td><td><tt> int</tt></td></tr> <tr><td>xsd:integer</td><td><tt>java.math.BigInteger</tt></td></tr> <tr><td>xsd:long </td><td><tt>long</tt></td></tr> <tr><td>xsd:QName </td><td><tt>javax.xml.namespace.QName</tt></td></tr> <tr><td>xsd:short </td><td><tt>short</tt></td></tr> <tr><td>xsd:string</td><td><tt>java.lang.String</tt></td></tr> </table> <p> If the WSDL says that an object can be <tt>nillable</tt>, that is the caller may choose to return a value of <tt>nil</tt>, then the primitive data types are replaced by their wrapper classes, such as Byte, Double, Boolean, etc. <h4>SOAP Encoding Datatypes</h4> <p> Alongside the XSD datatypes are the SOAP 'Section 5' datatypes that are all nillable, and so only ever map to the wrapper classes. These types exist because they all support the "ID" and "HREF" attributes, and so will be used when in an RPC-encoded context to support multi-ref serialization. <h3>Exceptions</h3>

This is an area which causes plenty of confusion, and indeed, the author of this section is not entirely sure how everything works, especially from an interop perspective. This means treat this section as incomplete and potentially inaccurate. See also section 5.5.5 and chapter 14 in the JAX-RPC specification

<h4>RemoteExceptions map to SOAP Faults</h4>

If the server method throws a <tt>java.rmi.RemoteException</tt> then this will be mapped into a SOAP Fault. The <tt>faultcode</tt> of this will contain the classname of the fault. The recipient is expected to deserialize the body of the fault against the classname.

<p>

Obviously, if the recipient does not know how to create an instance of the received fault, this mechanism does not work. Unless you include information about the exception class in the WSDL description of the service, or sender and receiver share the implementation, you can only reliably throw <tt>java.rmi.RemoteException</tt> instances, rather than subclasses.

<p>

When an implementation in another language receives such an exception, it should see the name of the class as the faultCode, but still be left to parse the body of the exception. You need to experiment to find out what happens there.

<h4>Exceptions are represented as <tt>wsdl:fault</tt> elements</h4> If a method is marked as throwing an <tt>Exception</tt> that is not an instance or a subclass of <tt>java.rmi.RemoteException</tt>, then things are subtly different. The exception is no longer a SOAP Fault, but described as a <tt>wsdl:fault</tt> in the WSDL of the method.

According to the JAX-RPC specification, your subclass of Exception must have accessor methods to access all the fields in the object to be marshalled <i>and</i> a constructor that takes as parameters all the same fields (i.e, arguments of the same name and type). This is a kind of immutable variant of a normal <a href="http://java.sun.com/products/javabeans">JavaBean</a>. The fields in the object must be of the datatypes that can be reliably mapped into WSDL.

<p>

If your exception meets this specification, then the WSDL describing the method will describe the exception too, enabling callers to create stub implementations of the exception, regardless of platform.

<p>

Again, to be sure of interoperability, you need to be experiment a bit. Remember, the calling language may not have the notion of Exceptions, or at least not be as rigorous as Java in the rules as to how exceptions must be handled.

<h3>What Axis can send via SOAP with restricted Interoperability</h3>

<h5>Unsigned data</h5>

You cannot consume or generate services that use unsigned datatypes with pure JAX-RPC, because there are no unsigned dataypes in Java. <p> Axis does have support for the unsigned types, so you can consume services written in C++, C# and the like, and re-implement interfaces designed for those languages. Be very wary about exporting unsigned datatypes, however, as to do so will stop Java clients that do not use Axis or another SOAP client library with unsigned support from using them. The current JAX-RPC specification does not address this issue.

<h5>Java Collections</h5>

Some of the Collection classes, such as <tt>Hashtable</tt>, do have serializers, but there is no formal interoperability with other SOAP implementations, and nothing in the SOAP specifications which covers complex objects. The most reliable way to send aggregate objects is to use arrays. In particular, .NET cannot handle them, though many Java SOAP implementations can marshall and unmarshall hash tables.

<h3>What Axis can not send via SOAP</h3>

<h5>Arbitrary Objects without Pre-Registration</h5>

You cannot send arbitrary Java objects over the wire and expect them to be understood at the far end. With RMI you can send and receive <tt>Serializable</tt> Java objects, but that is because you are running Java at both ends. <b>Axis will only send objects for which there is a registered Axis serializer.</b> This document shows below how to use the BeanSerializer to serialize any class that follows the JavaBean pattern of accessor and mutator. To serve up objects you must either register your classes with this BeanSerializer, or there must be serialization support built in to Axis.

Remote References

Remote references are neither part of the SOAP specification, nor the JAX-RPC specification. You cannot return some object reference and expect the caller to be able to use it as an endpoint for SOAP calls or as a parameter in other calls. Instead you must use some other reference mechanism, such as storing them in a <tt>HashMap</tt> with numeric or string keys that can be passed over the wire.

<h3>Encoding Your Beans - the BeanSerializer</h3> Axis includes the ability to serialize/deserialize, without writing any code, arbitrary Java classes which follow the standard <a href="http://java.sun.com/products/javabeans">JavaBean</a> pattern of get/set accessors. All you need to do is tell Axis which Java classes map to which XML Schema types. Configuring a bean mapping looks like this: <pre class="xml"><beanMapping qname="ns:local" xmlns:ns="someNamespace"              languageSpecificType="java:my.java.thingy"/></pre> The <beanMapping> tag maps a Java class (presumably a bean) to an XML QName. You'll note that it has two important attributes, <b>qname</b> and <b>languageSpecificType</b>. So in this case, we'd be mapping the "my.java.thingy" class to the XML QName someNamespace:local. <p>Let's take a look at how this works in practice. Go look at <a href="../samples/userguide/example5/BeanService.java">samples/userguide/example5/BeanService.java</a>. The key thing to notice is that the argument to the service method is an Order object. Since Order is not a basic type which Axis understands by default, trying to run this service without a type mapping will result in a fault. (If you want to try this for yourself, you can use the bad-deploy.wsdd file in the example5 directory.) But if we put a beanMapping into our deployment, all will be well. Here's how to run this example (from the example5 directory): <pre class="example">% java org.apache.axis.client.AdminClient -llocal:///AdminService deploy.wsdd <Admin>Done processing</Admin>

% java samples.userguide.example5.Client -llocal:// Hi, Glen Daniels!

You seem to have ordered the following:

1 of item : mp3jukebox 4 of item : 1600mahBattery

If this had been a real order processing system, we'd probably have charged you about now. %

</pre>

<h3> When Beans Are Not Enough - Custom Serialization</h3> Just as JWS deployment is sometimes not flexible enough to meet all needs, the default bean serialization model isn't robust enough to handle every case either. At times there will be non-bean Java classes (especially in the case of pre-existing assets) which you need to map to/from XML, and there also may be some custom XML schema types which you want to map into Java in particular ways. Axis gives you the ability to write custom serializers/deserializers, and some tools to help make your life easier when you do so. <p><i><font color="#FF0000">TBD - this section will be expanded in a future version! For now look at the DataSer/DataDeser classes (in samples/encoding). Also look at the BeanSerializer, BeanDeserializer, ArraySerializer, ArrayDeserializer and other classes in the org.apache.axis.encoding.ser package. </font></i> <h4> Deploying custom mappings - the <typeMapping> tag</h4> Now that you've built your serializers and deserializers, you need to tell Axis which types they should be used for. You do this with a typeMapping tag in WSDD, which looks like this: <pre class="xml"><typeMapping qname="ns:local" xmlns:ns="someNamespace"              languageSpecificType="java:my.java.thingy"              serializer="my.java.Serializer"              deserializer="my.java.DeserializerFactory"              encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/></pre> <p>This looks a lot like the <beanMapping> tag we saw earlier, but there are three extra attributes. One, <b>serializer</b>, is the Java class name of the Serializer <i>factory</i> which gets the serializer to be used to marshal an object of the specified Java class (i.e., my.java.thingy) into XML. Another, <b>deserializer</b>, is the class name of a Deserializer <i>factory</i> that gets the deserializer to be used to unmarshall XML into the correct Java class. The final attribute, the <b>encodingStyle</b>, which is SOAP encoding. <p>(The <beanMapping> tag is really just shorthand for a <typeMapping> tag with <tt>serializer="org.apache.axis.encoding.ser.BeanSerializerFactory"</tt>, <tt>deserializer="org.apache.axis.encoding.ser.BeanDeserializerFactory"</tt>, and <tt>encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"</tt>, but clearly it can save a lot of typing!) <h2> <a NAME="WSDL"></a>Using WSDL with Axis</h2> The <a href="http://www.w3.org/TR/wsdl">Web Service Description Language</a> is a specification authored by IBM and Microsoft, and supported by many other organizations. WSDL serves to describe Web Services in a structured way. A WSDL description of a service tells us, in a machine-understandable way, the interface to the service, the data types it uses, and where the service is located. Please see the spec (follow the link in the first sentence) for details about WSDL's format and options. <p>Axis supports WSDL in three ways: <ol> <li> When you deploy a service in Axis, users may then access your service's URL with a standard web browser and by appending "?WSDL" to the end of the URL, they will obtain an automatically-generated WSDL document which describes your service.</li>

<li> We provide a "WSDL2Java" tool which will build Java proxies and skeletons for services with WSDL descriptions.</li>

<li> We provide a "Java2WSDL" tool which will build WSDL from Java classes.</li> </ol>

<h3> <a NAME="WSDL: Obtaining WSDL for deployed services"></a>?WSDL: Obtaining WSDL for deployed services</h3> When you make a service available using Axis, there is typically a unique URL associated with that service. For JWS files, that URL is simply the path to the JWS file itself. For non-JWS services, this is usually the URL "http://<host>/axis/services/<service-name>". <p>If you access the service URL in a browser, you'll see a message indicating that the endpoint is an Axis service, and that you should usually access it using SOAP. However, if you tack on "?wsdl" to the end of the URL, Axis will automatically generate a service description for the deployed service, and return it as XML in your browser (try it!). The resulting description may be saved or used as input to proxy-generation, described next. You can give the WSDL-generation URL to your online partners, and they'll be able to use it to access your service with toolkits like .NET, SOAP::Lite, or any other software which supports using WSDL. <p>You can also generate WSDL files from existing Java classes (see <a href="#Java2WSDL: Building WSDL from Java">Java2WSDL: Building WSDL from Java</a> ). <br>  <h3><a NAME="WSDL2Java: Building stubs, skeletons, and data"></a>WSDL2Java: Building stubs, skeletons, and data types from WSDL</h3>

<h4>Client-side bindings</h4> <p>You'll find the Axis WSDL-to-Java tool in "org.apache.axis.wsdl.WSDL2Java". The basic invocation form looks like this:</p> <pre class="example"> % java org.apache.axis.wsdl.WSDL2Java (WSDL-file-URL) </pre>

<p>This will generate only those bindings necessary for the client.  Axis follows the JAX-RPC specification when generating Java client bindings from WSDL.  For this discussion, assume we executed the following:</p> <pre class="example"> % cd samples/addr % java org.apache.axis.wsdl.WSDL2Java AddressBook.wsdl </pre> <p>The generated files will reside in the directory "AddressFetcher2".  They are put here because that is the target namespace from the WSDL and namespaces map to Java packages.  Namespaces will be discussed in detail later.</p> <table BORDER COLS=2 WIDTH="100%" > <tr> <td><b>WSDL clause</b></td>

<td><b>Java class(es) generated</b></td> </tr>

<tr> <td>For each entry in the type section</td>

<td>A java class</td> </tr>

<tr> <td></td>

<td>A holder if this type is used as an inout/out parameter</td> </tr>

<tr> <td>For each portType</td>

<td>A java interface</td> </tr>

<tr> <td>For each binding</td>

<td>A stub class</td> </tr>

<tr> <td>For each service</td>

<td>A service interface</td> </tr>

<tr> <td></td>

<td>A service implementation (the locator)</td> </tr> </table>

There is an <a href="ant/axis-wsdl2java.html">Ant Task</a> to integrate this action with an Ant based build process.

<h4>Types</h4> <p>The Java class generated from a WSDL type will be named from the WSDL type.  This class will typically, though not always, be a bean.  For example, given the WSDL (the WSDL used throughout the WSDL2Java discussion is from the <a href="../samples/addr/AddressBook.wsdl">Address Book sample</a>):</p> <pre class="example"> <xsd:complexType name="phone">   <xsd:all>     <xsd:element name="areaCode" type="xsd:int"/>     <xsd:element name="exchange" type="xsd:string"/>     <xsd:element name="number" type="xsd:string"/>   </xsd:all> </xsd:complexType> </pre> <p>WSDL2Java will generate: <pre class="example"> public class Phone implements java.io.Serializable {     public Phone() {...}     public int getAreaCode() {...}     public void setAreaCode(int areaCode) {...}     public java.lang.String getExchange() {...}     public void setExchange(java.lang.String exchange) {...}     public java.lang.String getNumber() {...}     public void setNumber(java.lang.String number) {...}     public boolean equals(Object obj) {...}     public int hashCode() {...} } </pre> <h4>Mapping XML to Java types : Metadata</h4> <p>Notice in the mapping above, the XML type name is "phone" and the generated Java class is "Phone" - the capitalization of the first letter has changed to match the Java coding convention that classes begin with an uppercase letter. This sort of thing happens a lot, because the rules for expressing XML names/identifiers are much less restrictive than those for Java. For example, if one of the sub-elements in the "phone" type above was named "new", we couldn't just generate a Java field called "new", since that is a reserved word and the resultant source code would fail to compile.</p> <p>To support this kind of mapping, and also to enable the serialization/deserialization of XML attributes, we have a <b>type metadata</b> system which allows us to associate Java data classes with descriptors which control these things.</p> <p>When the WSDL2Java tool creates a data bean like the Phone class above, it notices if the schema contains any attributes, or any names which do not map directly to Java field/property names. If it finds any of these things, it will generate a static piece of code to supply a <b>type descriptor</b> for the class. The type descriptor is essentially a collection of <b>field descriptors</b>, each of which maps a Java field/property to an XML element or attribute.</p> <p>To see an example of this kind of metadata, look at the "test.encoding.AttributeBean" class in the Axis source, or generate your own bean from XML which uses attributes or names which would be illegal in Java.</p> <h4>Holders</h4> <p>This type may be used as an inout or out parameter.  Java does not have the concept of inout/out parameters.  In order to achieve this behavior, JAX-RPC specifies the use of holder classes.  A holder class is simply a class that contains an instance of its type.  For example, the holder for the Phone class would be:</p> <pre class="example"> package samples.addr.holders; public final class PhoneHolder implements javax.xml.rpc.holders.Holder { public samples.addr.Phone value;

public PhoneHolder() { }

public PhoneHolder(samples.addr.Phone value) { this.value = value; } } </pre> <p>A holder class is <b>only</b> generated for a type if that type is used as an inout or out parameter. Note that the holder class has the suffix "Holder" appended to the class name, and it is generated in a sub-package with the "holders". </p> <p>The holder classes for the primitive types can be found in javax.xml.rpc.holders.</p> <h4>PortTypes</h4> <p>The Service Definition Interface (SDI) is the interface that's derived from a WSDL's portType.  This is the interface you use to access the operations on the service.  For example, given the WSDL:</p> <pre class="example"> <message name="empty"> <message name="AddEntryRequest">   <part name="name" type="xsd:string"/>   <part name="address" type="typens:address"/> </message> <portType name="AddressBook">   <operation name="addEntry">     <input message="tns:AddEntryRequest"/>     <output message="tns:empty"/> </operation> </portType> </pre> <p>WSDL2Java will generate: <pre class="example"> public interface AddressBook extends java.rmi.Remote { public void addEntry(String name, Address address) throws java.rmi.RemoteException; } </pre>

<p>A note about the name of the SDI. The name of the SDI is typically the name of the portType. However, to construct the SDI, WSDL2Java needs information from both the portType <b>and</b> the binding. (This is unfortunate and is a topic of discussion for WSDL version 2.)

<p>JAX-RPC says (section 4.3.3): "The name of the Java interface is mapped from the name attribute of the wsdl:portType element. ... If the mapping to a service definition interface uses elements of the wsdl:binding ..., then the name of the service definition interface is mapped from the name of the wsdl:binding element." <p>Note the name of the spec. It contains the string "RPC". So this spec, and WSDL2Java, assumes that the interface generated from the portType is an RPC interface. If information from the binding tells us otherwise (in other words, we use elements of the wsdl:binding), then the name of the interface is derived instead from the binding. <p>Why? We could have one portType - pt - and two bindings - bRPC and bDoc. Since document/literal changes what the interface looks like, we cannot use a single interface for both of these bindings, so we end up with two interfaces - one named pt and another named bDoc - and two stubs - bRPCStub (which implements pt) and bDocStub (which implements bDoc). <p>Ugly, isn't it? But you can see why it's necessary. Since document/literal changes what the interface looks like, and we could have more than one binding referring to a single portType, we have to create more than one interface, and each interface must have a unique name. <br>  <h4> Bindings</h4> A Stub class implements the SDI.  Its name is the binding name with the suffix "Stub".  It contains the code which turns the method invocations into SOAP calls using the Axis Service and Call objects.  It stands in as a <b>proxy</b> (another term for the same idea) for the remote service, letting you call it exactly as if it were a local object. In other words, you don't need to deal with the endpoint URL, namespace, or parameter arrays which are involved in dynamic invocation via the Service and Call objects. The stub hides all that work for you. <p>Given the following WSDL snippet: <pre class="example"><binding name="AddressBookSOAPBinding" type="tns:AddressBook">   ... </binding></pre> <p>WSDL2Java will generate: <pre class="example">public class AddressBookSOAPBindingStub extends org.apache.axis.client.Stub implements AddressBook {     public AddressBookSOAPBindingStub() throws org.apache.axis.AxisFault {...}

    public AddressBookSOAPBindingStub(URL endpointURL, javax.xml.rpc.Service service) throws org.apache.axis.AxisFault {...} <br>    public AddressBookSOAPBindingStub(javax.xml.rpc.Service service) throws org.apache.axis.AxisFault {...} <br>    public void addEntry(String name, Address address) throws RemoteException {...}<br>}</pre> <h4> Services</h4> Normally, a client program would not instantiate a stub directly.  It would instead instantiate a service locator and call a get method which returns a stub.  This locator is derived from the service clause in the WSDL.  WSDL2Java generates two objects from a service clause.  For example, given the WSDL: <pre class="example"><service name="AddressBookService">   <port name="AddressBook" binding="tns:AddressBookSOAPBinding">     <soap:address location="http://localhost:8080/axis/services/AddressBook"/>   </port> </service></pre> <p>WSDL2Java will generate the service interface: <pre class="example">public interface AddressBookService extends javax.xml.rpc.Service {     public String getAddressBookAddress(); <br>    public AddressBook getAddressBook() throws javax.xml.rpc.ServiceException; <br>    public AddressBook getAddressBook(URL portAddress) throws javax.xml.rpc.ServiceException; }</pre> <p>WSDL2Java will also generate the locator which implements this interface: <pre class="example">public class AddressBookServiceLocator extends org.apache.axis.client.Service implements AddressBookService {     ... }</pre> <p>The service interface defines a get method for each port listed in the service element of the WSDL. The locator is the implementation of this service interface.  It implements these get methods. It serves as a locator for obtaining Stub instances. The Service class will by default make a Stub which points to the endpoint URL described in the WSDL file, but you may also specify a different URL when you ask for the PortType. <p>A typical usage of the stub classes would be as follows:

<pre class="example">public class Tester {   public static void main(String args) throws Exception {      // Make a service     AddressBookService service = new AddressBookServiceLocator();       // Now use the service to get a stub which implements the SDI.     AddressBook port = service.getAddressBook();       // Make the actual call     Address address = new Address(...);     port.addEntry("Russell Butek", address);     }<br>}</pre>

<h4> Server-side bindings</h4> Just as a stub is the client side of a Web Service represented in Java, a <b>skeleton</b> is a Java framework for the server side.  To make skeleton classes, you just specify the "--server-side --skeletonDeploy true" options to WSDL2Java. For instance, using the AddressBook.wsdl as we had above: <pre class="example">% java org.apache.axis.wsdl.WSDL2Java --server-side --skeletonDeploy true AddressBook.wsdl</pre> <p>You will see that WSDL2Java generates all the classes that were generated before for the client, but it generates a few new files: <br>  <br>  <table BORDER COLS=2 WIDTH="100%" > <tr> <td><b>WSDL clause</b></td>

<td><b>Java class(es) generated</b></td> </tr>

<tr> <td>For each binding</td>

<td>A skeleton class</td> </tr>

<tr> <td></td>

<td>An implementation template class</td> </tr>

<tr> <td>For all services</td>

<td>One deploy.wsdd file</td> </tr>

<tr> <td></td>

<td>One undeploy.wsdd file</td> </tr> </table>

<p>If you don't specify the "--skeletonDeploy true" option, a skeleton will not be generated. Instead, the generated deploy.wsdd will indicate that the implementation class is deployed directly. In such cases, the deploy.wsdd contains extra meta data describing the operations and parameters of the implementation class.

Here is how you run WSDL2Java to deploy directly to the implementation: <pre class="example">% java org.apache.axis.wsdl.WSDL2Java --server-side AddressBook.wsdl</pre> <p>And here are the server side files that are generated: <br>  <br>  <table BORDER COLS=2 WIDTH="100%" > <tr> <td><b>WSDL clause</b></td>

<td><b>Java class(es) generated</b></td> </tr>

<tr> <td>For each binding</td> <td>An implementation template class</td>

</tr>

<tr> <td>For all services</td>

<td>One deploy.wsdd file with operation meta data</td> </tr>

<tr> <td></td>

<td>One undeploy.wsdd file</td> </tr> </table>

<h4> Bindings</h4> <h5> Skeleton Description (for Skeleton Deployment) </h5> The skeleton class is the class that sits between the Axis engine and the actual service implementation.  Its name is the binding name with suffix "Skeleton".  For example, for the AddressBook binding, WSDL2Java will generate: <pre class="example">public class AddressBookSOAPBindingSkeleton implements AddressBook,     org.apache.axis.wsdl.Skeleton {     private AddressBook impl;       public AddressBookSOAPBindingSkeleton() {         this.impl = new AddressBookSOAPBindingImpl();     }       public AddressBookSOAPBindingSkeleton(AddressBook impl) {         this.impl = impl;     }       public void addEntry(java.lang.String name, Address address) throws java.rmi.RemoteException     {         impl.addEntry(name, address);     } }</pre> <p>(The real skeleton is actually much richer.  For brevity we just show you the basic skeleton.) <p>The skeleton contains an implementation of the AddressBook service.  This implementation is either passed into the skeleton on construction, or an instance of the generated implementation is created.  When the Axis engine calls the skeleton's addEntry method, it simply delegates the invocation to the real implementation's addEntry method. <h5> Implementation Template Description </h5> <p>WSDL2Java also generates an implementation template from the binding: <pre class="example">public class AddressBookSOAPBindingImpl implements AddressBook { <br>    public void addEntry(String name, Address address) throws java.rmi.RemoteException {     } }</pre> <p>This template could actually be used as a test implementation but, as you can see, it doesn't do anything.  It is intended that the service writer fill out the implementation from this template.</p> <p>When WSDL2Java is asked to generate the implementation template (via the --server-side flag), it will ONLY generate it if it does not already exist.  If this implementation already exists, it will not be overwritten.</p> <h4>Services</h4> <p>The tool also builds you a "deploy.wsdd" and an "undeploy.wsdd" for each service for use with the AdminClient. These files may be used to deploy the service once you've filled in the methods of the Implementation class, compiled the code, and made the classes available to your Axis engine.</p> <h3><a NAME="Java2WSDL: Building WSDL from Java"></a>Java2WSDL: Building WSDL from Java</h3> The Java2WSDL and WSDL2Java emitters make it easy to develop a new web service. The following sections describe the steps in building a web service from a Java interface. <br>  <h4> Step 1: Provide a Java interface or class</h4> Write and compile a Java interface (or class) that describes the web service interface.  Here is an example interface that describes a web services that can be used to set/query the price of widgets (<a href="../samples/userguide/example6/WidgetPrice.java">samples/userguide/example6/WidgetPrice.java</a>): <pre class="example">package samples.userguide.example6; <br>/**  * Interface describing a web service to set and get Widget prices.  **/ public interface WidgetPrice {     public void setWidgetPrice(String widgetName, String price);     public String getWidgetPrice(String widgetName); }</pre> <p><b>Note: </b>If you compile your class with debug information, Java2WSDL will use the debug information to obtain the method parameter names. <h4> Step 2: Create WSDL using Java2WSDL</h4> Use the Java2WSDL tool to create a WSDL file from the interface above. <p>Here is an example invocation that produces the wsdl file (<tt>wp.wsdl</tt>) from the interface described in the previous section:

% java org.apache.axis.wsdl.Java2WSDL -o wp.wsdl&nbsp; -l"http://localhost:8080/axis/services/WidgetPrice" -n&nbsp; 
"urn:Example6"&nbsp;-p"samples.userguide.example6" "urn:Example6"&nbsp; samples.userguide.example6.WidgetPrice
<p>Where: <ul> <li> -o indicates the name of the <b><i>output WSDL</i></b> file</li>

<li> -l indicates the<b><i> location of the service</i></b></li>

<li> -n is the target <b><i>namespace</i></b> of the WSDL file</li>

<li> -p indicates a mapping from the <b><i>package to a namespace</i></b>.  There may be multiple mappings.</li>

<li> the class specified contains the interface of the webservice.</li> </ul> The output WSDL document will contain the appropriate WSDL types, messages, portType, bindings and service descriptions to support a SOAP rpc, encoding web service.  If your specified interface methods reference other classes, the Java2WSDL tool will generate the appropriate xml types to represent the classes and any nested/inherited types.  The tool supports JAX-RPC complex types (bean classes), extension classes, enumeration classes, arrays and Holder classes. <p>The Java2WSDL tool has many additional options which are detailed in the <a href="reference.html#Java2WSDL">reference guide</a>. There is an <a href="ant/axis-java2wsdl.html">Ant Task</a> to integrate this action with an Ant based build process. <h4> Step 3: Create Bindings using WSDL2Java</h4> Use the generated WSDL file to build the appropriate client/server bindings for the web service (see <a href="#WSDL2Java: Building stubs, skeletons, and data">WSDL2Java</a>): <pre class="example">% java org.apache.axis.wsdl.WSDL2Java -o . -d Session -s -S true  -Nurn:Example6 samples.userguide.example6 wp.wsdl</pre> <p>This will generate the following files: <ul> <li> <b><tt>WidgetPriceSoapBindingImpl.java</tt></b> : Java file containing the default server implementation of the WidgetPrice web service.</li> <br> You will need to modify the *SoapBindingImpl file to add your implementation (see  <a href="../samples/userguide/example6/WidgetPriceSoapBindingImpl.java">../samples/userguide/example6/WidgetPriceSoapBindingImpl.java</a> ). <li> <b><tt>WidgetPrice.java</tt></b>:  New interface file that contains the appropriate <b><tt>java.rmi.Remote</tt></b> usages.</li> <li> <b><tt>WidgetPriceService.java</tt></b>: Java file containing the client side service interface.</li> <li> <b><tt>WidgetPriceServiceLocator.java</tt></b>: Java file containing the client side service implementation class.</li> <li> <b><tt>WidgetPriceSoapBindingSkeleton.java</tt></b>: Server side skeleton.</li> <li> <b><tt>WidgetPriceSoapBindingStub.java</tt></b>: Client side stub.</li> <li> <b><tt>deploy.wsdd</tt></b>: Deployment descriptor</li> <li> <b><tt>undeploy.wsdd</tt></b>: Undeployment descriptor</li> <li> (data types):  Java files will be produced for all of the other types and holders necessary for the web service.  There are no additional files for the WidgetPrice web service.</li> </ul> <p>Now you have all of the necessary files to build your client/server side code and deploy the web service!</p> <h2> <a NAME="published interfaces"></a>Published Axis Interfaces</h2> Although you may use any of the interfaces and classes present in Axis, you need to be aware that some are more stable than others since there is a continuing need to refactor Axis to maintain and improve its modularity. <p>Hence certain interfaces are designated as <i>published</i>, which means that they are relatively stable. As Axis is refactored, the Axis developers will try to avoid changing published interfaces unnecessarily and will certainly consider the impact on users of any modifications. <p>So if you stick to using only published interfaces, you'll minimise the pain of migrating between releases of Axis. On the other hand, if you decide to use unpublished interfaces, migrating between releases could be an interesting exercise! If you would like an interface to be published, you should make the case for this on the <a href="mailto:axis-user@ws.apache.org">axis-user</a> mailing list. <p>The current list of published interfaces is as follows: <ul> <li> JAX-RPC interfaces. These interfaces are from JAX-RPC 1.0 specification, and will change only when new versions of the specification are released. <ul> <li>javax.xml.messaging.Endpoint</li> <li>javax.xml.messaging.URLEndpoint</li> <li>javax.xml.rpc.Call</li> <li>javax.xml.rpc.FaultException</li> <li>javax.xml.rpc.JAXRPCException</li> <li>javax.xml.rpc.ParameterMode</li> <li>javax.xml.rpc.Service</li> <li>javax.xml.rpc.ServiceException</li> <li>javax.xml.rpc.ServiceFactory</li> <li>javax.xml.rpc.Stub</li> <li>javax.xml.rpc.encoding.DeserializationContext</li> <li>javax.xml.rpc.encoding.Deserializer</li> <li>javax.xml.rpc.encoding.DeserializerFactory</li> <li>javax.xml.rpc.encoding.SerializationContext</li> <li>javax.xml.rpc.encoding.Serializer</li> <li>javax.xml.rpc.encoding.SerializerFactory</li> <li>javax.xml.rpc.encoding.TypeMapping</li> <li>javax.xml.rpc.encoding.TypeMappingRegistry</li> <li>javax.xml.rpc.handler.Handler</li> <li>javax.xml.rpc.handler.HandlerChain</li> <li>javax.xml.rpc.handler.HandlerInfo</li> <li>javax.xml.rpc.handler.HandlerRegistry</li> <li>javax.xml.rpc.handler.MessageContext</li> <li>javax.xml.rpc.handler.soap.SOAPMessageContext</li> <li>javax.xml.rpc.holders.BigDecimalHolder</li> <li>javax.xml.rpc.holders.BigIntegerHolder</li> <li>javax.xml.rpc.holders.BooleanHolder</li> <li>javax.xml.rpc.holders.BooleanWrapperHolder</li> <li>javax.xml.rpc.holders.ByteArrayHolder</li> <li>javax.xml.rpc.holders.ByteHolder</li> <li>javax.xml.rpc.holders.ByteWrapperArrayHolder</li> <li>javax.xml.rpc.holders.ByteWrapperHolder</li> <li>javax.xml.rpc.holders.CalendarHolder</li> <li>javax.xml.rpc.holders.DateHolder</li> <li>javax.xml.rpc.holders.DoubleHolder</li> <li>javax.xml.rpc.holders.DoubleWrapperHolder</li> <li>javax.xml.rpc.holders.FloatHolder</li> <li>javax.xml.rpc.holders.FloatWrapperHolder</li> <li>javax.xml.rpc.holders.Holder</li> <li>javax.xml.rpc.holders.IntHolder</li> <li>javax.xml.rpc.holders.IntegerWrapperHolder</li> <li>javax.xml.rpc.holders.LongHolder</li> <li>javax.xml.rpc.holders.LongWrapperHolder</li> <li>javax.xml.rpc.holders.ObjectHolder</li> <li>javax.xml.rpc.holders.QNameHolder</li> <li>javax.xml.rpc.holders.ShortHolder</li> <li>javax.xml.rpc.holders.ShortWrapperHolder</li> <li>javax.xml.rpc.holders.StringHolder</li> <li>javax.xml.rpc.namespace.QName</li> <li>javax.xml.rpc.server.ServiceLifecycle</li> <li>javax.xml.rpc.soap.SOAPFault</li> <li>javax.xml.rpc.soap.SOAPHeaderFault</li> <li>javax.xml.transform.Source</li> </ul> </li> <li>Axis interfaces. These have less guarantees of stability: <ul> <li>org.apache.axis.AxisFault</li> <li>org.apache.axis.Handler</li> <li>org.apache.axis.DefaultEngineConfigurationFactory</li> <li>org.apache.axis.EngineConfiguration</li> <li>org.apache.axis.EngineConfigurationFactory</li> <li>org.apache.axis.Message</li> <li>org.apache.axis.MessageContext</li> <li>org.apache.axis.SOAPPart</li> <li>org.apache.axis.client.Call</li> <li>org.apache.axis.client.Service</li> <li>org.apache.axis.client.ServiceFactory</li> <li>org.apache.axis.client.Stub</li> <li>org.apache.axis.client.Transport</li> <li>org.apache.axis.description.TypeDesc</li> <li>org.apache.axis.description.AttributeDesc</li> <li>org.apache.aixs.description.ElementDesc</li> <li>org.apache.axis.encoding.DeserializationContext</li> <li>org.apache.axis.encoding.Deserializer</li> <li>org.apache.axis.encoding.DeserializerFactory</li> <li>org.apache.axis.encoding.DeserializerTarget</li> <li>org.apache.axis.encoding.FieldTarget</li> <li>org.apache.axis.encoding.MethodTarget</li> <li>org.apache.axis.encoding.SerializationContext</li> <li>org.apache.axis.encoding.Serializer</li> <li>org.apache.axis.encoding.SerializerFactory</li> <li>org.apache.axis.encoding.SimpleType</li> <li>org.apache.axis.encoding.Target</li> <li>org.apache.axis.encoding.TypeMapping</li> <li>org.apache.axis.encoding.TypeMappingRegistry</li> <li>org.apache.axis.encoding.ser.BaseDeserializerFactory</li> <li>org.apache.axis.encoding.ser.BaseSerializerFactory</li> <li>org.apache.axis.encoding.ser.BeanPropertyTarget</li> <li>org.apache.axis.encoding.ser.SimpleSerializer</li> <li>org.apache.axis.encoding.ser.SimpleDeserializer</li> <li>org.apache.axis.session.Session</li> <li>org.apache.axis.transport.http.SimpleAxisServer</li> <li>org.apache.axis.transport.jms.SimpleJMSListener</li> <li>org.apache.axis.utils.BeanProperty</li> <li>org.apache.axis.wsdl.WSDL2Java</li> <li>org.apache.axis.wsdl.Java2WSDL</li> </ul> </ul> <h2><a name="newbie"></a>Newbie Tips: Finding Your Way Around</h2> <p>So you've skimmed the User's Guide and written your first .jws service, and everything went perfectly! Now it's time to get to work on a real project, and you have something specific you need to do that the User's Guide didn't cover. It's a simple thing, and you know it must be in Axis <em>somewhere</em>, but you don't know what it's called or how to get at it. This section is meant to give you some starting points for your search.</p> <h3>Places to Look for Clues</h3> <p>Here are the big categories.</p> <ul> <li><a href="../samples/"><b>The samples.</b></a> These examples are complete with deployment descriptors and often contain both client and server code. </li> <li><b>The Javadocs.</b> Full Javadocs are included with the binary distribution. The Javadocs can be intimidating at first, but once you know the major user classes, they are one of the fastest ways to an answer.</li> <li><b><a href="http://ws.apache.org/axis/mail.html">The mailing list archives.</a></b> If you know what you want but don't know what it's called in Axis, this is the best place to look. Chances are someone has wanted the same thing and someone else has used (or developed) Axis long enough know the name.</li> <li> Consult the <A HREF="http://ws.apache.org/axis">Axis web site</a> for updated documentation and the <a href="http://nagoya.apache.org/wiki/apachewiki.cgi?AxisProjectPages">Axis Wiki</a> for its Frequently Asked Questions (FAQ), installation notes, interoperability issues lists, and other useful information. </li> <li> <b>WSDL2Java.</b> Point WSDL2Java at a known webservice that does some of the things you want to do. See what comes out. This is useful even if you will be writing the actual service or client from scratch. If you want nice, human-readable descriptions of existing web services, try <a href="http://www.xmethods.net">http://www.xmethods.net</a>.</li> </ul> <h3>Classes to Know</h3> <h4>org.apache.axis.MessageContext</h4> <p>The answer to most "where do I find..." questions for an Axis web service is "in the MessageContext." Essentially everything Axis knows about a given request/response can be retrieved via the MessageContext. Here Axis stores:</p> <ul> <li>A reference to the AxisEngine</li> <li>The request and response messages (<code>org.apache.axis.Message</code> objects available via getter and setter methods)</li> <li>Information about statefulness and service scope (whether the service is maintaining session information, etc.)</li> <li>The current status of processing (whether or not the "pivot" has been passed, which determines whether the request or response is the current message)</li> <li>Authentication information (username and password, which can be provided by a servlet container or other means)</li> <li>Properties galore. Almost anything you would want to know about the message can be retrieved via <code>MessageContext.getProperty()</code>. You only need to know the name of the property. This can be tricky, but it is usually a constant, like those defined in <code>org.apache.axis.transport.http.HTTPConstants</code>. So, for example, to retrieve the ServletContext for the Axis Servlet, you would want: <code>((HttpServlet)msgC.getProperty(HTTPConstants.MC_HTTP_SERVLET)).getServletContext();</code><br> </li> </ul> <p>From within your service, the current MessageContext object is always available via the static method <code>MessageContext.getCurrentContext()</code>. This allows you to do any needed customization of the request and response methods, even from within an RPC service that has no explicit reference to the MessageContext.</p> <h4>org.apache.axis.Message</h4> <p>An <code>org.apache.axis.Message</code> object is Axis's representation of a SOAP message. The request and response messages can be retrieved from the MessageContext as described above. A Message has:</p> <ul> <li>MIME headers (if the message itself has MIME information)</li> <li>Attachments (if the message itself has attachments)</li> <li>A SOAPPart (and a convenience method for quick retrieval of the SOAPPart's SOAPEnvelope). The SOAPPart gives you access to the SOAP "guts" of the message (everything inside the <soap:Envelope> tags)</li> </ul> <h4>org.apache.axis.SOAPEnvelope</h4> <p>As you can see, starting with the MessageContext lets you work your way down through the API, discovering all the information available to you about a single request/response exchange. A MessageContext has two Messages, which each have a SOAPPart that contains a SOAPEnvelope. The SOAPEnvelope, in turn, holds a full representation of the SOAP Envelope that is sent over the wire. From here you can get and set the contents of the SOAP Header and the SOAP Body. See the Javadocs for a full list of the properties available.</p> <h2> <a NAME="tcpmon"></a>Appendix : Using the Axis TCP Monitor (tcpmon)</h2> The included "tcpmon" utility can be found in the org.apache.axis.utils package. To run it from the command line: <pre>% java org.apache.axis.utils.tcpmon listenPort targetHost targetPort</pre> Without any of the optional arguments, you will get a gui which looks like this: <center> <p><img SRC="images/tcpmon1.jpg" height=599 width=599></center>

<p>To use the program, you should select a local port which tcpmon will monitor for incoming connections, a target host where it will forward such connections, and the port number on the target machine which should be "tunneled" to. Then click "add". You should then notice another tab appearing in the window for your new tunneled connection. Looking at that panel, you'll see something like this: <center> <p><img SRC="images/tcpmon2.jpg" height=600 width=599></center>

<p>Now each time a SOAP connection is made to the local port, you will see the request appear in the "Request" panel, and the response from the server in the "Response" panel. Tcpmon keeps a log of all request/response pairs, and allows you to view any particular pair by selecting an entry in the top panel. You may also remove selected entries, or all of them, or choose to save to a file for later viewing. <p>The "resend" button will resend the request you are currently viewing, and record a new response. This is particularly handy in that you can edit the XML in the request window before resending - so you can use this as a great tool for testing the effects of different XML on SOAP servers. Note that you may need to change the content-length HTTP header value before resending an edited request.

<h2> <a NAME="soapmon"></a>Appendix: Using the SOAP Monitor </h2> Web service developers often have the need to see the SOAP messages being used to invoke web services along with the results of those messages. The goal of the SOAP Monitor utility is to provide a way for these developers to monitor the SOAP messages being used without requiring any special configuration or restarting of the server. <p> In this utility, a handler has been written and added to the global handler chain. As SOAP requests and responses are received, the SOAP message information is forwarded to a SOAP monitor service where it can be displayed using a web browser interface. <p> The SOAP message information is accessed with a web browser by going to http://localhost:<port>/axis/SOAPMonitor (where <port> is the port number where the application server is running). <p> The SOAP message information is displayed through a web browser by using an applet that opens a socket connection to the SOAP monitor service. This applet requires a Java plug-in 1.3 or higher to be installed in your browser. If you do not have a correct plug-in, the browser should prompt you to install one. <p> The port used by the SOAP monitor service to comminicate with applets is configurable. Edit the web.xml file for the Axis web application to change the port to be used.

<b>Note: The SOAP Monitor is NOT enabled by default for security reasons.</b> To enable it, read <a href="install.html#soapmon">Enabling the SOAP Monitor</a> in the Installation instructions.

<a NAME="Glossary"> <h2>Glossary</h2></a>

<dl> <dt> <i>Handler</i></dt> <dd> A reusable class which is responsible for processing a MessageContext in some custom way. The Axis engine invokes a series of Handlers whenever a request comes in from a client or a transport listener.</dd> <dt> <i>SOAP</i></dt> <dd> The Simple Object Access Protocol (yes, despite the fact that it sometimes doesn't seem so simple, and doesn't have anything to do with objects... :)). You can read the SOAP 1.1 specification at <a href="http://www.w3.org/TR/SOAP">http://www.w3.org/TR/SOAP</a>. The W3C is currently in the midst of work on SOAP 1.2, under the auspices of the <a href="http://www.w3.org/2000/xp/Group/">XML Protocol Group</a>.</dd> <dt> <i>Provider</i></dt> <dd> A provider is the "back-end" Handler which is responsible for actually performing the "meat" of the desired SOAP operation. Typically this means calling a method on some back-end service object. The two commonly used providers are RPCProvider and MsgProvider, both in the org.apache.axis.providers.java package.</dd> </dl>

</body> </html>

Add new attachment

Only authorized users are allowed to upload new attachments.

List of attachments

Kind Attachment Name Size Version Date Modified Author Change note
jpg
axis.jpg 11.0 kB 1 06-Apr-2006 09:45 218.144.184.45
jpg
axis1.jpg 11.0 kB 1 06-Apr-2006 09:45 218.144.184.45
« This page (revision-1) was last changed on 06-Apr-2006 09:45 by UnknownAuthor