You are on page 1of 61

Java Web Service

2004
Matt
Outline
 Web Service Concept
• Web Service and Java
 XML
 XML Parsing
 JAXB
 SOAP
 WSDL
 JAX-RPC
 SAAJ
 UDDI
 JAXR
2
Web Service 特點
 誇程式語言平台
• 底層的運作(資料的傳輸及服務的呼叫)皆以XML作為
local和remote溝通及互動的表達語言
• SOAP以XML為基礎並架構在HTTP之上
• SOAP是以文字為基礎的通訊協定

 Loosely coupling
• Web Services Description Language
• 動態地呼叫與使用Web Service所提供的服務

 動態服務的取得
• UDDI
3
Web Service 特點
 提供同步與非同步的運算模式
• 可以和Message Server整合
• IBM MQ Server, MS MSMQ

 透通防火牆的保護
• HTTP

4
Service-Oriented Architecture
 Service provider
broker

 Service requester

 Service broker provider requester

 XML, SOAP, WSDL, UDDI

5
Java Web Service
 Java WSDP (Web Service Developer Pack)

 Document-oriented package
• JAXP (Java API for XML Processing)
• JAXB (Java Architecture for XML Binding)
• SAAJ (SOAP with Attachment API for Java)

 Procedure-oriented package
• JAX-PRC (Java API for XML-based RPC)
• JAXR (Java API for XML Registries)

6
JAXP (Java API for XML Processing)
 剖析與存取XML文件的API
• DOM
• SAX

 文件轉換
• 如轉成HTML以顯示在網頁上

7
JAXB (Java Architecture for XML Binding)
 將XML Schema轉成Java類別的技術

 以便可以使用Java類別和XML文件進行互動,以
使在進行剖析與處理XML文件時變得更簡單及自

8
JAX-RPC (Java API fro XML-based RPC)
 Java的使用者可以利用JAX-RPC呼叫Server的
某一程序

 所有底層的運作都必須基於SOAP協定,這些部
份皆已經被JAX-RPC自動處理完畢了

9
JAXR (Java API for XML Registries)
 Web Service利用JAXR將其所提供的服務註冊
到UDDI Server中,而客戶則可以利用JAXR到
註冊Server中找尋所需的服務

10
SAAJ (SOAP with Attachments API for Java)
 透過SAAJ的使用,可以提供非同步運算的Web
Services

 讓Client和Server之間藉由【message】來做溝
通,Client可以不用保持在等待回應的狀態,可
先做其他的工作

11
Example

Registries

1.註冊服務
3.下載相關資料 (JAXR)
(JAXR)
2.查詢服務
(JAXR)

4.下載WSDL文件
5.request
(JAX-RPC)
Requester Provider
6.response
(JAX-RPC)

12
Outline
 Web Service Concept
• Web Service and Java
 XML
 XML Parsing
 JAXB
 SOAP
 WSDL
 JAX-RPC
 SAAJ
 UDDI
 JAXR
13
XML
 eXtensible Markup Language

 XML Schema

14
Outline
 Web Service Concept
• Web Service and Java
 XML
 XML Parsing
 JAXB
 SOAP
 WSDL
 JAX-RPC
 SAAJ
 UDDI
 JAXR
15
XML Parsing
 XML Parsing及文件轉換的功能由JAXP (Java API for
XML Processing)所提供

 XML Parsing模型有兩程
• DOM (Document Object Model)
• SAX (Simple API for XML)

 SAX
• Event-driven
• Serial的方式取得XML資料
 DOM
• 利用標籤間具有階層性的關係,在記憶體中以樹狀結構的方式重
現XML文件
• 利用traversal的演算法即可擷取XML文件中的資料,可以
ransom的方式存取tree上任一節點的資料
16
Used to create a SAX Handles document
SAX Parser events: start tag,
end tag, etc.

Handles
Parser
Errors

Handles
DTDs and
Entities
17
import java.io.*;
import org.xml.sax.*;
import org.xml.sax.helpers.DefaultHandler;
import javax.xml.parsers.SAXParserFactory;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.ParserConfigurationException;

