2019년 7월 8일 월요일

[책]기초에서 실무까지 XML 웹서비스

기초에서 실무까지 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 (링크)

추가적인 용어

약어

  • ns : NameSpace
  • tns : TargetNameSpace
  • xs : xml schema

1장 . 웹서비스 개요

웹서비스 구성 하는 3가지 요소

  1. 웹 서비스 제공자 : Provider
  • Publish : 서비스 공개
  1. 웹 서비스 중계자 : Broker
  • Find : 서비스 검색
  1. 웹 서비스 소비자 : Consumer
  • Bind : 특정 프로토콜을 이용해서 웹 서비스 시스템에 접속하는 것을 의미
UDDI : 공개 및 검색
  • 웹 서비스의 공개(publish) 와 검색(find)를 위한 XML 저장소(registory)의 구현과 사용 방법을 표준화 한것
WDSL : 웹 서비스 기술 언어
  • 표준화된 방식으로 웹 서비스의 인터페이스를 기술하는 XML 기술
SOAP : 단순 객체 접근 프로토콜
  • 정보 교환을 위해 필요한 구조를 표준화 한 것

2장 . 웹 서비스 개발 S/W

JWSDP 소개

JWSDP란

  • 자바에서 WS를 쉽게 구현 하기 위한 통합 개발 툴킷

JWSDP에 포함된 기술

  1. JAXP : Java API for XML Processing
  • DOM , SAX 파서를 생성, XML 문서를 해석하기 위한 API를 제공
  • 디폴트 파서 : Apache의 Xerces2를 사용
  • XSLT : XSL 문서를 사용하여 XML 문서를 변환
  • XSLT 엔진 : Apache의 Xalan 사용
  1. 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)
  1. JAXB : Java Architecture for XML Binding
  • Java object <-> XML 문서 (마샬링 , 언마샬링)
  • XML과 자바 코드 사이를 매핑하는 표준 방법을 제공
  1. JAXR : Java API for XML Registries
  • 여러 가지 종류의 XML 저장소에 일관 되게 접근하여 정보를 저장하거나 검색할 수 있는
    표준 API를 제공
  • XML 저장소 종류 의 예 : ebXML , UDDI 레지스트리
  1. SAAJ : SOAP with Attachments API for Java
  • SOAP 메시지를 생성하고 , 전송하는 API
  1. JAXM : Java API for XML Messaging
  • 비동기적인 웹 서비스 형태를 구현하기 위한 API 제공
  1. Tomact : 아파치 JSP 엔진
  2. 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 속성 : 네임스페이스와 스카마문서를 명시
  • 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"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <!-- 외부 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
  • SOAP 메시지 구조(1.2) xml schema 문서 URL

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
env:encodingStyle="http://www.w3.org/2003/05/soap-encoding"
<!-- 사용자 정의 속성 추가 -->
env:encodingStyle="http://www.w3.org/2003/05/soap-encoding http://cosmoslight/encoding"
  • 단순 타입 표기법

<엘리멘트 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장. 웹서비스 시스템 개발

개발 순서

  1. 원격 프로시저를 정의하는 인터페이스 정의
  • 패키지를 선언 해야 함.
  • 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;
}
  1. 원격 인터페이스를 구현한 클래스 작성
  • 구현 클래스의 접근 제어자는 public
  • 인자가 없는 default 생성자가 꼭 있어야 함.

package hello;
public class HelloImpl implements HelloIF{
   public String sayHello(String s) throws RemoteException{
      return “hello “+s+” !”;
   }
}
  1. 배치 기술(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 파일 생성 : 임시용
  1. Tie 클래스 와 WSDL 문서 생성
  • wsdeploy.bat :
  • 파일 위치 : jaxrpc 의 bin 디렉토리 위치
  • 역할
  • tie 클래스 생성
  • WSDL 문서 자동 생성하여 WAR파일에 추가함.
  • 명령어 : wsdeploy -o 결과.war 임시용.war
  1. 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>
  • 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 호출 모델 - 소스 작성

  1. ServiceFactory 객체 생성
  • 관련 패키지 : javax.xml.rpc
  • ServiceFactory 클래스 추상화 클래스 임.
  1. Service 객체 생성
  • javax.xml.rpc.Service 인터페이스형 객체를 생성
  • 생성시 필요한 정보
  • wsdl 다운로드 URL
  • 웹 서비스 네임스페이스명 - wsdl 문서에 있음
  • <definitions>의 targetNamespace
  • 웹 서비스명 - wsdl 문서에 있음
  • <service>의 name
  1. stub 객체 생성하기
  2. 원격 인터페이스 객체로 형 변환
  3. 원격 프로시저 호출
  4. 전체 소스

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(
     QName serviceQName = new QName("http://localhost:8080/hello/webservice/wsdl/webservice",
         "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);
  }
}

동적 호출 인터페이스 모델 - 소스 작성

  1. ServiceFactory 객체 생성
  2. Service 객체 생성
  3. 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.setReturnType(
 
new QName("http://www.w3.org/2001/XMLSchema",
    "반환형"));
원격 프로시저의 반환형 지정
  1. 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(
     QName serviceQName = new QName("http://localhost:8080/hello/webservice/wsdl/webservice",
         "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.setTargetEndpointAddress("http://localhost:8080/hello/webservice");
     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/");
     call.setOperation(new QName("http://localhost:8080/hello/webservice/wsdl/webservice",
          "sayHello"));
     call.addParameter("String_1"
          ,new QName("http://www.w3.org/2001/XMLSchema","string")
          ,ParameterMode.IN);
     call.setReturnType("String_1"
          ,new QName("http://www.w3.org/2001/XMLSchema","string"));
     //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(); 
    }   
  }
}

cosmoslight.huni@gmail.com님이 다음 문서를 첨부했습니다.

[책]기초에서 실무까지 XML 웹서비스
Google 문서: 온라인에서 문서를 만들고 수정해 보세요.
Google LLC, 1600 Amphitheatre Parkway, Mountain View, CA 94043, USA
다른 사용자가 Google 문서의 문서를 나와 공유하여 발송된 이메일입니다.
Google 문서 로고

댓글 없음: