기초에서 실무까지 XML 웹 서비스
책 정보
- 출판사 : 프리렉
- 출판사 책 사이트 : https://freelec.co.kr/book/catalogue_view.asp?page=2&UID=60#review
- 동영상 강의 사이트 : 동영상 강좌는 쓰레기 임.
- 출판년도(초판) : 2003-10-02
관련 사이트
저자 정보
- 신민철
용어 정리
- OMG : Object Management Group
- CORBA : Common Object Request Broker Architecture
- DCOM : Distributed Component Object Model
- RMI : Remote Method Invocation
- SOAP : Simple Object Access Protocol
- UDDI : Universal Description, Discovery and Integration
- WDSL : Web Service Description Language
- JWSDP : Java Web Service Developer Pack
- WS : Web Service
- DOM : Document Object Model
- SAX : Simple API for XML
- JAXP : Java API for XML Processing
- XSLT : XML Stylesheet Language Transformation
- JAX-RPC : Java API for XML-based RPC
- RPC : Remote Procedure Call
- WAR : Web Application Archives
- Marshalling : Java -> XML
- Unmarshalling : XML -> Java
- JAX-WS : Java API for XML Web Service
- PI : Processing Instruction, 프로세싱 지시자
- xsd : XML Schema Definition , xml 스키마 정의 파일 확장자
- xsi : XML Schema Instance
- URN : Uniform Resource Name (링크)
추가적인 용어
- Jabber : 관련 사이트#1
- WS-I :
약어
- ns : NameSpace
- tns : TargetNameSpace
- xs : xml schema
1장 . 웹서비스 개요
웹서비스 구성 하는 3가지 요소
- 웹 서비스 제공자 : Provider
- Publish : 서비스 공개
- 웹 서비스 중계자 : Broker
- Find : 서비스 검색
- 웹 서비스 소비자 : Consumer
- Bind : 특정 프로토콜을 이용해서 웹 서비스 시스템에 접속하는 것을 의미
UDDI : 공개 및 검색
- 웹 서비스의 공개(publish) 와 검색(find)를 위한 XML 저장소(registory)의 구현과 사용 방법을 표준화 한것
WDSL : 웹 서비스 기술 언어
- 표준화된 방식으로 웹 서비스의 인터페이스를 기술하는 XML 기술
SOAP : 단순 객체 접근 프로토콜
- 정보 교환을 위해 필요한 구조를 표준화 한 것
2장 . 웹 서비스 개발 S/W
JWSDP 소개
JWSDP란
- 자바에서 WS를 쉽게 구현 하기 위한 통합 개발 툴킷
JWSDP에 포함된 기술
- JAXP : Java API for XML Processing
- DOM , SAX 파서를 생성, XML 문서를 해석하기 위한 API를 제공
- 디폴트 파서 : Apache의 Xerces2를 사용
- XSLT : XSL 문서를 사용하여 XML 문서를 변환
- XSLT 엔진 : Apache의 Xalan 사용
- JAX-RPC : Java API for XML-base RPC
- SOAP 메시지에 근거한 RPC 방식의 WS C/S 개발위한 API
- 서버 개발 시
- WSDL 문서 자동 생성 기능
- WAR 파일 생성
- 클라이언트 개발 시
- WSDL 기반으로 stub 코드 생성
- 실행 시 내부적으로 JAXP 와 SAAJ를 이용하여 SOAP 메시지 생성, 전송, 해석하는
역할을 함. - 현재는 JAX-WS 라고 함 (Java API for XML Web Services)
- JAXB : Java Architecture for XML Binding
- Java object <-> XML 문서 (마샬링 , 언마샬링)
- XML과 자바 코드 사이를 매핑하는 표준 방법을 제공
- JAXR : Java API for XML Registries
- 여러 가지 종류의 XML 저장소에 일관 되게 접근하여 정보를 저장하거나 검색할 수 있는
표준 API를 제공 - XML 저장소 종류 의 예 : ebXML , UDDI 레지스트리
- SAAJ : SOAP with Attachments API for Java
- SOAP 메시지를 생성하고 , 전송하는 API
- JAXM : Java API for XML Messaging
- 비동기적인 웹 서비스 형태를 구현하기 위한 API 제공
- Tomact : 아파치 JSP 엔진
- Java WSDP Registry Server : 테스트용 UDDI 레지스트리 임.
3장 . XML 기초 문법
XML문서의 종류
- Well-Formed Document
- Valid Document
EBNF 표기법
- Exteneded Backus-Nar Form
- 예) XML 및 ASN.1 등을 정의 할때 사용함.
- 문법 형태
- Symbol ::= Expression
- Pattern 결합
- A? : 옵션, A 표현이 올 수도 있고 안 올 수도 있음
- A B : 순차, A 다음에 B
- A|B : 선택, A 혹은 B
- A-B : A는 오지만 B는 오지 말아야
- A+ : 한개 이상
- A* : 0 이거나 한개 이상
XML 문서 구조 및 선언
- 문서 : 서두 + 엘리멘트
- 서두 : PI
- <? ?> : 형식
- 엘리멘트 : 1개의 root 엘리멘트
- 문서 선언
- <?xml version="1.0" encoding="utf-8" standalone="yes"?>
- 이 선언 이전에 어떤 문자열도 올 수 없다. 주석도
- 그리고 <?xml 와 같이 받드시 <?xml 빈공백 올수 없다.
- 속성들
- version : 필수 1.0 , 생략 불가
- encoding : 문서의 인코딩 , 생략 가능 , 기본값 utf-8
- standalone : DTD나 schema 참조 여부 기본값, yes
5장 . XML 스키마
요약
- 스키마 선언 관련 (참조링크)
- xsi:noNamespaceSchemaLocation 속성 : 스키마 문서의 URI 경로를 명시 한다.
- xsi:noNamespaceSchemaLocation="http://www.example.com/MyData.xsd"
- xsi:schemaLocation 속성 : 네임스페이스와 스카마문서를 명시
- xsi:schemaLocation="urn:MyData http://www.example.com/MyData.xsd"
- URN : 독립적인 이름을 제공 부여 하기 위한 방법
- NID(Namespace ID) 와 NSS(Namespace Specific String) 으로 구성되어 있음
- 각 구분은 콜론(:)으로 함.
- 예)
- urn:한국-시민:000000-0000000
- urn:xmlgo:registory1
- Qname : qualified name , 적합한 이름
- namespace_part + local_part
- 예) <xsd:element>
스키마(Schema) 파일 구조
- 확장자 : xsd
- 형식
<?xml version="1.0"?>
<!-- 외부 XML schema 문서의 참조에 관련된 엘리멘트 -->
<!-- 새로운 엘리멘트 및 속성을 선언하는 엘리멘트 -->
</xsd:schema>
|
- 관련 엘리멘트들
- 외부 스키마 문서 참조용 엘리멘트들
- <include>
- <import>
- <redefine>
- <annotation>
- 새로운 엘리멘트 / 속성 선언관련 엘리멘트들
- <element>
- <attribute>
- <simpleType>
- <complexType>
- <group>
- <attributeGroup>
- <notation>
- <annotation>
- 주석 관련
- <!-- 기본 주석 -->
- <annoation>
<annotation>
(appinfo | documentation) *
</annotation>
<appinfo source="외부 참조 문서 경로">주석 내용</appinfo>
<documentation source="외부 참조 문서 경로" xml:lang="사용된 언어"></documentation>
|
엘리멘트 선언
- <xsd:element> 요소를 사용
- 데이터만 갖는 엘리멘트 선언
- 형식 : <xsd:element name="엘리멘트 이름"
minOccurs="최소횟수" maxOccurs="최대횟수" type="테이타 타입"/> - 내용 : <title>책 제목</title>
- 자식을 갖는 엘리멘트
- 자식 과 속성을 갖는 엘리멘트
- 속성만 갖는 빈 엘리멘트
- 테이터 과 속성을 갖는 엘리멘트
- 글로벌 엘리멘트 참조
- null 값을 가지는 엘리멘트
- 테이터가 0 아니라 null 상태를 인것을 의미함
- nillable 속성값이 true 임
- 엘리먼트의 다형성
- substitutionGroup 속성을 값 지정하여 같은 것으로 취급하게 함.
엘리멘트 범위
- 글로벌 엘리멘트
- <xsd:schema> 하위에 선언
- 다른 곳에 참조(ref) 가능 함.
- 로컬 엘리멘트
- 다른 엘리멘트 하위에 선언
- 다른 곳에서 참조 불가능 함.
속성 선언
- 형식
<attribute
name="속성명"
use="optional|required" // 생략 가능 (기본값: optional)
default="기본값" // 속성 생략 기본 값 (use가 optional일 경우)
ref="참조할 전역 속성명"
type="테이타 타입" // build in 속성과 사용자 정의 속성 유형 모두 가능
/>
|
- 속성도 선언위치에 따라 엘리멘트와 같이 글로벌과 로컬 속성을 구분되어 짐.
Data Type
- 분류 : 사용 용도에 따라
- Built-in Simple Type
- 스키마 언어에 미리 정의 되어 있음
- xsd:심플타입명 과 같은 형식
- User define Simple Type
- 사용자가 새로 정의하는 심플 타입
- Complex Type
- 사용자가 정의 복잡 타입
- 자식 엘리멘트 과 속성을 가지는 엘리멘트 선언시 사용
사용자 정의 Simple Type
공백으로 분리된 여러 데이터를 가지는 심플 타입 정의
- 형식 : <list itemType="심플 타입 이름">
- 문법
<!-- 저자들 -->
<xs:simpleType name="authors">
<xs:list itemType="xsd:string"/>
</xs:simpleType>
<!-- 타입 사용 -->
<xs:element name="authors" type="authors"/>
|
- 문서 사용예
<authors>김하나 이두명 삼세기</authors>
|
여러 개의 심플 타입을 결합한 심플 타입 정의
- 설명 : <union> 하나 이상의 심플 타입을 결합하여 새로운 심플 타입을 정의
- 문법
<union memberTypes="심플타입#1 심플타입#2"/>
|
- 사용예
<!-- 스키마 파일 정의 -->
<xs:simpleType name="OldPost">
<xs:restriction base="xsd:int">
<xs:length value="6">
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="NewPost">
<xs:restriction base="xsd:int">
<xs:length value="5">
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="post">
<union memberTypes="OldPost NewPort">
</xs:simpleType>
<!-- 타입 정의 -->
<xs:element name="post" type="post"/>
<!-- 사용예 -->
<post>15171</post>
|
Wild Card
- 임의의 엘리멘트나 속성을 사용할 수 있도록 해주는 기능
<any>
- 엘리멘트 wild card
- 속성 설명
- namespace : 엘리멘트의 ns를 지정함. anyURI 혹은 아래 값이 올 수 있음.
- maxOccurs :
- minOccurs :
- processContents : 유효성 검사 여부. [ skip | strict | lax ]
- skip : 유효성 검사 하지 않음
- strict : 반드시 유효성 검사를 함.
- lax : 스키마 정보를 얻을 수 있을 경유만 유효성 검사
- namespace 의 anyURI 대신 올 수 있는 값들
값
|
설명
|
##any
|
어떤 ns에 속하는 엘리멘트든지 다 올 수 있다.
|
##other
|
Target ns를 제외한 다른 ns에 속하는 엘리멘트만 올 수 있음.
|
##targetNamespace
|
Target ns에 속하는 엘리멘트만 올 수 있음
|
##local
|
ns에 속하지 않는 엘리멘트만 올 수 있음.
|
<anyAttribute>
- 속성 wild card
- 속성 설명
- namespace : 사용 가능한 속성의 네임스페이스
- processContents : 유효성 검사 여부
- namespace 의 anyURI 대신 올 수 있는 값들
값
|
설명
|
##any
|
어떤 ns에 속하는 속성이든지 다 올 수 있다.
|
##other
|
Target ns를 제외한 다른 ns에 속하는 속성만 올 수 있음.
|
##targetNamespace
|
Target ns에 속하는 속성만 올 수 있음
|
##local
|
ns에 속하지 않는 속성만 올 수 있음.
|
스키마 문서의 결합
- <include> : 같은 ns를 가지는 문서의 결합
- <import> : 다른 ns를 가지는 문서의 결합
- <redefine> : 같은 ns나 ns가 없는 스키마 문서를 결합할 때 문서의 일부를 재 정의 할 때 사용
<include> 사용
- 문법
<xs:include schemaLocation="$포함될_스키마_문서"/>
|
<import> 사용
- 문법
<xs:import
namespace="$포함할_스키마_문서의_네임스페이스"
schemaLocation="$포함될_스키마_문서"/>
|
<redefine> 사용
- 문법
<xs:redefine schemaLocation="$포함될_스키마_문서"/>
<!-- 재정의할 내용 -->
</xs:redefine>
|
Namespace 가지는 Schema
- 문법
<?xml version="1.0"?>
<xs:schema
targetNamespace="$네임스페이스_이름"
elementFormDefault="$엘리멘트의 네임스페이스_포함여부"
attributeFormDefault="$속성의 네임스페이스_포함여부"
xmlns="$네임스페이스_이름">
…
</xs:schema>
|
- 속성들
- targetNamespace : 스키마 문서에서 정의되는 새로운 마크업 언어가 가질 네임스페이스를
지정해 주면 된다. - elementFormDefault : 스키마 문서에 정의된 element들이 주어진 tns에 속할 것인지를 결정
- qualified : tns에 속함 (기본값)
- unqualified : tns에 속하지 않음
- attributeFormDefault : 스키마 문서에 정의된 속성들이 주어진 tns에 속할 것인지를 결정
- qualified : tns에 속함
- unqualified : tns에 속하지 않음(기본값)
- xmlns : 글로벌 선언을 로컬 엘리멘트 선언에 접두사(ns) 없이 참조 가능하도록 디폴트 ns 선언 해두는 것이다.
스키마 인스턴스 지정 방법
- 속성
- xsi:noNamespaceSchemaLocation : ns 없는 스키마 문서 URI를 지정함
- xsi:schemaLocation : ns가 있는 스키마 문서를 지정함
- 값 유형#1: “ns ~.xsd”
- 값 유형#1: “ns#1 ~.xsd ns#2 ~.xsd”
6장. SOAP 이해
SOAP 장점
- SOAP는 경량 프로토콜
- CORBA , RMI , DCOM에 비해
- 텍스트 기반 프로토콜
- OS 중립적
- HTTP 사용 가능
- 방화벽에 통과 가능
- 보안에 취약할 수 있음
SOAP 스펙
- 책의 버젼은 1.1
- 현재 버젼은 1.2
- 관련 사이트
- SOAP 메시지 구조(1.1) xml schema 문서 URL
- namespace : http://schemas.xmlsoap.org/soap/envelope
- SOAP 메시지 구조(1.2) xml schema 문서 URL
- namespace : https://www.w3.org/2003/05/soap-envelope/
SOAP 메시지 교환 모델
- 발신자과 수신자 모델
- sender , receiver : endpoint(종점)
- 단방향 이동
- Message Chain
- 단방향 메시지를 여러 개를 병합해서 더 복잡한 동작을 만들어 낼 수 있음.
- 중개자(intermdiary) 또는 Actor : 메시지를 발신하는 역할을 하는 종점
SOAP 메시지 구조
- Envolpe : 필수적
- 관련 엘리멘트 <Envolpe>
- Header : 선택적임
- 메시지 내용에 대한 추가적인 기능
- 트랙잭션 관리
- 발신자 인증
- 관련 엘리멘트 <Header>
- 자식 엔리멘트를 Header Entry라고 함.
- Header Entry의 Root 엘리멘트는 접두어 붙은 QName으로 기술 되어야 한다.
- 속성들 (1.1) 기준
- actor : 중개자(액터) 중 누가 헤더 엔트리를 처리할 것인가 지정
- 값 : actor URI
- mustUnderstand : 반드시 처리해야 됨을 지정
- 0 | 1 , 1 -> 반드시 처리 해야 함.
- 기본값은 0
- Body : 필수적
- 메시지 내용을 기술
- 관련 엘리멘트 : <Body>
- Root 엔리멘트는 QName으로 기술 되어야 함.
- <Fault> 엘리멘트
- Body 하위 엘리멘트
- 자식 엘리멘트 목록
- <faultcode> : 오류 코드 (1.1)
네임스페이스 접두를 사용해야 함.
오류 코드
|
설명
|
env:VersionMismatch
|
요청 SOAP 메시지의 <Envelope> 엘리멘트의 네임스페이스 명이 잘못 되었음을 발경한 경우
|
env:MustUnderstand
|
mustUnderstand 속성값이 1인 헤더 엔트리를 중계자(액터)또는 최종 수신자가 처리하지 못한 경우
|
env:Client
|
클라이언트의 요청 SOAP 메시지 정보가 불충분하여 처리할 수 없는 경우
|
env:Server
|
서버에서 SOAP메시지를 처리하는 도중 오류가 발생하는 경우
|
- <faultstring> : 오류에 대한 설명
- <faultactor> : 오류가 발생한 액터
- 중계자에서 오류가 발생한 경우 반드시 기술 되어야 함.
- <detail> : 오류에 대한 추가적인 정보 기술
SOAP 인코딩
- 특정 프로그래밍 언어로 작성된 프로그램에서 SOAP 메시지를 생성할 때 프로그램 언어의 테이터형을
SOAP 메시지에서 표기하는 방법의미 한다. - encodingStyle 속성
// version 1.1
// version 1.2
<!-- 사용자 정의 속성 추가 -->
|
- 단순 타입 표기법
<엘리멘트 xsi:type="xsd:$데이터_형">데이터</엘리멘트>
|
자바의 기본 형 과 xml schema 빌트인 형
Java
|
XML Schema
|
boolean
|
xsd:boolean
|
byte
|
xsd:byte
|
short
|
xsd:short
|
int
|
xsd:int
|
long
|
xsd:long
|
float
|
xsd:float
|
double
|
xsd:double
|
String
|
xsd:string
|
- 배열 표기법
<!-- 문법 -->
<접두사:메소드명>
<배열참조변수명 href="#배열식별자"/>
</접두사:메소드명>
<array id="배열식별자" xsd:type="enc:Array" enc:arrayType="데이터형[n]">
<item>순번 0의 값</item>
<item>순번 1의 값</item>
</array>
|
<!-- 실제 사용예 -->
<ns0:addBooks>
<arrayOfString_1 href="#bookarray"/>
</ns0:addBooks>
<array id="bookarray" xsi:type="enc:Array" enc:arrayType="xsd:string[3]">
<item>book1</item>
<item>book2</item>
<item>book3</item>
</array>
|
- 구조체 표기법 : class 형을 의미
<!-- 문법 -->
<env:Envelope
xmlns:구조체접두사=”구조체에_대한_네임스페이스_이름”>
<접두사:메소드명>
<구조체인자명 href="#식별자"/>
</접두사:메소드명>
<구조체_엘리멘트명 id="식별자" xsd:type="구조체접두사:구조체명">
<멤버변수명1 xsi:type=”테이터형”>값</멤버변수명1>
<멤버변수명2 xsi:type=”테이터형”>값</멤버변수명2>
</구조체_엘리멘트명>
|
<!-- 실제 사용예 -->
<env:Envelope xmlns:ns1=”http://cosmoslight/struct”>
<ns0:addBook>
<Book_1 href="#bookId01"/>
</ns0:addBook>
<book id="bookId01" xsi:type="ns1:Book">
<title xsi:type=”xsd:string”>Hello WebService</title>
<price xsi:type=”xsd:int”>29000</price>
</book>
|
SOAP 메시지를 전송하는 프로토콜
- SOAP과 전송 프로토콜을 접목시키는 작업을 binding이라고 함.
- HTTP 특징
- 연결 지향
- 무 상태
첨부 파일을 포함한 SOAP
- SOAP Messages with Attachments
- SOAP 메시지
- SOAP Part
- Attachment Part
8장. 웹서비스 시스템 개발
개발 순서
- 원격 프로시저를 정의하는 인터페이스 정의
- 패키지를 선언 해야 함.
- java.rmi.Remote 인터페이스를 상속 받아야 함.
- 반환형과 인자형은 JAX-RPC에서 지원하는 타입이어야 함.
- 원격 프로시저는 java.rmi.RemoteException을 반드시 thorws 해야 함.
package hello;
import java.rmi.*;
public inteface HelloIF extends Remote{
public String sayHello(String s) throws RemoteException;
}
|
- 원격 인터페이스를 구현한 클래스 작성
- 구현 클래스의 접근 제어자는 public
- 인자가 없는 default 생성자가 꼭 있어야 함.
package hello;
public class HelloImpl implements HelloIF{
public String sayHello(String s) throws RemoteException{
return “hello “+s+” !”;
}
}
|
- 배치 기술(DD) 작성
- web.xml 배치 기술자를 작성 : servlet 컨테이너에 배포시
- web.xml 기술되는 내용
- 세션에 대한 정보
- URL 매핑에 대한 정보
- 초기화에 대한 내용
- welcome file에 대한 정보
- web.xml 반드시 이어야 하는가 ?
- RMI interface 배치 기술자 작성 : jaxrpc-ri.xml 문서를 작성
<?xml version="1.0"?>
version="1.0"
targetNamespaceBase="$원격_프로시저의_네임스페이스명"
typeNamespaceBase="$구조체에_대한_네임스페이스명">
<endport
name="$웝서비스_시스템_이름"
interfae="$원격_인터페이스명"
implmentation="$구현_클래스명"/>
<endpointMapping
endpointName="$웝서비스_시스템_종정명"
urlPatter="$URL_경로"/>
</webService>
|
- targetNamespaceBase : 원격프로시저에 대한 네임스페이스명
- typeNamespaceBase : 구조체에 대한 네임스페이스명
- <endpoint> : 웹서비스 시스템의 원격 인터페이스와 구현 클래스 이름 기술
웹 서비스 시스템 이름 기술
- name : 웹서비스 시스템 이름
- <endpointMapping>
- endpointName : endpoint의 name 참조
- war 파일 생성 : 임시용
- Tie 클래스 와 WSDL 문서 생성
- wsdeploy.bat :
- 파일 위치 : jaxrpc 의 bin 디렉토리 위치
- 역할
- tie 클래스 생성
- WSDL 문서 자동 생성하여 WAR파일에 추가함.
- 명령어 : wsdeploy -o 결과.war 임시용.war
- WAR 패키징 및 배치
JAX-RPC에서 지원하는 Data Type
- 자바 기본 데이터 타입(Primitives Type)
- boolean
- byte
- short
- int
- long
- float
- double
- j2se sdk 클래스
- java.lang
- Boolean
- Byte
- Short
- Integer
- Long
- Float
- Double
- String
- java.math
- BigDecimal
- BigInteger
- java.util
- Calender
- Date
- Collection 타입의 클래스
- java.util.List
- ArrayList
- LinkedList
- Stack
- Vector
- java.util.Map
- HashMap
- Hashtable
- Properties
- TreeMap
- java.util.Set
- HashSet
- TreeSet
- Arrays
- 1차원 배열 뿐만 아니라 다차원 배열도 지원함.
- 사용자 정의 클래스 조건
- public 디폴트 생성자를 반드시 가져야 함
- java.rmi.Remote 인터페이스를 직접 또는 간접적으로 구현해서는 안됨.
- 모든 필드의 테이터 형은 JAX-RPC가 지원하는 타입으로 구성되어야 함
- 필드는 final 또는 transient로 선언되면 안됨
- 필드는 private 또는 protected 접근 지정자를 가져야 함
- 필드에 대한 public getter/setter 메소드를 가져야 한다.
9장. 웹 서비스의 명세화
목적
- 웹 서비스 제공자는 웹 서비스의 기능 WSDL로 문서로 작성해서 웹 서비스 소비자가 다운로드 받을 수 있도록 웹 서버에 저장 하고 WSDL 문서의 다운로드 URL을 UDDI 레지스트리에 공개 해야 함.
- WSDL 문서는 웹 서비스 코드로 부터 자동 생성하는 도구를 사용하여 작성됨.
WSDL 소개
- CORBA의 IDL와 비슷함.
WDSL 문서의 구조
- 도식
<definitions>
<types>
인자 및 리턴값에서 사용될 복합 타입 기술, [ 0 or 1 ]
</types>
<message>
인자 및 리턴값을 기술, [ 1 or n ]
</message>
<portType>
<operation>
원격 프로시저 기술, [ 1 or n ]
</operation>
[1 or n]
</portType>
<binding>
호출에 사용되는 프로토콜에 대한 정보 기술, [1 or n]
</binding>
<service>
<port>
웹 서비스 시스템의 URL(종점:endpoint) 기술, [1 or n]
</port>
[1 or n]
</service>
</definitions>
<!-- 부수적인 엘리멘트 들 -->
<documentation>
사람이 읽기 위한 주석 , [0 or n]
</documentation>
<import>
외부 파일에 정의되어 있는 내용을 참조, [0 or n]
</import>
|
<definitions> 엘리멘트
- WSDL에서 사용되는 네임스페이스들을 선언
- 속성
- name : WSDL 문서의 내부 이름을 기술
- targetNamespace : WSDL에서 정의하는 원격 프로시저에 대한 ns 이름 기술
- 관례적으로 많이 사용되는 네임스페이스
접두사
|
네임스페이스명
|
설명
|
wsdl
|
http://schemas.xmlsoap.org/wsdl/
|
WSDL에 대한 네임 스페이스
|
soap
|
http://schemas.xmlsoap.org/wsdl/soap/
|
SOAP 바인딩에 대한 네임 스페이스
|
http
|
http://schemas.xmlsoap.org/wsdl/http/
|
HTTP GET & POST 바인딩에 대한 네임스페이스
|
mime
|
http://schemas.xmlsoap.org/wsdl/mime/
|
MIME 바인딩에 대한 네임스페이스
|
soapenc
|
http://schemas.xmlsoap.org/soap/encoding
|
SOAP 1.1 인코딩에 대한 네임스페이스
|
soapenc
|
http://www.w3.org/2003/05/soap-encoding
|
SOAP 1.2 인코딩에 대한 네임스페이스
|
soapenv
|
http://schemas.xmlsoap.org/soap/envelope
|
SOAP 1.1 에 대한 네임스페이스
|
soapenv
|
http://www.w3.org/2003/05/soap-envelope
|
SOAP 1.2 에 대한 네임스페이스
|
xsi
|
http://www.w3.org/2000/10/XMLSchema-instance
|
XML Schema 인스턴스에 대한 네임스페이스
|
xsd
|
http://www.w3.org/2000/10/XMLSchema
|
XML Schema 에 대한 네임스페이스
|
tns
|
(various)
|
현재 WSDL 문서에 정의된 내용에 대한 네임스페이스
|
<message> 엘리멘트
- 원격 프로시저의 인자와 반환값에 대한 정보를 기술함.
- 속성 :
- name : 구분하기 위한 이름, 필수, <operation> 에서 참조함.
- <part> : 하위 엘리멘트, 인자 및 반환 값에 대한 정보를 기술
- 속성
- name : 변수 이름
- type : 데이터 타입 , Qname형태로 기술
- 문법
<message name="$메시지_이름">
<part name="$인자_반환_변수이름" type="$데이터타입"/>
</message>
|
<types> 엘리멘트
- 원격 프로시저의 인자 및 반환값에 사용되는 복합 타입을 기술하기 위한 엘리멘트
- 복합 타입을 사용하지 않으면 생략가능
- 기본 문법
<types>
<schema
targetNamespace="$복합_타입_ns명"
xmlns:tns="$복합_타입_ns명"
<complexType name="$복합타입명">
~
</complexType>
</schema>
</types>
|
- 사용예
- 배열 정의
<complexType name="$array_name">
<complexContent>
<restriction base="soap-enc:Array">
<attribute ref="soap-enc:arrayType" wsdl:arrayType="$data_type[]"/>
</restriction>
</complexContent>
</complexType>
|
- 구조체 정의 : 자바의 클래스에 해당됨
<complexType name="$class_name">
<sequence>
<element name="member_var_name" type="data_type"/>
<element name="member_var_name" type="data_type"/>
</sequence>
</complexType>
|
<portType>과 <operation> 엘리멘트
- <portType> : 자바의 인터페이스에 해당함.
- 하위에 여러 개의 <operation>이 존재 할 수 있음.
- 속성
- name : 필수, 일반적으로 인터페이스명 기술 됨. <binding>에서 참조함
- <operation> : 자바의 메소드에 해당함
- name : 원격 프로시저 즉 메소드명이 기술됨.
- parameterOrder : 인자들의 순서를 지정함
<message>의 <part> 들의 이름을 순서 대로 적는다. - <input> 엘리멘트
- 인자 정보를 기술
- message 속성에 <message> 엘리멘트 참조를 기술 함.
- <output> 엘리멘트
- 반환 값 정보를 기술
- message 속성에 <message> 엘리멘트 참조를 기술 함.
- 문법
<portType name="$interfaceName">
<operation name="$methodName" parameterOrder="$para1 $para2">
<input message="$message_elm_name"/>
<output message="$message_elm_name"/>
</operation>
...
</portType>
|
<binding> 엘리멘트
- 웹 서비스 시스템과 웹 서비스 소비자인 클라이언트 간의 통신 방법을 기술하는 엘리멘트
- 바인딩 이란 웹 서비스 시스템에 접속하는 것
- <binding> 의 속성
- name : 바인딩 이름, 필수, <service>에 참조됨
- type : <portType>의 name을 기술 함.
바인딩의 종류
- SOAP 바인딩
- HTTP 바인딩
- MIME 바인딩
SOAP 바인딩 작성 문법
- 문법
<binding name="$bindingName" type="$portTypeName">
<soap:binding
style="rpc|document"/>
<operation name="$operationName">
<soap:operation soapAction="HTTP SOAPAction Header Value"/>
<input>
<soap:body namespace="$operation_input_ns_name"
use="encoded"
encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
</input>
<output>
<soap:body namespace="$operation_output_ns_name"
use="encoded"
encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
</output>
<fault>
<soap:body namespace="$fault_ns_name"
use="encoded"
encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
</fault>
</operation>
</binding>
|
- <soap:binding>
- soap 는 xmlns:soap=”http://schemas.xmlsoap.org/wsdl/soap” 의 네임 스페이스 임
- 하위 속성
- transport : 전송 프로토콜의 네임 스페이스 이름을 기술
- style : 전달되는 SOAP 메시지의 형태를 기술
- rpc : 프로시저명과 인자를 포함하고 있음
- document : 단순 정보 전달용(기본값)
- <operation>
- name 속성 : <portType> 하위의 <operation>의 name
- <soap:operation>
- soapAction 속성
- HTTP를 전송용 프로토콜 사용할때는 반드시 언급해야 함.
- <input>
- 원격 프로시저의 파라미터에 대한 네임스페이스과 인코딩 방법을 기술
- <output>
- 원격 프로시저의 반환값에 대한 네임스페이스과 인코딩 방법을 기술
- <fault>
- 오류값을 표현에 대한 네임스페이스과 인코딩 방법을 기술
- <soap:body>의 속성
- namespace : 호출 및 결과를 표현하기 위한에 대한 네임스페이스 기술
- use : 인코딩 방법을 별도로 사용하는지에 대한 여부를 기술 (literal | encoded)
- literal : 인코딩 없이 그대로 전달
- encoded : encodingStyle에 선언된 방식을 사용한다는 뜻
- encodingStyle : 인코딩 방식
HTTP 바인딩 작성 문법
- 세가지 방식
- HTTP GET 방식 - URL 인코딩 방식
- HTTP GET 방식 - URL 대체 방식
- HTTP POST 방식
- 필요하면 정리
MIME 바인딩 작성 문법
- 필요하면 정리
<service>, <port> 엘리멘트
- 웹 서비스 시스템에 대한 URL 정보를 기술
- 작성 문법
<service name="$WebServiceName">
<!-- SOAP 바인딩 종점 URL 정보 -->
<port name="$PortName" bindig="$REF_bindingName">
<soap:address location="$WebService_URL"/>
</port>
<!-- HTTP 바인딩 종점 URL 정보 -->
<port name="$PortName" bindig="$REF_bindingName">
<http:address location="$WebService_URL"/>
</port>
</service>
|
- 속성 및 하위 요소 설명
- service.name : 웹 서비스명을 기술
- port.name : 포트 이름을 기술
- port.binding : <binding>의 이름 참조
- <soap:address> : 웹서비스가 soap 바인딩을 이용할 때 정보
- <http:address> : 웹서비스가 http 바인딩을 이용할 때 정보
- <soap:address> 나 <http:address>의 location :
- 실제 Web 서비스의 URL 기술함.
자동 생성된 WSDL 문서 보기
- 자동 생성 시
- <soap:address location="REPLACE_WITH_ACTUAL_URL"/> 부분을 수정해 주어야 한다.
- JAX-RPC에 제공하는 도구
- wsdeploy.bat : tie 클래스 생성및 WSDL 문서 자동 생성하여 WAR 파일에 추가함
- wscompile.bat : 웹 서비스 시스템의 인터페이스 및 구현 클래스 생성
- 관련 : config.xml 필요 wsdl 문서와 동일한 위치
- wscompile -import -keep config.xml
- keep : 소스 파일 생성하는 옵션
- config.xml
<?xml version="1.0" encoding="UTF-8"?>
<wsdl location="webservice.wsdl" packageName="book"/>
</configuration>
|
- 속성
- location : wsdl 문서의 위치
- packageName : 웹 서비스 시스템의 인터페이스 및 구현 클래스가 속하는 패키지를 지정함
12장. 웹 서비스 클라이언트 개발
JAX-RPC 클라이언트 호출 모델
- 정적 스텁 호출 모델
- 정적 스텁을 이용해서 원격 프로시저를 호출하는 모델
- 정적 스텁 : WSDL 문서를 이용해서 수동으로 생성된 스텁 클래스
- 동적 프록시 호출 모델
- 동적 프록시 하여 수동으로 스텁클래스를 생성하지 않고 호출하는 함.
- 동적 프록시 : 동적으로 생성되는 프록시 웹 서비스 시스템과 웹 서비스 클라이언트를 연결해
주는 스텁 클래스를 말함.
- 동적 호출 인터페이스 모델
- 클라이언트 측에서 원격 인터페이스명을 알지 못해도 동적으로 원격 메서드를 호출할 수
있도록 해주는 모델 - Call 객체를 이용함
- DII(동적 호출 인터페이스) : 동적으로 호출 가능한 인터페이스
웹 서비스 시스템 실행 확인
- 해당 URL로 시험 하여 결과 나타남.
- stub을 이용하기 위한 기본 정보 WSDL 문서에 있음 **
정적 stub 호출 모델
- stub 클래스 생성
- wscompile.bat 이라는 도구 사용 (jswdp의 jaxrpc/bin에 존재)
- 생성 문법
- wscompile -gen:client -d $output_dir config.xml
- -gen:client : 클라이언트 측 스텁을 생성 시키라는 option
- -d : 생성된 스텁을 저장할 디렉토리, 생략하면 현재 디렉토리 (.)
- config.xml 문서 필요 다음 내용을 포함 함.
- wsdl 문서를 다운로드 받는 URL
- location 속성 : 시스템 종점 URL 이나 UDDI 에서 구할 수 있음
- stub 클래스가 포함될 Package명
- packageName 속성 : 시스템 종점 URL에서 확인 가능
- 클라이언트 프로그램 소스 작성 순서
- 1 - 웹 서비스 시스템의 구현 객체를 참조하는 객체를 생성
- 관련 클래스 명은 <service>엘리멘트의 name 속성값 + _Impl 임
$(wsdl_service_name)_Impl.class
|
- 2 - stub 객체 얻기
Stub stub = (Stub)webServiceRef.get$PortName();
|
- 3 - 원격 인터페이스 객체로 형 변환
- 4 - 원격 프로시저 호출
- 전체 소스
package hello;
import javax.xml.rpc.Stub;
public class HelloClient{
public static void main(String[] args){
//1 - 웹 서비스 시스템 구현 객체 생성
WebService_Impl websvc = new WebService_Impl();
//2 - stub 객체 얻기
Stub stub = (Stub) websvc.getHelloIFPort();
//3 - 원격 인터페이스 객체로 형 변환
HelloIF hello = (HelloIF)stub;
//4 - 원격 프로시저 호출
String greet = hello.sayHello("cosmoslight");
System.out.println(greet);
}
} |
동적 Proxy 호출 모델 - 소스 작성
- ServiceFactory 객체 생성
- 관련 패키지 : javax.xml.rpc
- ServiceFactory 클래스 추상화 클래스 임.
- Service 객체 생성
- javax.xml.rpc.Service 인터페이스형 객체를 생성
- 생성시 필요한 정보
- wsdl 다운로드 URL
- 웹 서비스 네임스페이스명 - wsdl 문서에 있음
- <definitions>의 targetNamespace
- 웹 서비스명 - wsdl 문서에 있음
- <service>의 name
- stub 객체 생성하기
- 원격 인터페이스 객체로 형 변환
- 원격 프로시저 호출
- 전체 소스
package hello;
import javax.xml.rpc.*;
import javax.xml.namespace.*;
import java.net.*;
public class HelloClient{
public static void main(String[] args){
//1 - ServiceFactory 객체 생성
ServiceFactory svcFactory = ServiceFactory.newInstance();
//2 - Service 객체 생성
URL wsdlurl = new URL(
"Webservice");
Service service =
svcFactory.createService(wsdlurl,serviceQName);
//3 - stub 객체 생성하기
QName portQName = new QName("http://localhost:8080/hello/webservice/wsdl/webservice"
,"HelloIFPort")
Stub stub = (Stub) service.getPort(portQName,hello.HelloIF.class);
//4 - 원격 인터페이스 객체로 형 변환
HelloIF hello = (HelloIF)stub;
//5 - 원격 프로시저 호출
String greet = hello.sayHello("cosmoslight");
System.out.println(greet);
}
} |
동적 호출 인터페이스 모델 - 소스 작성
- ServiceFactory 객체 생성
- Service 객체 생성
- Call 객체 생성의 속성값 지정
구분
|
관려 메소드
|
설명
|
종점 지정
|
call.setTargetEndpointAddress("종점URL")
| |
SOAPACTION 사용 여부
|
call.setProperty(
Call.SOAPACTION_USE_PROPERTY,
new Boolean(true) or new Boolean(false));
|
false : 사용 안함 (기본값)
true : 사용함 (일반적)
|
SOAPACTION URI 지정
|
call.setProperty("URI");
|
SOAPACTION을 사용할 경우에 URI 경로가 없다면 “”로 지정해야 함.
|
SOAP 메시지 인코딩 지정
|
call.setProperty(
"javax.xml.rpc.encodingstyle.namespace.uri",
"http://schemas.xmlsoap.org/soap/encoding/");
|
기본 인코딩을 soap 인코딩으로 지정
|
원격 프로시저 이름 지정
|
call.setOperationName(
new QName("원격 프로시저 네임스페이스명",
"원격 프로시저명"));
|
원격 프로시저명은 WSDL 문서에 있는 <operation> 엘리멘트의 name 속성값과 동일해야 함
|
원격 프로시저 인자형 지정
|
call.addParameter("인자형",
"인자형"),
ParameterMode.IN);
|
addParameter는 인자 개수만큼 존재 해야 함.
인자명은 WSDL 문서에 있는 <part> 엘리멘트 name 속성명과 동일 해야 함.
인자형은 XML 스키마 언어의 빌트인 SympleType이 와야 함.
|
원격 프로시저 반환형
지정
|
"반환형"));
|
원격 프로시저의 반환형 지정
|
- Call 객체를 통해 원격 메소드 호출
소스
package hello;
import javax.xml.rpc.*;
import javax.xml.namespace.*;
import java.net.*;
public class HelloClient{
public static void main(String[] args){
//1 - ServiceFactory 객체 생성
ServiceFactory svcFactory = ServiceFactory.newInstance();
//2 - Service 객체 생성
URL wsdlurl = new URL(
"Webservice");
Service service =
svcFactory.createService(wsdlurl,serviceQName);
//3 - call 객체 생성하기 및 속성값 지정
QName portQName = new QName("http://localhost:8080/hello/webservice/wsdl/webservice"
,"HelloIFPort")
Call call = service.createCall(portQName);
call.setProperty(Call.SOAPCTION_USE_PROPERTY,new Boolean(true));
call.setProperty(Call.SOAPCTION_URI_PROPERTY,"");
call.setProperty("javax.xml.rpc.encodingstyle.namespace.uri",
"http://schemas.xmlsoap.org/soap/encoding/");
"sayHello"));
call.addParameter("String_1"
,ParameterMode.IN);
call.setReturnType("String_1"
//4 - Call 객체를 통해 원격 메소드 호출
Object params[] = {new String("cosmoslight")};
//5 - 원격 프로시저 호출
String greet = (String) call.invoke(params);
System.out.println(greet);
}
} |
SAAJ를 이용한 클라이언트
import java.io.*;
import java.util.*;
import javax.xml.parsers.*;
import org.w3c.dom.*;
import org.xml.sax.*;
import javax.xml.soap.*;
import javax.xml.transform.dom.*;
public class HelloClient {
/// Field
/// Constructor
/// Method
public static void main(String args[]) {
try {
//DOM 파서 생성
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setNamespaceAware(true);
DocumentBuilder parser = factory.newDocumentBuilder();
//요청 SOAP 메세지 DOMSource 생성
String sendMessage =
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>" +
"<env:Envelope " +
" xmlns:env=\"http://schemas.xmlsoap.org/soap/envelope/\"" +
" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"" +
" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"" +
" xmlns:enc=\"http://schemas.xmlsoap.org/soap/encoding/\"" +
" xmlns:ns0=\"http://localhost:8080/hello/webservice/wsdl/webservice\"" +
" env:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\">" +
" <env:Body>" +
" <ns0:sayHello>" +
" <String_1 xsi:type=\"xsd:string\">길동</String_1>" +
" </ns0:sayHello>" +
" </env:Body>" +
"</env:Envelope>";
StringReader reader = new StringReader(sendMessage);
InputSource is = new InputSource(reader);
Document document = parser.parse(is);
DOMSource requestSource = new DOMSource(document);
//SOAPMessage 객체 생성
MessageFactory messageFactory = MessageFactory.newInstance();
SOAPMessage requestSoapMessage = messageFactory.createMessage();
SOAPPart requestSoapPart = requestSoapMessage.getSOAPPart();
requestSoapPart.setContent(requestSource);
//SOAPConnection 객체 생성
SOAPConnectionFactory scf = SOAPConnectionFactory.newInstance();
SOAPConnection connection = scf.createConnection();
//요청 SOAP 메세지 보내고, 응답 SOAP 메세지 받기
SOAPMessage responseSoapMessage = connection.call(requestSoapMessage,
"http://localhost:8080/hello/webservice");
//응답 결과 얻기
SOAPPart responseSoapPart = responseSoapMessage.getSOAPPart();
SOAPEnvelope se = responseSoapPart.getEnvelope();
SOAPBody sb = se.getBody();
Name name = se.createName("sayHelloResponse","ns0",
"http://localhost:8080/hello/webservice/wsdl/webservice");
Iterator iterator = sb.getChildElements(name);
SOAPElement eSayHelloRespons = (SOAPElement) iterator.next();
name = se.createName("result");
iterator = eSayHelloRespons.getChildElements(name);
SOAPElement eResult = (SOAPElement) iterator.next();
iterator = eResult.getChildElements();
javax.xml.soap.Text text = (javax.xml.soap.Text) iterator.next();
System.out.println(text.getValue());
} catch(Exception e) {
e.printStackTrace();
}
}
}
|
댓글 없음:
댓글 쓰기