public class BookListApp {


public static void main(String[] args){
try{
//取得SAXParserFactory之物件實體
SAXParserFactory factory = SAXParserFactory.newInstance();
factory.setValidating(true);

//取得JAXP所預設之SAX剖析器
SAXParser parser = factory.newSAXParser();

//取得Handler程式之物件實體,BookList_Handler程式已經繼承DefaultHandler類別
//下列用法是採用物件導向的多形特性。
DefaultHandler handler = new BookList_Handler();

//設定XML文件檔名與Handler程式,並開始進行剖析的工作
parser.parse(args[0], handler);
18
}catch (SAXParseException e1){
System.out.println("發生錯誤行數: " + e1.getLineNumber());
System.out.println("錯誤訊息: " + e1.getMessage());
}catch (ParserConfigurationException e2){
System.out.println(e2);
}catch(Exception e3){
System.out.println(e3);
}
}
}

19
/**
這個Handler物件就是用來和SAX剖析器進行互動之用
*/
import org.xml.sax.*;
import org.xml.sax.helpers.DefaultHandler;

public class BookList_Handler extends DefaultHandler{

//暫存XML資料的字串變數
StringBuffer txtBuf = null;

/**
文件相關的事件處理函數
*/
public void startDocument() throws SAXException{
System.out.println("開始剖析文件的工作");
}

public void endDocument() throws SAXException{


System.out.println("結束剖析文件的工作");
}

20
/**
元素相關的事件處理函數
*/
public void startElement(String nameSpace, String sName,
String qName, Attributes atts) throws SAXException{

//列印上一個XML資料
displayText();

//顯示標籤的名字
String name = sName;
if (name.equals(""))
name = qName;

System.out.println("開始剖析元素:" + name);

//取得該元素的所有屬性
if (atts != null){
for (int i = 0; i < atts.getLength(); i++){
//取得元素的名稱
String aName = atts.getLocalName(i);
if (aName.equals(""))
aName = atts.getQName(i);
21
System.out.println("元素:" + name + "的屬性:"
+ aName + "為:" + atts.getValue(i));
}
}
}

public void endElement(String nameSpace, String sName,


String qName) throws SAXException{
//列印上一個XML資料
displayText();

//顯示標籤的名字
String name = sName;
if (name.equals(""))
name = qName;

System.out.println("結束剖析元素:" + name);
}

/**
文字事件相關的處理函數
*/
22
public void characters(char[] buf, int offset,
int len) throws SAXException{
String str = new String(buf, offset, len);

//合併XML資料
if (txtBuf == null)
txtBuf = new StringBuffer(str);
else
txtBuf.append(str);
}

/*
public void ignorableWhitespace(char buf[],
int offset, int len) throws SAXException{
System.out.println("忽略資料");
}
*/

/**
印出XML資料
*/
public void displayText(){
if (txtBuf == null)
return; 23
System.out.println("解析出來的文字:->" + txtBuf + "<-");

txtBuf = null;
}

/**
其它有用的成員函數
*/
public void setDocumentLocator(Locator local){
System.out.println("system ID:" + local.getSystemId());
System.out.println("public identifier:" + local.getPublicId());
}

public void processingInstruction(String appName,


String data) throws SAXException{
System.out.println("應用程式名稱:" +
appName + ",初始參數:" + data);
}
}

24
DOM

A
P Application

XML File DOM Parser DOM Tree I

25
/**
本程式是用來取得DOM剖析器之物件實體.
*/
import java.io.*;

//與DOM剖析器相關的類別
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.FactoryConfigurationError;
import javax.xml.parsers.ParserConfigurationException;

//剖析過程中所會引發的例外事件(和SAX剖析器共用)
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;

//與DOM相關的例外事件
import org.w3c.dom.Document;
import org.w3c.dom.DOMException;

import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

26
public class BookListDOMApp {
public static void main(String[] args){
try{

//取得 DocumentBuilderFactory 之物件實體


DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();

//設定判斷有效性
factory.setValidating(true);

//設定判斷命名空間
factory.setNamespaceAware(true);

//設定是否忽略註解
factory.setIgnoringComments(true);

//設定是否忽略空白
factory.setIgnoringElementContentWhitespace(true);

//設定是否要展開實體參考
factory.setExpandEntityReferences(true);
27
//將CDATA結點轉換成Text結點
factory.setCoalescing(true);

//取得DOM剖析器
DocumentBuilder builder = factory.newDocumentBuilder();

//委託剖析例外事件
builder.setErrorHandler(new BookListDOM_ErrorHandler());

//建立DOM樹狀結構
Document document = builder.parse(new File(args[0]));

//取得根結點
Node node = document.getDocumentElement();

//取得根結點的所有子元素
NodeList nodeList = node.getChildNodes();
for (int i = 0; i < nodeList.getLength(); i++) {
Node node2 = nodeList.item(i);

28
System.out.println("-----------------分割線---------------------");
System.out.println("getNodeName():" + node2.getNodeName());
System.out.println("getNodeValue():" + node2.getNodeValue());
System.out.println("getNodeType():" + node2.getNodeType());
System.out.println("getAttributes():" + node2.getAttributes());
}

}catch (SAXParseException e1){


System.out.println("發生錯誤行數: " + e1.getLineNumber());
System.out.println("錯誤訊息: " + e1.getMessage());
}catch (ParserConfigurationException e2){
System.out.println(e2);
}catch(Exception e3){
System.out.println(e3);
}
}
}

29
import java.io.*;
import javax.xml.parsers.*;
import org.xml.sax.*;
import org.w3c.dom.*;

public class BookListDOMRecursive {

public static void main(String[] args){


new BookListDOMRecursive(args[0]);
}

public BookListDOMRecursive(String fileName){


try{

//取得 DocumentBuilderFactory 之物件實體


DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();

//設定判斷有效性
factory.setValidating(false);

//設定判斷命名空間
factory.setNamespaceAware(true);
30
//設定是否忽略註解
factory.setIgnoringComments(true);

//設定是否忽略空白
factory.setIgnoringElementContentWhitespace(true);

//設定是否要展開實體參考
factory.setExpandEntityReferences(true);

//將CDATA結點轉換成Text結點
factory.setCoalescing(true);

//取得DOM剖析器
DocumentBuilder builder = factory.newDocumentBuilder();

//建立DOM樹狀結構
Document document = builder.parse(new File(fileName));

//取得根結點
Node node = document.getDocumentElement();

//執行巡行XML文件的功能
recursiveXML(node, 0);
31
}catch (SAXParseException e1){
System.out.println("發生錯誤行數: " + e1.getLineNumber());
System.out.println("錯誤訊息: " + e1.getMessage());
}catch (ParserConfigurationException e2){
System.out.println(e2);
}catch(Exception e3){
System.out.println(e3);
}
}

//遞迴函數, 用以巡行整份XML文件
public void recursiveXML(Node node, int esc){

//列印空白區隔字元
for (int k = 0; k < esc; k++)
System.out.print(" ");

if (node.getNodeType() == 1) {
//元素為標籤(Element)型態
//列印標題名稱
System.out.print("Element: " + node.getNodeName() + "\n");
32
//取得結點的所有子元素
NodeList nodeList = node.getChildNodes();

//進入遞迴過程
for (int i = 0; i < nodeList.getLength(); i++) {
recursiveXML(nodeList.item(i), esc + 4);
}
} else if (node.getNodeType() == 3) {
//元素為一般文字型態
//列印文字內容
System.out.print("Text: " + node.getNodeValue() + "\n");
}
}

33
Outline
 Web Service Concept
• Web Service and Java
 XML
 XML Parsing
 JAXB
 SOAP
 WSDL
 JAX-RPC
 SAAJ
 UDDI
 JAXR
34
JAXB:XML文件的物件化

35
 JAXB機制是由以下三大類別所組成
• javax.xml.bind
• javax.xml.bind.util
• javax.xml.bind.helper

 Marshal
• object ->xml
 Unmarshal
• xml ->object

36
Example
 recommandBook.xml
 recommandBook.xsd

 xjc recommandBook.xsd
 產生generated\...

 若要修改recommandBook.xml檔
• 利用unmarshaller物件把XML轉換成content tree
• 修改
• Marshaller物件做正向編組
• 另存新檔.xml
37
import java.io.*;
import java.util.*;
import javax.xml.bind.*;
import javax.xml.bind.util.*;
import generated.*;

public class RBookModifier {

public RBookModifier(){
try {

//取得JAXBContext物件, 並設定Java套件名稱
JAXBContext jc = JAXBContext.newInstance("generated");

//取得提供Unmarshal功能的物件
Unmarshaller um = jc.createUnmarshaller();

//指定欲Unmarshal的XML文件, 及取得XML根元素
RecommandBook rb = (RecommandBook)um.unmarshal(new
FileInputStream("tempBook.xml"));

//取得ProductsType子元素
ProductsType rt = rb.getProducts();
38
//取得MainProductType子元素
MainProductType mpt = rt.getMainProduct();

//更改主約產品保險額度
mpt.setMpCoverage(200);

//更改主約產品保險費率
mpt.setMpFee((double)2000);

//取得驗證內容樹的物件
javax.xml.bind.Validator vt = jc.createValidator();

//設定欲驗證之內容樹根元素
boolean b = vt.validateRoot(rb);

if (b)
System.out.println("符合有效性");

Marshaller m = jc.createMarshaller();
m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT,Boolean.TRUE);
m.marshal(rb, new FileWriter("tempBook.xml"));;
39
}catch (Exception e){
System.out.println("Err: " + e);
}
}

public static void main(String[] args){


new RBookModifier();
}
}

40
Outline
 Web Service Concept
• Web Service and Java
 XML
 XML Parsing
 JAXB
 SOAP
 WSDL
 JAX-RPC
 SAAJ
 UDDI
 JAXR
41
SOAP
 SOAP被看做是實作RPC機制的通訊協定,也是
• Object remote procedure call
• Messaging
• xml transform
 SOAP message包括 XML content
• SOAP envelope
• SOAP encoding rules SOAP message
• SOAP RPC representation
HTTP protocol

TCP/IP protocol
42
Outline
 Web Service Concept
• Web Service and Java
 XML
 XML Parsing
 JAXB
 SOAP
 WSDL
 JAX-RPC
 SAAJ
 UDDI
 JAXR
43
WSDL
 WSDL只是說明存取某一服務的通訊協定,
function name,參數型態等資訊

 W3C對SOA架構的規範,描述服務的完整資訊包

• Agreement
• Relationship
• detail

44
business

service

composition

orchestration
WSDL

presentation

policy
Implementation
description
Interface
description
45
WSDL Spec
 六個元素
• Services
Implementation
• Port Description
• Types
• Message Interface
• PortType Description

• Binding

46
Types
 執行訊息交換時新增的資料型態
 XML Schema

<types>
<myNewType/>
</types>

47
Message
 那些資訊需要傳輸

48
PortType
 定義Web Service傳送接收的作業
• Function name
• Parameter

49
Binding
 SOAP Binding
 HTTP Get/Post Binding
 MIME Binding

50
Port
 提供Web Service的端點位置

51
Service
 可利用Service把所有port包起來

52
Outline
 Web Service Concept
• Web Service and Java
 XML
 XML Parsing
 JAXB
 SOAP
 WSDL
 JAX-RPC
 SAAJ
 UDDI
 JAXR
53
JAX-RPC
 以JAX-RPC來實作Web Service中的SOAP及
WSDL機制

 JAX-RPC runtime指的就是應用程式伺服器

54
Static Stub
package freejavaman;

import javax.xml.rpc.Stub;

public class HelloWorld_RPC_Client {

public static void main(String[] args) {


try {
//取得Stub介面
Stub stub = (Stub)(new MyHelloWorld_Impl().
getHelloWorld_RPC_InterfacePort());

//強制轉換成伺服端介面
HelloWorld_RPC_Interface hello = (HelloWorld_RPC_Interface)stub;

//使用WEB Service服務
System.out.println(hello.sayHello("FreeJavaMan"));
} catch (Exception e) {
System.out.println(e);
}
} 55

}
Dynamic Stub
package freejavaman;

import java.net.URL;
import javax.xml.rpc.Service;
import javax.xml.rpc.JAXRPCException;
import javax.xml.namespace.QName;
import javax.xml.rpc.ServiceFactory;

public class HelloWorld_Proxy_Client {

public static void main(String[] args) {


try {
String UrlString = "http://localhost:8080/myWS/hello?WSDL";
String nameSpaceUri = "http://com.test/wsdl/MyHelloWorld";
String serviceName = "MyHelloWorld";
String portName = "HelloWorld_RPC_InterfacePort";

URL helloWsdlUrl = new URL(UrlString);

//取得對映至伺服端的Service物件
ServiceFactory serviceFactory = ServiceFactory.newInstance(); 56
Dynamic Stub
Service helloService = serviceFactory.createService(helloWsdlUrl,
new QName(nameSpaceUri, serviceName));

//取得遠端服務介面
HelloWorld_RPC_Interface myProxy = (HelloWorld_RPC_Interface)
helloService.getPort(new QName(nameSpaceUri, portName),
freejavaman.HelloWorld_RPC_Interface.class);

System.out.println(myProxy.sayHello(" Allan"));
} catch (Exception e) {
System.out.println(e);
}
}
}

57
Dynamic Invocation Interface (DII)
package freejavaman;

import javax.xml.rpc.Call;
import javax.xml.rpc.Service;
import javax.xml.rpc.JAXRPCException;
import javax.xml.namespace.QName;
import javax.xml.rpc.ServiceFactory;
import javax.xml.rpc.ParameterMode;

public class HelloWorld_Dynamic_Client {

private static String endpoint = "http://127.0.0.1:8080/myWS/hello";


private static String qnameService = "MyHelloWorld";
private static String qnamePort = "HelloWorld_RPC_InterfacePort";
private static String BODY_NAMESPACE_VALUE =
"http://com.test/wsdl/MyHelloWorld";

private static String ENCODING_STYLE_PROPERTY =


"javax.xml.rpc.encodingstyle.namespace.uri";
private static String NS_XSD = "http://www.w3.org/2001/XMLSchema"; 58
Dynamic Invocation Interface (DII)
private static String URI_ENCODING =
"http://schemas.xmlsoap.org/soap/encoding/";

public static void main(String[] args) {


try {
//取得伺服器上的Service
ServiceFactory factory = ServiceFactory.newInstance();
Service service = factory.createService(new QName(qnameService));

QName port = new QName(qnamePort);

Call call = service.createCall(port);


call.setTargetEndpointAddress(endpoint);

//設定遠端呼叫之基本參數值
call.setProperty(Call.SOAPACTION_USE_PROPERTY, new Boolean(true));
call.setProperty(Call.SOAPACTION_URI_PROPERTY, "");
call.setProperty(ENCODING_STYLE_PROPERTY, URI_ENCODING);

59
Dynamic Invocation Interface (DII)
//設定回傳型態
QName QNAME_TYPE_STRING = new QName(NS_XSD, "string");
call.setReturnType(QNAME_TYPE_STRING);

//設定WEB Service函數名稱
call.setOperationName(new QName(BODY_NAMESPACE_VALUE,
"sayHello"));
call.addParameter("String_1", QNAME_TYPE_STRING, ParameterMode.IN);

//呼叫遠端函數
String[] params = { " Everybody" };
String result = (String)call.invoke(params);

//顯示執行結果
System.out.println(result);

} catch (Exception e) {
System.out.println(e);
}
}
} 60
Outline
 Web Service Concept
• Web Service and Java
 XML
 XML Parsing
 JAXB
 SOAP
 WSDL
 JAX-RPC
 SAAJ
 UDDI
 JAXR
61

You might also like