You are on page 1of 400

e -XML/Java/SOAP

2001/03/16
957-2085-11-5
ISBN957-2085-11-5
Growbal

e -XML/Java/SOAP
XML ,.
Java Write once ,run anywhere ,,
.
-XML,-Java,.
, XSL ,SAXDOM Java

XML ,

XML-RPC , SOAP Web Service, Java Applet Application


Servlet JSP XML .
,:

XML

XML

Applet

Java Servlet

Java Beans

SOAP

XSLT

Java

Java Application

JSP

XML-RPC

1.

. XML
. XML
. Java XML
.
1

2. XML

.
.
.

XML

. Namespaces
. XPath
.
. XLink XPointer
3. XML Parsers

.
.

DOM SAX

. AELfred XML Parser


. Apache Xerces XML Parser
. Sun JAXPJava API for XML parsing
4. Java/XML

. Java/XML
. Client side Java XML
. Server side Java XML
. XSLT XPath
. XML-RPCRemote Procedure Call
. SOAPSimple Object Access Protocol
5.

. e-CommerceEDIEAI
.
.
. JDBC
. B2B2C
. B2C
. Web Service
. B2B
.
. SOAP service
.
.
.

B2B



Web 100% 0%

SunMicrosoftIBM XML
XML XML XML

XML
XML Java XML

XML Java Java/XML

ibookPress www.ibookpress.com

E-mail javaxml@pchome.com.tw
3


Arthur

From: Arthur Tseng


Sent: Tuesday, August 01, 2000 6:57 PM
Subject:

Dear growbal:
Linuxer

Linux

Linux
Emily

......................................................................................................................................7
1.1
1.2
1.3
1.4

XML.............................................................................................................................7
XML ....................................................................................................9
Java XML..............................................................................................................13
................................................................................................................15
XML .................................................................................................................18
2.1
XML .................................................................................................18
2.2
........................................................................................................21
2.3
............................................................................................................27
2.4
2.5
2.6
2.7

Namespaces................................................................................................................33
XPath..........................................................................................................................35
........................................................................................................................46
XLink XPointer.....................................................................................................67

XML Parsers ..........................................................................................................70


3.1
............................................................................................................70
3.2
DOM SAX ...........................................................................71
3.3
AELfred XML Parser.................................................................................................75
3.4
Apache Xerces XML Parser.......................................................................................89
3.5
Sun JAXPJava API for XML parsing ..............................................................103
Java/XML ................................................................................................................ 115
4.1
Java/XML .............................................................................. 115
4.2
Client side Java XML ........................................................................120
4.3
Server side Java XML ........................................................................151
4.4
XSLT XPath ...............................................................................................189
4.5
XML-RPCRemote Procedure Call...........................................................209
4.6
SOAPSimple Object Access Protocol......................................................232
......................................................................................................266
5.1
e-CommerceEDIEAI ..........................................................266
5.2
..........................................................................................................268
5.3
..................................................................................................270
5.4
JDBC .......................................................................................................276
5.5
B2B2C .................................................................................278
5.6
B2C ........................................................................................................279
5.7
Web Service ...........................................................................................318
5.8
B2B ........................................................................................................368
5.9
..........................................................................................................................386
5.10
SOAP service ..........................................................................................387
5.11
..........................................................................................................388
5

5.12
5.13

..........................................................................................................392
..................................................................................................................398

1.1 XML
...
XML XML XML
XML
Java XML

XML XML
eXtensible Markup LanguageXML
1998 2 10 XML World Wide Web ConsortiumW3C
Recommendation

XML
XML
<?xml version="1.0"?>
<!DOCTYPE books [
<!ELEMENT books book+>
<!ELEMENT book title,author,qty>
<!ELEMENT title #PCDATA>
<!ELEMENT author #PCDATA>
<!ELEMENT qty #PCDATA>
]>
<books>
<book>
<title>Java XML</title>
<author>Growbal</author>
<qty>30</qty>
<price unit="NTD">500</price>
</book>
<book>
7

<title>Palm Programming</title>
<author>Kuo</author>
<qty>40</qty>
<price unit="NTD">500</price>
</book>
<books>
XML XML Document Type
DefinitionDTD XML XML
2

XML
1.
XML
2.
XML XML
3.
DTD XML SchemaXML XML Schema
XML
XML
4.
XML

XML SGMLStandard Generalized Markup Language


SGML ISOInternational Standard Organization8879:1986

SGML SGML
SGML

HTMLHypertext Markup Language


HTML WWWWorld Wide Web
HTMLWWW Internet
HTML SGML HTML
tag HTML
8

WWW HTML WWW

IntranetHTML
HTML HTML
HTML HTML

XMLExtensible Markup Language


WWW HTML SGML
XML
SGML HTML

1.2 XML
XML
Web
application

XML XML
XSL HTMLWML

Electronic Data Interchange

EDIElectronic Data InterchangeValue-Added


NetworkVAN X12 EDIFACT
9

B2B EDI B2B


EDI
EDI VANEDI

ISA*00*

*00* *08*61112502RSR

*01*TEST KK000001

*010108*1137*U00102000001768*0*P?
GS*PO*6111250211*KK000001 *010108*1137*9788*X*003021
ST*850*397823
BEG*00*RE*4321**010201
REF*AH*M119
REF*DP*651
REF*IA*000100767
DTM*010*010111
N1*BY*91*1288
N1*ST*91*87446
N1*ZZ*991*1288
PO1*1*1*EA*13.34**CB*80221*IZ*365*UP*718379271642
PO1*1*2*EA*13.34**CB*80222*IZ*384*UP*718379271574
PO1*1*3*EA*13.34**CB*80223*IZ*322*UP*718379271498
PO1*1*4*EA*13.34**CB*80224*IZ*361*UP*718379271849
PO1*1*5*EA*13.34**CB*80225*IZ*365*UP*718379271006
CTT*26
SE*36*397823
GE*1*9785
IEA*1*000009562
EDI EDI
EDI
EDI
XML XML
EDI XML XML

HTTP WWWXML HTTP


Internet
XML XML
XML XML
XML EDI

10

XML XML 1.0


Document Type DefinitionDTD XML DTD
XML DTD
XML Schema XML XML
XML EDI XML

XML EDI XML-EDIhttp://www.xmledi.net EDI


EDI
XML-EDI EDI
XML-EDI XML Internet EDI
EDI EDI EDI
EDI XML-EDI XML-EDI EDI
XML EDI

e-Commerce

Business-to-businessB2B

Business-to-customerB2C

EDI B2B

Enterprise Application IntegrationEAI

11

Linux Server
SQL EAI

XMLXML
XML COBOL
XML XML

Middleware
XML

XML

Electronic Publishing
12

XML SGML XML

W3C XML XSLeXtensible


Stylesheet LanguageXSL XSLTXSL Transformation FOFormating Object
XML XML HTMLWML XML

XML

XML XML
XML meta-language
4 XML-RPCSOAP XML
Sun J2EEJava 2 Enterprise Edition.NET XML
XML

1.3 Java XML


Java XML
Java XML Web application
ECEDIERPEAI Java XML
Java XML

Java
Java IA
Java WWW Internet
Internet WWW Java Applet
Java Applet Internet
Java
Java Java Java
Java Java
Java API

13

1997 Java Servlet Java Servlet Java


javax.servlet
Servlet CGI Java
Servlet Servlet Servlet Java
Visual Machine CGI

1999 6 Sun JSPJava Server Pages Java Servlet


Java JSP Java Java Beans Java Servlet

Java XML Java Unicode


Big5
GB
Java Unicode
Java API

Java XML XML


XML Java XML Java
XML Sun Java XML API
Java API for XML ParsingJAXP XML
XML APIJAXP XML
XML XSLTXSL Transformation Clark's xtApache Xalan
Apache SOAP for JavaXML-RPCGMD-IPSI XQL Engine XML Java
Java XML

Java
Java
write once, run anywhere Java Java
Visual MachineJVM Java
tier
3-tier
Java
Windows NT/2000 Server Java
Unix/Linux Server

Java
14

Java API Java


XML XML
node XML node tree Java
XML Java

Java API
Java API
Java

1.4

XML Java

Fat client

15

data tier
Persistence tier
URL

client tier

middle tier

CGI request

CGI
Script language PHPCold FusionASP
markup

.
Delivery tier
Construction tier

16

Delivery tierConstruction tier

...
XML
http://www.w3c.org http://xmlhack.com/ http://www.xml.com
XML xml java EC

17

2 XML
2.1 XML
...
XML
well-formedXML
DTDDocument Type DefinitionvalidXML
Namespaces XML XML
XML XPathXPointer XLink
XML Cascading Style SheetsCSSeXtensible
StylesheetFormating ObjectsFO
XML XPath XSL Transformation XSLT
XML Schema XML
XML XML Java XML

XML
XML UNIX vijoejedDOS edit
pe2qeditWindows notepad
XML
XML XML XML
XML

XML Windows notepad


18

XML XML
XML DTDXML schemastylesheet
XML XML
XML XML
XML XML Internet

Merlot
Java XML Mer-lo ChannelPoint, Inc. Mer-lotXML.org Merlot
DTDvalid XML

Merlot

Merlot
Java 2 Standard Edition
Java LinuxWindowsSolarisMac
32MB RAM

http://java.sun.com/j2se/ J2SE JREJava runtime environment


classpath
http://www.merlotxml.org/ Merlot

java -jar Merlot-1.0rc2.jar

Morphon XMLEditor
Morphon Java XML Version 1.0 beta 8.01
XML CSS
XML IBM XML4J DTD

19

Morphon XMLEditor

Java 2 Standard Edition


Java LinuxWindowsSolarisMac

http://java.sun.com/j2se/ J2SE JREJava runtime environment


classpath
http://www.morphon.com/ Morphon

Unix runXMLEditor1.2.sh Windows runXMLEditor1.2.bat


JAVA_HOME JDK

Microsoft XML notepad


XML Windows Microsoft Internet Explorer 4.0
IE 4.0service pack 1 IE XML beta 1.5
XML Processing Instrument
<?xml version="1.0"?> DTD
DTD XML IE 5 XML Schema XML
XML Schema
XML

20

XML notepad

Microsoft http://www.microsoft.com xpsetup.exe

Windows

2.2
eXtensible Markup Language; XML
XML www.w3c.org
XML
www.w3c.org XML

XML

XML .xml XML

XML declaration
XML XML XML
<?xml?>
XML
21

version="1.0"
encoding="Big5"
standalone="yes"
XML
<?xml version="1.0" encoding="Big5" standalone="yes"?>
XML XML

version declaration
XML 1.0 XML 1.0
XML
XML default

encoding declaration
26 ASCII 128

Big5 GB EUC-JP Shift-JISinternationalizationi18n


UnicodeUTF-8UTF-16
XML XML
http://www.w3c.org/international/

UTF-8

Unicode

UTF-16

16 32 Unicode

Big5

GB2312

Shift-JIS Windows
EUC-JP

Unix

XML UTF-8 XML

standalone declaration
XML DTDDocument Type Definition
XML standalone="yes" XML
standalone="no" standalone
XML
<?xml version="1.0" encoding="UTF-16" standalone="yes"?>
XML DTD standalone
<?xml version="1.0"

encoding="UTF-16" ?>
22

<!DOCTYPE DOCUMENT SYSTEM "/dtd/test.dtd">


........

Content
XML XML XML

Element
tag
XML
start tagend tag
<book> Java XML </book>

<book> </book>

HTML XML
DTD
empty-element tag

<br> </br>

<br/>

attribute
HTML HTML <BR>
HTML <IMG> XML

<br/>

23

<image source="img/picture1.tif"/>

XML XML

<book>

<name>Java XML</name>

<author>

<name>Growbal</name>

<email>growbal@taiwan.com</email>

</author>

<publish>

<date>2001-02-01</date>
</publish>
</book>

XML

<book>
<name>Java XML</name>
<author>
<name>Growbal
<email>growbal@taiwan.com
</name>
</email>
</author>
<publish><date>2001-02-01<publish></date>
</book>
<name><email><publish><date>
HTML XML

Attribute

1
<text fontsize="5" color="red">
This is an attribute demo.
24

</text>
2
<image source="picture.tif" />
fontsizecolor source

1
<text>
<fontsize>5</fontsize>
<color>red</color>
This is an attribute demo.
</text>
2
<image>
<source>picture1.tif</source>
</image>
XML

Entity
entity

XML

&amp;

&

&apos;

'

&gt;

>

&lt;

<

&quot;

"

<tv_program>Barney &amp; friends</tv_program>

Barney & friends

Unicode
&#x
25


&#

&#x00E0;

&#224;
alpha

CDATA section
CDATA character data XML
XML CDATA
<xml_sample>
<![CDATA[<xmldemo> XML
</xmldemo> XML
]]>
</xml_sample>
CDATA
<![CDATA[ ]]>
CDATA ]]> ]] >
> >

XML comment
XML
<!-- --> XML
<!-- -->
XML HTML
XML PIProcessing Instruction
<? Xml version="1.0" encoding="UTF-16"<!-- XML --> ?>
XML SGML
<!-- XML -- 89.10.18 -->

<anima>
TOTORO
<!--

-->

</anima>

well-formedXML
XML
well-formedXML
XML
<book>
<anima>
26

<title time="18:00">
MACROSS
</title>
<food></food>
<machine>
DVD player
<car>Porsche 911</car>
<paper size="A4"/>
</machine>
</anima>
<flightsim>Warbirds</flightsim>
<palmtype>
Palm V
</palmtype>
</book>

well-formedXML XML
DTD

2.3
eXtensible Markup Language; XML
XML www.w3c.org
XML
www.w3c.org XML

XML

XML .xml XML

XML declaration
XML XML XML

27

<?xml?>
XML
version="1.0"
encoding="Big5"
standalone="yes"
XML
<?xml version="1.0" encoding="Big5" standalone="yes"?>
XML XML

version declaration
XML 1.0 XML 1.0
XML
XML default

encoding declaration
26 ASCII 128

Big5 GB EUC-JP Shift-JISinternationalizationi18n


UnicodeUTF-8UTF-16
XML XML
http://www.w3c.org/international/

UTF-8

Unicode

UTF-16

16 32 Unicode

Big5

GB2312

Shift-JIS Windows
EUC-JP

Unix

XML UTF-8 XML

standalone declaration
XML DTDDocument Type Definition
XML standalone="yes" XML
standalone="no" standalone
XML
28

<?xml version="1.0" encoding="UTF-16" standalone="yes"?>


XML DTD standalone
<?xml version="1.0"

encoding="UTF-16" ?>

<!DOCTYPE DOCUMENT SYSTEM "/dtd/test.dtd">


........

Content
XML XML XML

Element
tag
XML
start tagend tag
<book> Java XML </book>

<book> </book>

HTML XML
DTD
empty-element tag

<br> </br>

<br/>

attribute
HTML HTML <BR>
HTML <IMG> XML

<br/>
29


<image source="img/picture1.tif"/>

XML XML

<book>

<name>Java XML</name>

<author>

<name>Growbal</name>

<email>growbal@taiwan.com</email>

</author>

<publish>

<date>2001-02-01</date>
</publish>
</book>

XML

<book>
<name>Java XML</name>
<author>
<name>Growbal
<email>growbal@taiwan.com
</name>
</email>
</author>
<publish><date>2001-02-01<publish></date>
</book>
<name><email><publish><date>
HTML XML

Attribute

1
30

<text fontsize="5" color="red">


This is an attribute demo.
</text>
2
<image source="picture.tif" />
fontsizecolor source

1
<text>
<fontsize>5</fontsize>
<color>red</color>
This is an attribute demo.
</text>
2
<image>
<source>picture1.tif</source>
</image>
XML

Entity
entity

XML

&amp;

&

&apos;

'

&gt;

>

&lt;

<

&quot;

"

<tv_program>Barney &amp; friends</tv_program>

Barney & friends


31

Unicode
&#x

&#

&#x00E0;

&#224;
alpha

CDATA section
CDATA character data XML
XML CDATA
<xml_sample>
<![CDATA[<xmldemo> XML
</xmldemo> XML
]]>
</xml_sample>
CDATA
<![CDATA[ ]]>
CDATA ]]> ]] >
> >

XML comment
XML
<!-- --> XML
<!-- -->
XML HTML
XML PIProcessing Instruction
<? Xml version="1.0" encoding="UTF-16"<!-- XML --> ?>
XML SGML
<!-- XML -- 89.10.18 -->

<anima>
TOTORO
<!--

-->

</anima>

well-formedXML
XML
well-formedXML
XML
32

<book>
<anima>
<title time="18:00">
MACROSS
</title>
<food></food>
<machine>
DVD player
<car>Porsche 911</car>
<paper size="A4"/>
</machine>
</anima>
<flightsim>Warbirds</flightsim>
<palmtype>
Palm V
</palmtype>
</book>

well-formedXML XML
DTD

2.4 Namespaces
Namespaces
XML XML XML
XML XML XML
XML
XML W3C
collision

W3C Namespaces
XML universal

Namespaces
1999-01-14W3C Namespaces Namespaces
< xmlns:prefix=""...>
prefix
33

Namespacesprefix bk ISBN
prefix isbn
<?xml version="1.0"?>
<bk:book

xmlns:bk='http://www.softchina.com.tw'
xmlns:isbn='urn:ISBN:0-123-63612-7'>

<bk:title>Palm </bk:title>
<isbn:number>123456789</isbn:number>
</bk:book>
Namespaces XML Namespaces
< xmlns=""...>
booktitle Namespaces 'http://www.softchina.com.tw'
Namespaces title version Namespaces
<?xml version="1.0"?>
<book

xmlns ='http://www.softchina.com.tw'
xmlns:isbn='urn:ISBN:0-123-63612-7'>
<title version="1.0">Palm </title>
<isbn:number>123456789</isbn:number>

</book>

Namespaces
cd version Namespaces
<?xml version="1.0"?>
<book

xmlns:bk='http://www.softchina.com.tw'
xmlns:isbn='urn:ISBN:0-123-63612-7'>
<cd bk:version="1.0" isbn:version="2.0">Palm </cd>
<isbn:number>123456789</isbn:number>

</book>
Namespaces prefix Namespaces
<?xml version="1.0"?>
<book

xmlns:bk='http://www.softchina.com.tw'
xmlns:cd='http://www.softchina.com.tw'>
<cdrom bk:version="1.0" cd:version="2.0">Palm </cdrom>
<isbn>123456789</isbn>

</book>

34

2.5 XPath
XPath
XPath XML XML XSLT XPointer 1999
11 16 XPath W3C Recommendation
XPath http://www.w3.org/TR/1999/REC-xpath-19991116

XPath
XPath Document Object ModelDOM XML node
XML Parser
XML DOM
<addressbook>
<record deleted="true">
<name></name>
<phone>27093677</phone>
<address> 130 </address>
</record>
<record>
<name></name>
<phone>29850611</phone>
<address> 233 </address>
</record>
</addressbook>
XML DOM addressbook root noderecord addressbook
record child nodenamephoneaddress record
parent noderecord deleted

XML DOM
35

XPath nodes
root
element
text
attribute
Namespace
comment
Processing instruction<?xml ... ?>

XPath
XML XPathXML XPath XPath
xpathdemo xlink:href XML
<addressbook xmlns="http://www.softchina.com.tw/java_xml">
<record deleted="true">
<name></name>
<phone>27093677</phone>
<phone>0933-1234567</phone>
<address> 130 </address>
</record>
<record>
<name></name>
<phone>29850611</phone>
<address> 233 </address>
<relatives>
<record>
<name></name>
<phone>29850678</phone>
<address> 277 </address>
</record>
</relatives>
</record>
<xpathdemo xlink:href="........."> ......

</xpathdemo>

<xpathdemo xlink:href ="........."> ......

</xpathdemo>

<xpathdemo xlink:href ="........."> ......

</xpathdemo>

......
</addressbook>


36

<xpathdemo path='/addressbook'></xpathdemo>

<xpathdemo path='/addressbook/record'> record


</xpathdemo>

<xpathdemo path='/addressbook/record/phone'> record


phone </xpathdemo>

<xpathdemo path='//record'> record </xpathdemo>

<xpathdemo path='//record/address'> record address


</xpathdemo>
*
<xpathdemo path='/addressbook/record/*'>

record

</xpathdemo>
<xpathdemo path='/*/*/record'>

record record

</xpathdemo>
<xpathdemo path='//*'></xpathdemo>

<xpathdemo path="//record[@deleted='true']">

deleted true record record

</xpathdemo>
<xpathdemo path="//record[normalize-space(@deleted)='ture']">

normalized-space() deleted

</xpathdemo>


<xpathdemo path='/addressbook/record[1]'> addressbook record
</xpathdemo>
<xpathdemo path=/addressbook/record[last()]'> addressbook record
</xpathdemo>

<xpathdemoe path='//record[@deleted]'> deleted record record
</xpathdemo>
37

<xpathdemo path='//record[@*]'> record record


</xpathdemo>
<xpathdemo path='//record[not(@*)]'> record record
</xpathdemo>
|
<xpathdemo path="//name | //phone | //address">

name phone address

</xpathdemo>
<xpathdemo path="/relatives/record | //name ">

relatives record name


</xpathdemo>

Axis
XPath axis
XPath
child::axis
parent::
descendant::
ancestor::
following-sibling::
preceding-sibling::
following::
preceeding::
self::
descendant-or-self::
ancestor-or-self::
attribute::
namespace::namespace

child::axis

child::
<xpathdemo path="//child::record">//record </xpathdemo>
<xpathdemo path="//child::record/child::name">

//record/name//child::record/name//record/child::name
</xpathdemo>

parent::
<xpathdemo path="//record/parent::*">
38

record addressbook relatives


</xpathdemo>

descendant::
Namespaces
<xpathdemo path="/descendant::*"></xpathdemo>
<xpathdemo path="/addressbook/record/descendant::*">

/addressbook/record namephoneaddressrelatives
relatives/namerelatives/phonerelatives/address

</xpathdemo>

<xpathdemo path="//record/descendant::*">

record /addressbook/record /

addressbook/record/relatives/record

</xpathdemo>
<xpathdemo path="//record/descendant::name">

record ancestor node name /addressbook/record


/addressbook/record/relatives/record name

</xpathdemo>
ancestor::

......
<xpathdemo path="/addressbook/record/relatives/name/ancestor::*">

/addressbook/record/relatives/name addressbook

recordrelatives

</xpathdemo>

<xpathdemo path="//record/ancestor::*">

addressbookrelatives
</xpathdemo>

following-sibling::
<xpathdemo path="/name/following-sibling::*">

phoneaddressrelatives

</xpathdemo>
<xpathdemo path="//addressbook/record/relatives/phone/following-sibling::*">

address
39

</xpathdemo>
preceding-sibling::
<xpathdemo path="//record/address/preceding-sibling::*">

namephone
</xpathdemo>
<xpathdemo path="/addressbook/record/relatives/phone/preceding-sibling::*">
name
</xpathdemo>

following::
XML namspace
<xpathdemo path="//record/address/following::*">
relativesrelatives/namerelatives/phonerelatives/address
</xpathdemo>
preceeding::
XML
namespace
<xpathdemo path="//record/address/preceeding::*">
namephone
</xpathdemo>
self::
<xpathdemo path="//record/self::*">

record
</xpathdemo>

descendant-or-self::

<xpathdemo path="//record/address/preceeding::*">

addressrelativesrelatives/namerelatives/phone

relatives/address
</xpathdemo>

ancestor-or-self::

40


<xpathdemo path="//record/address/preceeding::*">

addressbookphonenameaddressrelativesrelatives/name

relatives/phonerelatives/address
</xpathdemo>

attribute::
<xpathdemo path="//record/attribute::*">
record deleted

</xpathdemo>
namespace::namespace
<xpathdemo path="//record/namespace::*">
record namespace"http://www.softchina.com.tw/java_xml"

</xpathdemo>

XPath
or

and
=

!=

<=

>=

<

>

mod
div
+

XPath XPath
XPath Node setStringBooleanNumber
Node set

last()
41

position()

<xpathdemo path="//record[position() mod 2 = 0 ]">

record
</xpathdemo>
<xpathdemo path="//record[ position()= floor(last() div 2+ 0.5)

or position() = ceiling(last() div 2 + 0.5) ]">


record
</xpathdemo>

count()

<xpathdemo path='//*[count(phone)=2]'>
phone record </xpathdemo>

id()

<xpathdemo path='//*[count(phone)=2]'>
phone record </xpathdemo>

local-name()

namespace-uri()

42

name()

<xpathdemo path="//*[name()='record']">
record </xpathdemo>
//record

<xpathdemo path="//*[starts-with(name(),'rec')]">
1 rec </xpathdemo>
<xpathdemo path="//*[contains(name(),'ame')]">
ame </xpathdemo>
String

string()

string(123)= "123"

concat(,,*)

concat("abc","def",s) = "abcdef"

starts-with(, )

starts-with("abcdef", "ab") = true

contains(, )

contains("abcdef", "bc")

43

substring-before(, )

substring-before("2000/10/31","/")="2000"

substring-after(, )

substring-after("2000/10/31","/")="10/31"

substring(,,)

substring("abcdefgh", 4, 3)="def"

string-length()


<xpathdemo path="//*[string-length(name()) > 6]">
address</xpathdemo>
>

<xpathdemo path="//*[string-length(name()) = 6]">


record</xpathdemo>
<xpathdemo path="//*[string-length(name()) < 6]">
name</xpathdemo>
<

normalize-space()

normalize-space(" excellent! ")="excellent!"

44

translate(,,)

translate("this is a book!", "thisabok! ", "Thisabok. ")


"This is a book."

Boolean

boolean()

boolean(1=1)=true

not()

not(1=1) = false

true()

false()

lang()


<title xml:lang="en" />

lang("en")=true

Number

number()


45

number("123")=123

sum()


<nums>
<num>1</num>
<num>3</num>
<num>5</num>

</nums>

sum(nums) = 9

floor()

floor(123.456) = 123

ceiling()

ceiling(123.456) = 124

round()

round(123.456) = 123

2.6

46

XML
XML HTML XML
HTML XML

XML HTML HTML 4.x


HTML
HTML HTML

HTML
HTML
XML information
presentation XML
style sheet HTML
HTML PDA

W3C Cascading Style SheetsCSS Level 2W3C CSS2


http://www.w3.org/TR/1998/REC-CSS2-19980512
CSS XML
eXtensible Stylesheet LanguageXSL HTML XML
SGML Document Style and Semantics
Specification LanguageDSSSLXSL XML
formatting XML transformation
customization XSL XML

CSSCascading Style SheetsCSS


CSS 1996 HTML XML CSS
W3C 1998 5 12 CSS level 2
http://www.w3.org/TR/1998/REC-CSS2-19980512 HTML XML
CSS
HTML Netscape Navigator Mircosoft Internet Explorer
4.x
HTML

47


HTML
HTML
HTML XML

CSS CSS CSS


HTML Netscape
Navigator Microsoft Internet Explorer CSS
CSS level 2 CSS2 CSS level 1CSS1CSS2
media-specific CSS2

CSS2
XSL CSS XSL
XML

XML + CSS
XML CSS <?xml?>Processing instructionPI
<?xml-stylesheet ?> PI
<?xml-stylesheet type="text/css" href=" URL"?>

<?xml

version="1.0"?>

<?xml-stylesheet type="text/css" href="/css/book.css" ?>


<!DOCTYPE book SYSTEM "/dtd/book.dtd">
<book>
<title>Palm </title>
<author>Growbal Kuo</author>
<text>

</text>
</book>
XML CSS
book, title, author text { display: block }
book {
48

background: white;
color: black
}
title { font-size: 1.3em }
author { font-style: italic }
book, title, author text { margin: 0.5em }
CSS XML XML
CSS selectorproperty

{:}

book, title, author text


title
author
book, title, author text
XML element
property { }
selectortitle property
title {display:block; font-size:14pt; color:blue; font-style:italic}

CSS
CSS CSS
W3C CSS2 http://www.w3.org/Style/CSS/

(property)

font-family

title {font-family: "", Symbol}

title Symbol

(property)

font-style
normalitalicobliqueinherit Inherit parent
element

title {font-style: italic}

title

49


(property)

font-varient

normalsmall-capsinherit

title {font-varient: small-caps}

(property)

font-weight
normalboldbolderlighter 100200300400500600

700800900inherit 100 900 normal 400 bold


700

title {font-weight: 800}

800

(property)

font-stretch
narrowwidernarrower ultracondensedextra-condensed
condensed semicondensedsemi-expandedexpanded extra-expandedultra-expandedinherit

title {font-stretch: condensed}

(property)

font-size

xx-smallx-smallsmallmediumlarge x-largexx-large

pt(points=1/72 inch)pc (pica=12 pt)cmin(inch)


largersmaller
em ex x-height
px

title {font-size: 14pt}

(property)

font

50

title {font: bold italic 12pt/14pt ""}

font-weightfont-stylefont-size/line-heightfont-family

(property)

color
redblue blackwhite rgb
#rgb#rrggbbrgb(255, 0,0)rgb(100%,0%,0%)
title {color: red}
address {color: #f00}

phone {color: #ff0000}


fax {color: rgb(100%,100%,100%)}
mobil {color: rgb(255,0,0)}

(property)

(property)

(property)

title address phone fax mobil

background-color
transparentinherit color
body { background-color: white; color: black }
head1 { background-color: transparent; color: black }
body head1

background-image
noneURI inherit
body { background-image: url("/image/picture1.gif"); color: black }
paragraph1 {background-image: none}
body paragraph1

background-repeat
background-image repeat x y
repeat-x x repeat-y y no-repeat
51


body { background-image: url("/image/picture1.gif");
background-repeat: repeat;

color: black }

(property)

Body

background-attachment
background-image scrollfixedinherit


body { background-image: url("/image/picture1.gif");
background-attachment: fixed;

color: black }

(property)

background-position
background-image topcenterbottom
leftcenterright 0% 0%100% 100%

2cm 3cm 2cm 3cm


font-size
body
{ background-image: url("/image/picture1.gif");

background-position: center top; color: black }

(property)

center top 50% 0%

background

body { background: url("/image/back1.gif") repeat white center fixed}

background-imagebackground-repeatback ground-colorbackground-positionbackgroundattachment

52


(property)

text-indent

font-size

body { text-indent: 1cm }

(property)

text-align

leftrightcenterjustifyinherit

num { text-align: "."}

<num>1.23</num>
<num>12.3</num>
<num>768.12</num>

1. 23
12.3
768.12

(property)

text-decoration
noneunderlineoverline line-through
blink

list { text-decoration: underline }

(property)

text-shadow

noneinherit

title { text-shadow: 3px 4px 5px gray }

3px 4px 5px gray


font-size

53


(property)

letter-spacing
normalinherit
font-size

title { letter-spacing: 0.1em }

0.1em

(property)

word-spacing
normalinherit
font-size

title {word-spacing: 1em }

1em

(property)

text-transform
capitalizeuppercaselowercasenoneinherit
title { text-transform: capitalize }
title { text-transform: uppercase }

<title> java xml programming </title>

Java Xml Programming

JAVA XML PROGRAMMING

(property)

white-space
normal

pre nowrap
inherit

P {white-space: normal}
PRE {white-space: pre}
HTML CSS

54

Box model
CSS box model XML
paddingbordermargin

Box model

text {

margin: 10px 10px 10px 10px;


border: 5px 5px 5px 5px;
padding: }

margin margin margin font-size


auto

(property)

margin-top

margin

text { margin-top: 2em}

margin 2em

(property)

margin-bottom

margin

(property) margin-left

margin

(property)

margin-right
margin

55


(property)

margin
margin
text {margin: 2em }
text {margin: 2em 3em}

text {margin: 2em 3em 4em}


margin 2em margin

2em margin 3em margin 2em margin


3em margin 4em

Padding margin
(property) padding-top

padding

text {padding-top: 12px}

padding 12

(property) padding-left
padding

(property) padding-bottom
padding

(property) padding-right
padding

(property) padding

padding margin

text { padding: 10px 15px }

padding 10 15

Border
border margin thinmediumthickinherit
(property) border-top-width

border

text { border-top-width: 10px }


56

text border 10px

(property) border-left-width
border

(property) border-bottom-width
border

(property) border-right-width
border

(property) border-width
border

border color
(property) border-top-color

border

text { border-top-color: red }

border

(property) border-left-color

border

(property) border-bottom-color

border

(property) border-right-color

border

(property) border-color

border transparentinherit

border
(property) border-top-style
57

border
border
none
hidden
dotted
dashed

solid
double
groove
ridge
inset border
outset border

(property) border-left-style

border

(property) border-bottom-style

border

(property) border-right-style

border

(property) border-style

border

text { border-style: double }

border

58

border

(property) border-top

border

(property) border-left

border

(property) border-bottom

border

(property) border-right

border

(property) border

border

title { border: thick dashed black }

border


HTML XML

cell row cells column cells


HTML
<table>
<caption></caption>
<tr id="title">
<th>
<tr

<td>85

<td>65

id="student2">
<th>James Bond

<tr

<th>

id="student1">
<th>

<tr

<th>

<td>55

<td>86

id="student3">
<th>Aki

<td>70
59

<td>75

</table>
HTML CSS
table {display: table}
caption {display: table-caption}
tr {display: table-row}
th {display: table-cell}
td {display: table-cell}
XML
<?xml version="1.0" encoding="Big5"?>
<?xml-stylesheet type="text/css"

href="final_exam_score.css"?>

<final_exam_score>
<title></title>
<col_title>
<col></col>

<col></col>

<col></col>

</col_title>
<student>
<name></name>

<ch>85</ch>

<en>65</en>

<ch>55</ch>

<en>86</en>

</student>
<student>
<name>James Bond</name>
</student>
<student>
<name>Aki</name>

<ch>70</ch>

</student>
</final_exam_score>
XML CSS
final_exam_score { display: table;
table-layout:auto }
title {display: table-caption;
caption-side:top;
text-align:central;
width:auto}
col_title {display: table-row }
col {display:table-cell;
60

<en>75</en>

border:double;
background:lime;
width:20em}
student {display: table-row }
name {display:table-cell; background: cyan; width:20em}
ch {display:table-cell; width:20em }
en {display:table-cell; width:20em }

final_exam_score { display: table;

table-layout:auto }

final_exam_score
title {display: table-caption;
caption-side:top;
text-align:central;
width:auto}
title
col_title {display: table-row }
col_title
col {display:table-cell;
border:double;
background:lime;
width:20em}
col_ cell double 20em
student
namechen cells

XSLeXtensible Stylesheet Language


XSL XML formattingtransfor-mation
XML XSL

W3C XSL XSL CSS XSL


CSS
XSL customizationCSS
XSL CGI
PHPServletJava Server PagesActive Server Pages

61

HTML
XSL XML XSL
XML XSL XML

XSL XML
CSS Microsoft Internet Explorer 4.0 Netscape
Navigator 4.0
XML CSS

XSL CSS
XML XML HTML

XSL XSL TransformationsXSLT


XSLT 1999 11 16 W3C Recommendation

XSL XML
<?xml

version="1.0"?>

<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
......
62

</xsl:stylesheet>
XML XSL PIProcessing Instruction
<?xml version="1.0"?>
<?xml-stylesheet type="text/xml" href="MyXSL.xsl"?>
XPath XSL XPath XML
XML XSL
XSL XML HTML
<address_book>
<person>
<name></name>
<title></title>
<birthday>1968-09-04</birthday>
<address> 10 </address>
<phone type="(o)">27093600</phone>
<mobil>0932-168888</mobil>
<fax>29850666</fax>
</person>
<person>
<name></name>
<title></title>
<birthday>1955-05-06</birthday>
<address> 20 </address>
<phone type="(h)">04-2881777</phone>
<mobil>0912-345678</mobil>
<fax>04-2881778</fax>
</person>
</address_book>
<?xml version="1.0"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/address_book">
<html>
<body>
<h1></h1>
<table>
<tr>
<th></th>
63

<th></th>
<th></th>
</tr>
<xsl:apply-templates/>
</table>
</body>
</html>
</xsl:template>
<xsl:template match="person">
<tr>
<td><xsl:value-of select="name"/></td>
<td><xsl:value-of select="address"/></td>
<td><xsl:apply-templates select="phone"/></td>
</tr>
</xsl:template>
<xsl:template match="phone">
<xsl:value-of select="."/>
<xsl:value-of select="@type"/>
</xsl:template>
</xsl:stylesheet>
HTML
<html>
<body>
<table>
<tr>
<th></th>
<th></th>
<th></th>
</tr>
<tr>
<td></td>
<td> 10 </td>
<td>(o)27093600</td>
</tr>
<tr>
<td></td>
64

<td> 20 </td>
<td>(h)04-2881777</td>
</tr>
</table>
</body>
</html>
XSLT jclark xtApache Xalan
xt http://www.jclark.com/xml/xt.html 19991105
Xalan http://www.apache.org

Formatting ObjectsFO
FO XSL FO CSS
FO CSS FO PDF
56 Formatting object FO
CSS Box

Formatting property CSS

W3C XSL
<doc>
<chapter><title>Chapter</title>
<p>Text</p>
<section><title>Section</title>
<p>Text</p>
</section>
<section><title>Section</title>
<p>Text</p>
</section>
</chapter>
<chapter><title>Chapter</title>
<p>Text</p>
<section><title>Section</title>
<p>Text</p>
</section>
<section><title>Section</title>
<p>Text</p>
</section>
</chapter>
</doc>
XML XSL
<?xml version='1.0'?>
65

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:fo="http://www.w3.org/1999/XSL/Format"
version='1.0'>
<xsl:template match="chapter">
<fo:block break-before="page">
<xsl:apply-templates/>
</fo:block>
</xsl:template>
<xsl:template match="chapter/title">
<fo:block text-align="center" space-after="8pt"
space-before="16pt" space-after.precedence="3">
<xsl:apply-templates/>
</fo:block>
</xsl:template>
<xsl:template match="section/title">
<fo:block text-align="center" space-after="6pt"
space-before="12pt" space-before.precedence="0"
space-after.precedence="3">
<xsl:apply-templates/>
</fo:block>
</xsl:template>
<xsl:template match="p[1]" priority="1">
<fo:block text-indent="0pc" space-after="7pt"
space-before.minimum="6pt" space-before.optimum="8pt"
space-before.maximum="10pt">
<xsl:apply-templates/>
</fo:block>
</xsl:template>
<xsl:template match="p">
<fo:block text-indent="2pc" space-after="7pt"
space-before.minimum="6pt" space-before.optimum="8pt"
space-before.maximum="10pt">
<xsl:apply-templates/>
</fo:block>
66

</xsl:template>
</xsl:stylesheet>
XSL namespaceXSLT xslFO fo
FO XML PDF
Apache FOP http://xml.apache.org/fop/ XML PDF XEP
http://www.renderx.com/ XML PDF
FO FO FO
XML

2.7 XLink XPointer


XLink XPointer
XLink XML XPointer XML HTML
XLinkXPointer HTML Anchor tag
<A HREF=......> ...... </A> XLink
URLXPointer XML URL

XLink
XLink XML Linking Language Version 1.0 2000 7 3 W3C Candidate
RecommendationXLink http://www.w3.org/TR/2000/CR-xlink-20000703/
XLink HTML XML XLink HTML
<A HREF=...>...</A> XML XLink

XLink
<book xmlns:xlink="http://www.w3.org/1999/xlink"
xlink:type="simple"
xlink:href="http://www.softchina.com.tw/XML/Java/Growbal/">
JavaXML
</book>
<author xmlns:xlink="http://www.w3.org/1999/xlink"
xlink:type="simple"
xlink:href="growbal.xml"/>

67

<photo xmlns:xlink="http://www.w3.org/1999/xlink"
xlink:type="simple" xlink:href="growbal.gif"
xlink:actuate="onLoad" xlink:show="embed"/>
XLink " http://www.w3.org/1999/xlink " namespacenamespace prefix xlink
XLink
xlink:type
xlink:href URL
xlink:show
xlink:actuate

XPointer
XPointer XML Pointer Language Version 1.02000 6 7 W3C Candidate
Recommendation http://www.w3.org/TR/2000/CR-xptr-20000607
XPointer Internet text/xml application/xml XPointer
XML Path LanguageXPathXPath XML
XPointer XML HTML Anchor tagHTML Anchor

<A HREF="#Part1"> Part 1 </A>


HTML
<A NAME="Part1"> Part 1 </A>
XPointer
xpointer(id("1234"))
1234
xpointer(descendant::book[position()=3])
xpointer(/child::spec/child::body/child::*/child::book[position()=3])
xpointer(id("1234"))xpointer(id("part1"))
/1/11/3
XPointer XPath XML
XPointer
XPointer ID "1234"
XPointer XPointer
XPointer XML book book
XPointer XML spec body
book
XPointer ID "1234" ID "part1"
XPointer XML

XLink + XPointer
XPointer XLink XPointer XLink
HTML Anchor
68

<A HREF="http://www.softchina.com.tw/doc/document1.html#part1">
:
</A>
XLink + XPointer
http://www.softchina.com.tw/doc/document1.xml#xpointer(id("part1"))
XML
<part1 xmlns:xlink="http://www.w3.org/1999/xlink"
xlink:type="simple"
xlink:href="http://www.softchina.com.tw/doc/document1.xml#xpointer(id(&apos;part1&apos;))"/>
XML &apos;

B2C
CPU : AMD Athlon 1GHz
RAM : 256M DDR
Hard Disk : 30G bytes
DVD-ROM : 10x
2nd Storage Device : CD-RW 12x
Graphic Card : Voodoo 5
Sound Card : Yamaha 724
Monitor : 15 inches TFT
XML DTD

69

3 XML Parsers

3.1
...
Java XML XML Java Java
Application

XML
XML
XML SAX DOM
XML fred XML Apache Xerces
SAX Java XML
Sun Java JAXPJava API for XML ParsingProcessing
Java
XML

XML XML XML


XML
XML
<?xml version="1.0" ?>
<bookorder>
<book>
<name>Java XML</name>
<author>Growbal</author>
<quantity>50</quantity>
70

</book>
<book>
<name>PalmOS Programming</name>
<author>Kuo</author>
<quantity>30</quantity>
</book>
</bookorder>
XML XML
XML XML
Java XML Growbal Palm Programming
Kuo
XML XML XML XML

XML XML
XML XML
XML XML SAX
DOM XML
XML XML
XML parser
XML
XML
XML CJavaPerlPHP
Java XML

3.2 DOM SAX


DOM SAX
XML XML
treeevent driven
XML object

TreeDOMDocument Object Model


71

a
XML XML element

XML XML XML


XML
1. root element<bookorder>root node
2. <book>element nodebranch node
child node
3. <name>(element node)
4. name "Java XML"text node
5. <author>element node
6. author 50text node
XML a

XML node

DOM
72

Object HTML
DocumentFrameForm
DOMDocument Object Model Javascript DOM

Microsoft Netscape DOM


DOM

XML XML
XML XML
XML
W3C XML DOM API
XML
XML XML

W3C DOM
XML HTML
W3C XML interface W3C XML
XML
XML W3C
XML W3C

SunOracleIBMMicrosoftApache
XML
DOM XML XML tree of nodes
XML XML tree of
nodes XML
DOM 4

Event drivenSAX Event driven

XML XML event


event handler XML
73

XML XML
<?xml version="1.0" encoding="UTF-8" ?>
<book>
<name>Java XML</name>
<quantity>50</quantity>
</book>
XML events
<?xml ... ?>startDocument
<book>StartElement
<name>
Java XMLcharacters
</name>endElement
<quantity>
50
</quantity>
</book>
endDocument
callbackevent handler
XML event handler

SAXSimple API for XML


SAXSimple API for XMLXML XML
XML-DEV mailing list 1998 5 DOM
DOM W3C
http://www.megginson.com/SAX
SAX XML open tagclose tag#PCDATA
CDATA event
DOM SAX XML object
SAX fred parser 23.1KB

XML Event Handler SAX


SAX event driven XML SAXSAX XML
SAX version 2SAX version 2
http://www.megginson.com/SAX
SAX 4

74

3.3 AELfred XML Parser


lfred XML Parser
Opentext 1998 1.2a
XML SAX version 1 DOMlfred
lfred DOM
Java applet 23KB fred XML
lfred N
lfred XML valid
XML well-formed XML

lfred parser
http://www.opentext.com/services/content_management_services/aelfred.zip
aelfred.jar parser CLASSPATH
jar Linux shell bash
export CLASSPATH=$CLASSPATH://xml/aelfred.jar
shell csh
set CLASSPATH = ($CLASSPATH //xml/aelfred.jar)
Windows 9x autoexec.bat
SET CLASSPATH=C:\XML\aelfred.jar;%CLASSPATH%
Windows NT Windows 2000

lfred parser
lfred native
classXmlParsercom.microstar.xml.XmlParser
interfaceXmlHandlercom.microstar.xml.XmlHandler
document handler
XmlException XML
HandlerBase XmlHandler
SAX SAX version 1 class com.microstar.xml.SAXDriver

lfred
Java
java.lang.Object
75

|
+---com.microstar.xml.XmlParser
XmlParser XML XmlHandler
XmlHandler handler = new MyHandler();
XmlParser parser = new XmlParser();
parser.setHandler(handler);
parser.parse("http://www.host.com/doc.xml", null);
XmlParser XmlHandler XmlParser XML
XmlHandler
XmlHandler class handler

XmlParser parser
parser.setHandlerhandler parser
handler
XML parser.parseXML ......;

lfred
com.microstar.xml.XmlHandler interfaceimplement
class
import com.microstar.xml.XmlHandler;
// XmlHandler MyHandler
public class MyHandler implements XmlHandler {
public void attribute (String attrName,
String attrValue,
Boolean isSpecified)
{
// (method)
}
public void charData(char ch[],
int start,
int length) {
// (method)
}
public void doctypeDecl (String name,
string publicId,
String systemId) {
// (method)
}
76

public void endDocument() {


// (method)
}
public void endElement(String name) {
// (method)
}
public void endExternalEntity(String systemId) {
// (method)
}
public void error(String message,
String systemId,
int line,
int column) {
// (method)
}
public void ignorableWhitespace(char[], int, int) {
// (method)
}
public void processingInstruction(String target,
String data) {
// (method)
}
public void resolveEntity(String publicId,
String systemId) {
// (method)
}
public void startDocument() {
// (method)
}
public void startElement(String name) {
// (method)
}
public void startExternalEntity(String systemId) {
// (method)
}
}
77

XmlHandler XmlHandler method


XmlHander HandlerBase
HandlerBase Java
java.lang.Object
|
+----com.microstar.xml.HandlerBase
HandlerBase XmlHandler XmlHandler method
HandlerBase
XmlHandler method method method
method HandlerBase method
MyHandler HandlerBase method charData()startElement()
endElement() XML
import com.microstar.xml.HandlerBase;
public class MyHandler extends HandlerBase {
// method
public void startElement(String name) {
// (method)
System.out.println("" + name);
}
public void endElement(String name) {
// (method)
System.out.println("------------");
}
public void charData (char s[], int startPos, int length)
{
System.out.println(": " +
new String (s, startPos, length));
}
}

lfred
com.microstar.xml.XmlException
XmlException
java.lang.Object
|
+---java.lang.Throwable
|
+---java.lang.Exception
78

|
+---com.microstar.xml.XmlException
XmlException
String message
String systemIdXML
int lineXML
int columnXML
XmlHandler error() XmlException HandlerBase
error()
public void error(String message,
String systemId,
int line,
int column) throws XmlException, Exception
Handler error() XmlException try...catch...

XmlException
import com.microstar.xml.HandlerBase;
public class MyHandler extends HandlerBase {
public void charData (char s[], int startPos, int length)
{
System.out.println("Data: " + new String (s, startPos, length));
}
// HandlerBase error()
public void error (String message,
String systemId,
int line,
int column)
throws XmlException, Exception
{
System.out.println("XML : " + new String (message) );
}
}

lfred SAX
lfred SAX version 1 SAX com.microstar.xml.SAXDriver
lfred SAX version 1 methods
XML SAXDriver lfred
native

79

lfred SAX lfred


lfred SAX lfred lfred
API SAX API
SAX version 1 SAX version 2
SAX1 package
org.xml.sax
org.xml.sax.helpers

SAX

SAX
SAX lfred SAX parser
lfred import com.microstar.xml.SAXDriver;
org.xml.sax.Parser parser = new com.microstar.xml.SAXDriver();
SAX API XML
parser.parse(xmluri);

import org.xml.sax.Parser;
import com.microstar.xml.SAXDriver
public class MySAXParser() {
pulic void startParse(String xmluri) {
try {
// SAX
org.xml.sax.Parser parser= new com.microstar.xml.SAXDriver();
// XML
parser.parse(xmluri);
} catch (Exception e) {
System.out.println(":"+ e.getMessage());
}
80

}
}

SAX
SAX Event HandlerSAX version 1 interface
DTDHandler
DocumentHandler
EntityHandler
ErrorHandler
DocumentHandler
import org.xml.sax.DocumentHandler;
import org.xml.sax.Attributes;
import org.xml.sax.Locator;
import org.xml.sax.InputSource;

import org.xml.sax.Parser;
class MyDocumentHandler implements DocumentHandler {
public void characters(char ch[], int start, int length) {
//
}
public void startDocument() {
//
}
public void endDocument() {
//
}
public void startElement(String name, AttributeList atts)

//
}
public void endElement(String name) {
//
}
public void ignorableWhitespace(char ch[], int start, int length) {
//
}
public void processingInstruction(String target, String data) {
// PI
81

}
public void setDocumentLocator(Locator locator) {
// Locator
}

}
ErrorHandler method

XML1.0
fetal error XML well-formedness SAX
error XML DTD non-validXML SAX
XML
warning SAX XML
import org.xml.sax.ErrorHandler;
import org.xml.sax.SAXParseException;
import java.io.IOException;
class MyErrorHandler implements ErrorHandler {
public void error(SAXParseException e) throws SAXException {
// method
}
public void fatalError(SAXParseException e) throws SAXException {
// method
}
public void warning(SAXParseException e) throws SAXException {
// method
}
}
SAX1 DTD org.xml.sax.DTDHandler method
notationDecl
unparsedEntityDecl
method DTD NOTATION ENTITYENTITIES
XML
DTDHandler
82

import org.xml.sax.DTDHandler;
import org.xml.sax.SAXParseException;
class MyDTDHandler implements DTDHandler {
public void notationDecl(String name,
String publicId,
String systemId) throws SAXException
{
// mehtod
}
public abstract void unparsedEntityDecl(String name,
String publicId,
String systemId,
String notationName) throws SAXException
{
// mehtod
}
}
DocumentHandler method
method

SAX
org.xml.sax.HandlerBase

public class HandlerBase


extends Object
implements EntityResolver, DTDHandler, DocumentHandler, ErrorHandler
method SAX

MySAXDemo1.java
// packages
import java.io.FileReader;
import java.lang.*;
import org.xml.sax.Parser;
import org.xml.sax.AttributeList;
import org.xml.sax.InputSource;
import org.xml.sax.HandlerBase;
83

import com.microstar.xml.SAXDriver;
//
public class MySAXDemo1 extends HandlerBase
{
private int indentcount = 0;
// XML
public static void main (String args[])
throws Exception
{
System.out.println("file=" + args[0]);
// SAX
org.xml.sax.Parser parser =
new com.microstar.xml.SAXDriver();
//
MySAXDemo handler = new MySAXDemo();
//
parser.setDocumentHandler(handler);
parser.setErrorHandler(handler);
// XML XML
FileReader fr = new FileReader(args[0]);
//
parser.parse(new InputSource(fr));
}
// --------- HandlerBase
//

method

//

HandlerBase method -------------

public void startDocument ()


{
System.out.println("XML ");
public void endDocument ()
{
System.out.println("XML ");
}
public void startElement (String name,
84

AttributeList attributes)
{
indentcount ++;
String indent = new String("");
for (int i=0; i<indentcount; i++) {
indent += "\t";
}

System.out.println(":"+indent+ name);
}
public void endElement (String name)
{
indentcount --;
}
public void characters (char ch[], int start,
int length)
{
String s = (new String(ch, start, length)).trim();
if (s.length() > 0) {
String indent = new String("");
for (int i=0; i<indentcount; i++)
indent += "\t";
System.out.println
(":"+ indent +"'" + s.trim() + "'");
}
}
}

javac MySAXDemo1.java
Classpath sax.jar aelfred.jar jar

set classpath=.;c:\jdk1.2.2\lib\tools.jar;e:\xml\sax.jar;e:\aelfred.jar
PATH JDK bin
set PATH=c:\jdk1.2.2\bin;%PATH%
XML book.xml
<book>
<title>Java XML</title>
85

<author>Kuo</author>
<qty>30</qty>
</book>
Java Application Java Windows
9x/NT/2000 DOS Linux shell
java

MySAXDemo1 book.xml

SAX
import com.microstar.xml.SAXDriver;

org.xml.sax.Parser parser =
new com.microstar.xml.SAXDriver();

lfred SAXDrive XML


lfred
Java

import org.xml.sax.helpers.*;
SAX
org.xml.sax.Parser parser =
ParserFactory.makeParser();
MySAXDemo2.java
// packages
import java.io.FileReader;
import java.lang.*;
import org.xml.sax.Parser;
import org.xml.sax.AttributeList;
import org.xml.sax.InputSource;
import org.xml.sax.HandlerBase;
import org.xml.sax.helpers.*;
// import com.microstar.xml.SAXDriver;
86

//
public class MySAXDemo2 extends HandlerBase
{
private int indentcount = 0;
// XML
public static void main (String args[])
throws Exception
{
System.out.println("file=" + args[0]);
// SAX
//org.xml.sax.Parser parser =
//

new com.microstar.xml.SAXDriver();

org.xml.sax.Parser parser =
ParserFactory.makeParser();
//
MySAXDemo2 handler = new MySAXDemo2();
//
parser.setDocumentHandler(handler);
parser.setErrorHandler(handler);
// XML XML
FileReader fr = new FileReader(args[0]);
//
parser.parse(new InputSource(fr));
}

// --------- HandlerBase
//

method
87

//

HandlerBase method -------------

public void startDocument ()


{
System.out.println("XML ");
}
public void endDocument ()
{
System.out.println("XML ");
}
public void startElement (String name,
AttributeList attributes)
{
indentcount ++;
String indent = new String("");
for (int i=0; i<indentcount; i++) {
indent += "\t";
}

System.out.println(":"+indent+ name);
}
public void endElement (String name)
{
indentcount --;
}
public void characters (char ch[], int start,
int length)
{
String s = (new String(ch, start, length)).trim();
if (s.length() > 0) {
String indent = new String("");
for (int i=0; i<indentcount; i++)
indent += "\t";
System.out.println
(":"+ indent +"'" + s.trim() + "'");
}
}
88

javac MySAXDemo2.java
XML Java system property
java -Dorg.xml.sax.parser=com.microstar.xml.SAXDriver
MySAXDemo2 book.xml

Apache Xerces
java -Dorg.xml.sax.parser=org.apache.xerces.parsers.SAXParser
MySAXDemo2 book.xml
jar classpath
set classpath=e:\xml\xerces.jar;%classpath%

SAX 4
SAX http://www.megginson.com/SAX/ SAX version 1

3.4 Apache Xerces XML Parser


Apache Xerces XML Parser
Apache Software Fundation Java XML parser Xerces-j 1.2.0
2000
8
XML 1.0 XML schemaW3C
API SAX version
2 DOM level 2 SAX version 1 DOM level 1

http://xml.apache.org/dist/xerces-j/
Xerces.jar CLASSPATH
Xerces /Xerces.jar

set classpath=e:\xml\xerces.jar;%classpath%

Xerces parser SAX


SAX interface SAX XML class

Apache Xerces parser SAX version 2SAX2 package


89

org.xml.sax
org.xml.sax.helpers
SAX2 org.xml.sax package
org.xml.sax.AttributeList SAX1 org.xml.sax.Attributes
org.xml.sax.Attributes
org.xml.sax.DTDHandler
org.xml.sax.ContentHandler
org.xml.sax.DocumentHandler SAX1 org.xml.sax.ContentHandler
org.xml.sax.EntityResolver
org.xml.sax.ErrorHandler
org.xml.sax.Locator
org.xml.sax.Parser SAX1 org.xml.sax.XMLReader
org.xml.sax.XMLFilter
org.xml.sax.XMLReader

org.xml.sax.HandlerBase SAX1 org.xml.sax.helpers.DefaultHandler


org.xml.sax.InputSource
Exception
org.xml.sax.SAXException
org.xml.sax.SAXParseException
org.xml.sax.SAXNotRecognizedException
org.xml.sax.SAXNotSupportedException
SAX2 org.xml.sax.helpers package
org.xml.sax.helpers.AttributeListImpl
org.xml.sax.helpers.AttributesImpl
org.xml.sax.helpers.DefaultHandler
org.xml.sax.helpers.LocatorImpl
org.xml.sax.helpers.NamespaceSupport
org.xml.sax.helpers.ParserAdapter
org.xml.sax.helpers.ParserFactory
org.xml.sax.helpers.XMLFilterImpl
org.xml.sax.helpers.XMLReaderAdapter
org.xml.sax.helpers.XMLReaderFactory
90

org.xml.sax.XMLReader XML SAX XML


org.xml.sax.XMLReader SAX1 org.xml.sax.Parser XML XML
SAX
Apache Xerces parser SAX version 2 parser org.xml.sax.XMLReader
org.apache.xerces.parsers.SAXParser
Java packages SAX2 Xerces SAX

import org.xml.sax.XMLReader;
import org.apache.xerces.parsers.SAXParser;
object
XMLReader parser = new SAXParser();
XML (xmluri XML URI)
parser.parser(xmluri);
Xerces SAX
public void saxParser(String xmluri) {
try {
XMLReader parser = new SAXParser();
parser.parser(xmluri);
} catch (SAXException e) {
System.out.println(":"+ e.getMessage());
} catch (Exception e) {
System.out.println(":"+ e.getMessage());
}
}
lefred parser event driven
XML XML
Xerces parser SAX XML
Event Handler
Event Handler
lfred SAX version 1SAX version 2 Event Handler
SAX1 SAX1
org.xml.sax.ContentHandler
org.xml.sax.ErrorHandler
org.xml.sax.DTDHandler
org.xml.sax.EntityHandler
DefaultHandler
SAX1 HandlerBase
XML Event Handler MySAX2Demo.java
91

import java.io.FileReader;
import org.xml.sax.XMLReader;
import org.xml.sax.Attributes;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
import org.apache.xerces.parsers.SAXParser;
//
public class MySAX2Demo extends DefaultHandler
{
private int indentcount=0;
// XML
public static void main (String args[])
throws Exception
{
// SAX
XMLReader xr =
new org.apache.xerces.parsers.SAXParser();
//
MySAX2Demo handler = new MySAX2Demo();
//
xr.setContentHandler(handler);
xr.setErrorHandler(handler);
// XML XML
FileReader fr = new FileReader(args[0]);
//
xr.parse(new InputSource(fr));
}
public MySAX2Demo ()
{
super();
}
// --------- DefaultHandler
92

//
//

method
DefaultHandler method -------------

public void startDocument ()


{
System.out.println("XML ");
}
public void endDocument ()
{
System.out.println("XML ");
}
public void startElement (String uri,
String localName,
String qName,
Attributes attributes)
throws SAXException
{
indentcount ++;
String indent = new String("");
for (int i=0; i<indentcount; i++) {
indent += "\t";
}

System.out.println(":"+indent+ localName);
}
public void endElement (String uri,
String localName,
String qName)
{
indentcount --;
}
public void characters (char ch[], int start,
int length)
{
String s = (new String(ch, start, length)).trim();
if (s.length() > 0) {
93

String indent = new String("");


for (int i=0; i<indentcount; i++)
indent += "\t";
System.out.println
(":"+ indent +"'" + s.trim() + "'");
}
}
}

javac MySAX2Demo.java
sax2.jar classpath
set classpath=e:\xml\sax2.jar;%classpath%

java MySAX2Demo book.xml

Xerces SAXParser XML


Java

import org.apache.xerces.parsers.SAXParser;

import org.xml.sax.helpers.XMLReaderFactory;

XMLReader xr =
new org.apache.xerces.parsers.SAXParser();

XMLReader xr = XMLReaderFactory.createXMLReader();

SAX2 XMLReaderFactory

MySAX2Demo2.java
import java.io.FileReader;
94

import org.xml.sax.XMLReader;
import org.xml.sax.Attributes;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
import org.xml.sax.helpers.XMLReaderFactory;
//
public class MySAX2Demo2 extends DefaultHandler
{
private int indentcount=0;
// XML
public static void main (String args[])
throws Exception
{
// SAX
XMLReader xr = XMLReaderFactory.createXMLReader();
//
MySAX2Demo2 handler = new MySAX2Demo2();
//
xr.setContentHandler(handler);
xr.setErrorHandler(handler);
// XML XML
FileReader fr = new FileReader(args[0]);
//
xr.parse(new InputSource(fr));
}
public MySAX2Demo2 ()
{
super();
}
// --------- DefaultHandler
//
//

method
DefaultHandler method -------------

public void startDocument ()


95

{
System.out.println("XML ");
}
public void endDocument ()
{
System.out.println("XML ");
}
public void startElement (String uri,
String localName,
String qName,
Attributes attributes)
throws SAXException
{
indentcount ++;
String indent = new String("");
for (int i=0; i<indentcount; i++) {
indent += "\t";
}System.out.println(":"+indent+ localName);
}
public void endElement (String uri,
String localName,
String qName)
{
indentcount --;
}
public void characters (char ch[], int start,
int length)
{
String s = (new String(ch, start, length)).trim();
if (s.length() > 0) {
String indent = new String("");
for (int i=0; i<indentcount; i++)
indent += "\t";
System.out.println
(":"+ indent +"'" + s.trim() + "'");
}
96

}
}

java -Dorg.xml.sax.parser=org.apache.xerces.parsers.SAXParser
MySAX2Demo2 book.xml

DOM
W3C DOM
event
driven
event handler XML

DOM
XML

DOM DOM
SAX DOM SAX XML
SAX XML
XML DOM

DOM
Apache Xerces DOM org.apache.xerces.parsers.DOMParser
DOM
import org.apache.xerces.parsers.DOMParser;
import org.w3c.dom.Document;

DOMParser parser = new org.apache.xerces.parsers.DOMParser();


XML DOM parser
parser.parse(xmluri);
97

parser DOM doc Document Document


node doc node
Document doc = parser.getDocument();
XML DOM DOM
DOM Docment nodeXML
Docment
DOM org.w3c.dom.Node DOM
org.w3c.dom.NodeList

NodeNodeList
XML Processing InstructionDTD Node
method getNodeType()
node.getNodeType();

DOCUMENT_NODE
DOCUMENT_FRAGMENT_NODE
ELEMENT_NODE
TEXT_NODE
CDATA_SECTION_NODE
COMMENT_NODE
PROCESSING_INSTRUCTION_NODE
ENTITY_NODE
ENTITY_REFERENCE_NODE
DOCUMENT_TYPE_NODE
NOTATION_NODE
ATTRIBUTE_NODE
processNode()
public void processNode(Node node) {
switch (node.getNodeType()) {
case Node.DOCUMENT_NODE:
98

//
break;
case Node.ELEMENT_NODE:
//
break;
case Node.TEXT_NODE:
//
break;
case Node.CDATA_SECTION_NODE:
//
break;
case Node.PROCESSING_INSTRUCTION_NODE:
//
break;
case Node.ENTITY_REFERENCE_NODE:
//
break;
case Node.DOCUMENT_TYPE_NODE:
//
break;
......
}
}

import java.lang.*;
import java.io.*;
import org.apache.xerces.parsers.DOMParser;
import org.w3c.dom.*;
import org.xml.sax.*;
public class MyDOMDemo {
private int indentcount=0;
public static void main(String[] args) {
String xmluri = args[0];
MyDOMDemo myparser = new MyDOMDemo();
myparser.startParse(args[0]);
99

}
public void startParse(String xmluri) {
try {
org.apache.xerces.parsers.DOMParser parser =
new DOMParser();
parser.parse(xmluri);
Document doc = parser.getDocument();
// System.out.println("doc built");
processNode(doc);
} catch (IOException e) {
System.out.println("IO : "+e.getMessage());
} catch (SAXException e) {
System.out.println("SAX : "+e.getMessage());
} catch (Exception e) {
System.out.println(": "+e.getMessage());
}
}
public void processNode(Node node) {
switch (node.getNodeType()) {
case Node.ELEMENT_NODE:
processElementNode(node);
break;
case Node.TEXT_NODE:
processTextNode(node);
break;
case Node.CDATA_SECTION_NODE:
// processCDATANode(node);
break;
case Node.PROCESSING_INSTRUCTION_NODE:
//processPINode(node);
break;
case Node.ENTITY_REFERENCE_NODE:
//processEntityRefNode(node);
break;
case Node.DOCUMENT_TYPE_NODE:
//processDTDNode(node);
break;
100

case Node.COMMENT_NODE:
//processCommentNode(node);
break;
case Node.DOCUMENT_NODE:
NodeList nodes = node.getChildNodes();
if (nodes != null) {
for (int i=0;
i<nodes.getLength();
i++) {
processNode(nodes.item(i));
}
}
break;
} // switch
} // processNode
public void processElementNode(Node node) {
indentcount ++;
System.out.println(
""+
getIndent(indentcount) +
node.getNodeName());
//
NamedNodeMap attributes

= node.getAttributes();

for (int i=0; i<attributes.getLength(); i++) {


Node AttrNode = attributes.item(i);
//
processAttributeNode(AttrNode);
}

//
NodeList elements = node.getChildNodes();
if (elements != null) {
for (int i=0; i<elements.getLength(); i++) {
processNode(elements.item(i));
}
101

}
indentcount --;
} //processElementNode
public void processAttributeNode(Node node) {
indentcount ++;
Attr attr = (Attr)node;
System.out.println(
""+
getIndent(indentcount) +
attr.getName()+"="+attr.getValue());
indentcount--;
}

public void processTextNode(Node node) {


String s = node.getNodeValue().trim();
if (s.length()==0) return;
indentcount ++;
System.out.println(""+
getIndent(indentcount)+
s);
indentcount --;
}

public String getIndent(int indentcount) {


String indent = new String("");
for (int i=0; i<indentcount; i++) {
indent += "\t";
}
return indent;
}
}

102

javac MyDOMDemo.java
classpath xerces.jar
set classpath=.;c:\jdk1.2.2\lib\tools.jar;e:\xml\xerces.jar
XML book2.xml
<book>
<title>Palm Programming</title>
<author>Kuo</author>
<qty>30</qty>
<price unit="NTD">500</price>
</book>

java MyDOMDemo book2.xml

Java write once, run anywhere!

import org.apache.xerces.parsers.DOMParser;

org.apache.xerces.parsers.DOMParser parser =
new DOMParser();
SAX DOM
Sun JAXP
DOM 4

3.5 Sun JAXPJava API for XML parsing


Sun JAXPJava API for XML parsing
Sun Microsystem 1.0.1 XML 1.0 XML namespacesAPI SAX
version 1DOM level 1 Pure Java API XML

103

JAXP Java extension javax


SAX Java
Sun project-X Apache Xerces

Sun JAXP 1.1 JAXP 1.1 ea2


Early Access 2
JAXP 1.1 JAXP 1.0 JAXP Java API for XML Processing
Parsing Processing JAXP JAXP 1.1 SAX version 2
DOM level 2 XSL http://java.sun.com/xml/

Sun JAXP
JDK 1.1.8
PATH JAVA_HOME JDK C:\java
C:\> set PATH=C:\java\bin;%PATH%
C:\> set JAVA_HOME=C:\java
JAXP http://java.sun.com/xml Windows jaxp-1_0_1-win.exeUnix
jaxp-1_0_1.zip jaxp1.0.1

licence

docs/api/*

API javadoc

examples/*

readme.html
install.html

relnotes.html Release
jaxp.jar

Jaxp JAR

parser.jar

Sun JAR SAX1 DOM1

CLASSPATH jaxp.jar parser.jar

Windows
C:\jaxp1.0.1\jaxp.jar; C:\jaxp1.0.1\parser.jar
UnixLinux
/jaxp1.0.1/jaxp.jar:/jaxp1.0.1/parser.jar

JAXP
104

Sun JAXP Packages:


javax.xml.parsers
org.w3c.dom
org.xml.sax
org.xml.sax.helper

SAX
JAXP SAX
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.xml.sax.*;
import java.io.*;
system property
javax.xml.parsers.SAXParserFactory com.sun.xml.parser.Parser

SAXParserFactory factory = SAXParserFactory.newInstance();


SAXParser

parser = factory.newSAXParser();

SAX evnet handler JAXP_SAX_1 HandlerBase


method
public void startElement (String name, AttributeList attrs)
throws SAXException
{ ......
}
public void endElement (String name)
throws SAXException
{ ......
}
public void characters (char buf [], int offset, int len)
throws SAXException
{ ......
}
......
DTD
factory.setValidating(true);
Namespace
factory.setNamespaceAware(true);
XML xmluri XML URIhandler Event Handler
parser.parse(xmluri, handler);
105

JAXP_SAX_1.java
// packages
//import java.io.FileReader;
import java.io.*;
import java.lang.*;
import org.xml.sax.Parser;
import org.xml.sax.AttributeList;
import org.xml.sax.InputSource;
import org.xml.sax.HandlerBase;
import org.xml.sax.SAXException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
//
public class JAXP_SAX_1 extends HandlerBase
{
private int indentcount = 0;
// --------- HandlerBase
//
//

method
HandlerBase method -------------

public void startDocument ()


{
System.out.println("XML ");
}
public void endDocument ()
{
System.out.println("XML ");
}
public void startElement (String name,
AttributeList attributes)
{
indentcount ++;
String indent = new String("");
for (int i=0; i<indentcount; i++) {
indent += "\t";
}
106

System.out.println(":"+indent+ name);
}
public void endElement (String name)
{
indentcount --;
}
public void characters (char ch[], int start,
int length)
{
String s = (new String(ch, start, length)).trim();
if (s.length() > 0) {
String indent = new String("");
for (int i=0; i<indentcount; i++)
indent += "\t";
System.out.println
(":"+ indent +"'" + s.trim() + "'");
}
}

//-------------------------------------------public static void main (String args[])


{
if (args.length==0) {
System.out.println(" JAXP_SAX XML ");
System.exit(0);
}
String xmluri = args[0];
System.out.println("file=" + xmluri);
try {
// SAX
SAXParserFactory factory = SAXParserFactory.newInstance();
SAXParser

parser = factory.newSAXParser();

factory.setValidating(false);
107

factory.setNamespaceAware(false);
//
HandlerBase handler = new JAXP_SAX_1();
// XML XML
FileReader fr = new FileReader(xmluri);
//
//
parser.parse(new InputSource(fr), handler);
}
catch (SAXException e) {
System.out.println("SAX "+e.getMessage());
}
catch (IOException e) {
System.out.println("IO "+e.getMessage());
}
catch (Exception e) {
System.out.println(e.toString());
}

}
}
JAXP SAX version 1 HandlerBase

javac JAXP_SAX_1.java
classpath
XML pc.xml
<?xml version="1.0"?>
<pc>
<cpu vendor="AMD">K7-800</cpu>
<video_card>Voodoo 3 3000</video_card>
<ram>128M</ram>
<hd>Seagate 15G</hd>
</pc>

java JAXP_SAX_1 pc1.xml


108

DOM
JAXP DOM
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;

DocumentBuilderFactory factory=DocumentBuilderFactory.newInstance();
DocumentBuilder parser = factory.newDocumentBuilder();
DTD
factory.setValidating(true);
Namespace
factory.setNamespaceAware(true);
XML DOM
Document doc =parser.parse(xmluri);
(JAXP_DOM_1.java)
// packages
//import java.io.FileReader;
import java.io.*;
import java.lang.*;
import org.xml.sax.InputSource;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.*;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
//
public class JAXP_DOM_1
{
private int indentcount = 0;
public static void main (String args[])
{
109

if (args.length==0) {
System.out.println(" JAXP_DOM_1 XML ");
System.exit(0);
}
String xmluri = args[0];
String p = System.getProperty("javax.xml.parsers.DocumentBuilderFactory");
System.out.println("file=" + xmluri);
System.out.println("property="+p);
MyDOMDemo myparser = new MyDOMDemo();
myparser.startParse(args[0]);
}
public void startParse(String xmluri) {
DocumentBuilderFactory factory= DocumentBuilderFactory.newInstance();
factory.setValidating(false);
factory.setNamespaceAware(false);
try {
DocumentBuilder parser = factory.newDocumentBuilder();
// XML XML
FileReader fr = new FileReader(xmluri);
Document doc = parser.parse(new InputSource(fr));
processNode(doc);
// doc.getDocumentElement ().normalize ();
//System.out.println ("\n" +
//

doc.getDocumentElement().getNodeName());

} catch (SAXParseException e) {
System.out.println ("XML "
+ " line " + e.getLineNumber ()
+ "uri " + e.getSystemId ());
System.out.println("

" + e.getMessage ());

} catch (SAXException e) {
Exception x = e.getException ();
((x == null) ? e : x).printStackTrace ();
} catch (Throwable t) {
t.printStackTrace ();
110

}
}
public void processNode(Node node) {
switch (node.getNodeType()) {
case Node.ELEMENT_NODE:
processElementNode(node);
break;
case Node.TEXT_NODE:
processTextNode(node);
break;
case Node.CDATA_SECTION_NODE:
// processCDATANode(node);
break;
case Node.PROCESSING_INSTRUCTION_NODE:
//processPINode(node);
break;
case Node.ENTITY_REFERENCE_NODE:
//processEntityRefNode(node);
break;
case Node.DOCUMENT_TYPE_NODE:
//processDTDNode(node);
break;
case Node.COMMENT_NODE:
//processCommentNode(node);
break;
case Node.DOCUMENT_NODE:
NodeList nodes = node.getChildNodes();
if (nodes != null) {
for (int i=0;
i<nodes.getLength();
i++) {
processNode(nodes.item(i));
}
}
break;
} // switch
} // processNode
public void processElementNode(Node node) {
111

indentcount ++;
System.out.println(
""+
getIndent(indentcount) +
node.getNodeName());
//
NamedNodeMap attributes

= node.getAttributes();

for (int i=0; i<attributes.getLength(); i++) {


Node AttrNode = attributes.item(i);
//
processAttributeNode(AttrNode);
}

//
NodeList elements = node.getChildNodes();
if (elements != null) {
for (int i=0; i<elements.getLength(); i++) {
processNode(elements.item(i));
}
}
indentcount --;
} //processElementNode
public void processAttributeNode(Node node) {
indentcount ++;
Attr attr = (Attr)node;
System.out.println(
""+
getIndent(indentcount) +
attr.getName()+"="+attr.getValue());
indentcount--;
}
public void processTextNode(Node node) {
String s = node.getNodeValue().trim();
112

if (s.length()==0) return;
indentcount ++;
System.out.println(""+
getIndent(indentcount)+
s);
indentcount --;
}

public String getIndent(int indentcount) {


String indent = new String("");
for (int i=0; i<indentcount; i++) {
indent += "\t";
}
return indent;
}
}

javac

jaxp_dom_1.java

pc1.xml System property


javax.xml.parsers.DocumentBuilderFactory
java -Djavax.xml.parsers.DocumentBuilderFactory=
org.apache.xerces.jaxp.DocumentBuilderFactoryImpl

JAXP_DOM_1 pc1.xml

...
2 XML HTML
<HTML>
<BODY>
<TABLE>
<TR>
113

<TH></TH><TH></TH>
</TR>
<TR>
<TD>CPU</TD><TD>AMD Athlon 1GHz</TD>
</TR>
<TR>
<TD></TD><TD>256M DDR</TD>
</TR>
<TR>
<TD></TD><TD>30G bytes</TD>
</TR>
<TR>
<TD>DVD-ROM</TD><TD>10x</TD>
</TR>
<TR>
<TD></TD><TD>CD-RW 12x</TD>
</TR>
<TR>
<TD></TD><TD>Voodoo 5</TD>
</TR>
<TR>
<TD></TD><TD>Yamaha 724</TD>
</TR>
<TR>
<TD></TD><TD>15 inches TFT</TD>
</TR>
</TABLE>
</BODY>
</HTML>

114

4 Java/XML

4.1 Java/XML
...

Java Java AppletJava


ApplicationJava ServletJava Server Pages

Java XML
XML JDOM Java XML
XSLT J.Clark XT
XML Web Service
XML-RPC SOAP PHP

i18ninternationalization
JavaXML Internet duel-byte encoded
XT SOAP

Java/XML Java Java


Development KitJDK
Sun JDK1.3 SolarisLinux Windows Sun Java
http://java.sun.com/j2se/
Linux JDK RPM tar.gz RedHat Linux tar.gz
Linux
JDK1.3.0 Sun
1.3.0_01
http://java.sun.com/j2se/1.3.0_01/index.html
Java Sun
Java Unicode
Java Sun
JDK ......
115

Sun Java Linux Linux


Sun Java Java Development Kits
Linux Blackdown JDK JDK1.0.x Java SDK 1.3.x Sun
1.3 Linux JDK Blackdown

Blackdown JDK
http://www.blackdown.org/java-linux.html
Blackdown JDK
ftp://ftp1.sinica.edu.tw/pub1/java/linux/blackdown/

XML parser
Java Java XML
Windows Linux

SAX version 1 version 2


http://www.megginson.com/SAX
lfred XML
http://www.opentext.com/services/content_management_services/aelfred.zip
Apache Xerces
http://xml.apache.org/dist/xerces-j/
JDOM
http://www.jdom.org
JDOM beta 5 jdom-b5.tar.gz jdom-b5.zip
JDOM
JAXP
http://java.sun.com/xml

Web Server
Java appletJava servlet Java Server Pages Web
Server
Web Server Apache Apache Web Server
http://www.apache.org
Apache
Linux Apache Web Server
116

Linux Apache RedHat Linuxdatadir


/home/httpd/html
Apache httpd.confaccess.confsrm.conf RedHat Linux /etc

Apache apache_1.3.xx.tar.gz/usr/local Apache

tar zxvf apache_1.3.xx.tar.gz


cd /usr/local/apche_1.3.xx
./configure --prefix=/usr/local/apache
make
make install
Apache Web Server
/usr/local/apache/bin/apachectl start
/usr/local/apache/htdocs
Windows Apache Web Server
Windows Apache apache_1_3_12_win32.exe
\Apache Group\Apache\htdocs

JSDKJava Servlet Development Kit


Sun Servlet 1999/04/21 JSDK 2.1 Servlet 2.1
JSWDKJavaServer Pages Web Development Kit Jakarta-Tomcat
servlet.jar Servlet JSWDK Jakarta-Tomcat

Servlet engine Servlet

JSWDKJavaServer Pages Web Development Kit


JSP Sun

UnixJDK1.1.x
Win32JDK1.2

Windows
Linuxbash
set JAVA_HOME=c:\jdk1.2.2

export JAVA_HOME =/jdk1.2.2

set CLASSPATH=.;%JAVA_HOME%\

export CLASSPATH=.:$JAVA_HOME/

lib/tools.jar

lib\tools.jar

JSWDK
Webserver.jar Servlet Engine
117

lib/jspengine.jar JSP Engine


lib/servlet.jar Servlets API
lib/xml.jar XML
JSWDK JSP ServletsHTML URL

http://www.MyBookstore.com/bookshop
JSWDK
JSWDK JSWDK /jswdk-1.0.1
/jswdk-1.0.1/bookshop/WEB-INF/servlets
JSWDK Webserver.xml
<WebApplication id="bookshop"

mapping="/bookshop" docBase="baseball="/>

Servlets
Servlet bookshop/WEB-INF/servlets
bookshop/WEB-INF/servlets.properties
bookshop.code=BookshopServlet
bookshop.initparams=foo

http://www.MyBookstore.com/bookshop/servlet/BookshopServlet
servlet BookshopServlet

bookshop/WEB-INF/mappings.properties
/Bookshop=bookshop
bookshop servlets.properties bookshop.code
http://www.bookstore.com:8080/bookshop/Bookshop
bookshop Bookshop
JSP JavaBeans
JSP jsp

118

/bookshop/jsp
JavaBeans JSWDK server
Classpath JSWDK sever startserver.bat

WEBAPP/WEB-INF/mappings.properties WEBAPP/WEB-INF/servlets.properties
Tomcat server
JSP http://localhost:8080/WEBAPP/yourjsp.jsp

Servlet engine and JSP engine


Java Servlet JavaServer Pages Web Server Web Server
Servlet engine JSP engine
Apache Web Server Apache Group Jakarta Tomcat
Servlet JSP engine Web Server Tomcat

Tomcat Apache Web Server Microsoft Internet Information Server 4.0


Microsoft Personal Web Server, version 4.0 Netscape Enterprise Serverversion 3.0

http://jakarta.apache.org/

Tomcat Apache Web Server


Tomcat Apache Web Server
Apache Web Server JDK
Tomcat jakarta-tomcat.tar.gz
tar zxvf jakarta-tomcat.tar.gz
/Jakarta-tomcat

Linux Windows
CLASSPATH

.:/jdk1.2.2/lib/tools.jar .;c:\jdk1.2.2\lib\tools.jar

JAVA_HOME

/jdk1.2.2

c:\jdk1.2.2

TOMCAT_HOME /Jakarta-tomcat

c:\Jakarta-tomcat

ANT_HOME

c:\Jakarta-tomcat

/Jakarta-tomcat

Apache Apache mod_jserv.soLinux


http://jakarta.apache.org/builds/tomcat/release/v3.1/bin/linux/i386/mod_jserv.so
(Win32 ApacheModuleJServ.DLL)
Apache RedHat Linux /usr/lib/apache
119

Tomcat jakarta-tomcat/conf tomcat-apache.conf

LoadModule jserv_module modules/mod_jserv.so


Apache Web Server http.confRedHat Linux /etc/httpd/conf
Include "/jakarta-tomcat/conf/tomcat-apache.conf"
Tomcat server

4.2 Client side Java XML


Client side Java XML Java applet XML

Java xBase
dBASEClipperFoxPro DOS Novell Netware
14400bps modem
Java applet
Java applet Java
Java applet Java applet Netscape
Navigator Microsoft Internet Explorer Java applet

Java applet XML


Java applet XML Joystick.xml Java applet
XML
hard core

XML
XML
HTML XML HTML
Applet XML XML
HTML XML
lfred Event
Handler
Joystick.class
120

lfred Event Handler MyHandler.class XML


Joystick
ProductsDemo.class Joystick
HTML ProductsDemo.html Applet
ProductsDemo2.html jar

Java applet
XML lfred 23KB applet
XML
Java applet Java applet
JDK appletviewer Applet

XML
lfred validating XML
DTD validating XML
XML
DTD joystick.dtd
<!ELEMENT PRODUCTS (JOYSTICK)+>
<!ELEMENT JOYSTICK (JSNAME,

COMPANY, WEBSITE, IO, BUTTON, HAT,

THROTTLE, RUDDER, PRICE, PICTURE)>


<!ELEMENT JSNAME (#PCDATA) >
<!ELEMENT COMPANY (#PCDATA)>
<!ELEMENT WEBSITE (#PCDATA)>
<!ELEMENT IO (#PCDATA)>
<!ELEMENT BUTTON (#PCDATA)>
<!ELEMENT HAT (#PCDATA)>
<!ELEMENT THROTTLE (#PCDATA)>
<!ELEMENT RUDDER (#PCDATA)>
<!ELEMENT PRICE (#PCDATA)>
<!ELEMENT PICTURE EMPTY>
<!ATTLIST PICTURE SOURCE

(#PCDATA) #REQUIRED>

XML joystick.xml
<?xml version="1.0" ?>
<!DOCTYPE PRODUCTS SYSTEM 'joystick.dtd'>
121

<PRODUCTS>
<JOYSTICK>
<JSNAME>Saitek X36 Flight Controller</JSNAME>
<COMPANY> Saitek </COMPANY>
<WEBSITE>http://www.saitek.com/</WEBSITE>
<IO>USB</IO>
<PROGRAMMABLE>Yes</PROGRAMMABLE>
<BUTTON>7</BUTTON>
<HAT>3</HAT>
<THROTTLE>Yes</THROTTLE>
<RUDDER>Yes</RUDDER>
<PRICE>$99.95</PRICE>
<PICTURE SOURCE="Saitek_X36.gif"/>
</JOYSTICK>
<JOYSTICK>
<JSNAME>F-16 CombatStick(R) USB</JSNAME>
<COMPANY>CH Products</COMPANY>
<WEBSITE>http://www.chproducts.com</WEBSITE>
<IO>USB</IO>
<PROGRAMMABLE>Yes</PROGRAMMABLE>
<BUTTON>6</BUTTON>
<HAT>2</HAT>
<THROTTLE>Yes</THROTTLE>
<RUDDER>No</RUDDER>
<PRICE>$74.95</PRICE>
<PICTURE SOURCE="CH_F16CS2000.gif"/>
</JOYSTICK>
<JOYSTICK>
<JSNAME>SFS Flight Controller USB</JSNAME>
<COMPANY>Suncom Inc.</COMPANY>
<WEBSITE>http://www.suncominc.com</WEBSITE>
<IO>USB</IO>
<PROGRAMMABLE>Yes</PROGRAMMABLE>
<BUTTON>5</BUTTON>
<HAT>1</HAT>
<THROTTLE>No</THROTTLE>
<RUDDER>No</RUDDER>
<PRICE>$95</PRICE>
<PICTURE

SOURCE="Suncom_SFSFC_USB.jpg"/>

</JOYSTICK>
122

</PRODUCTS>

Joystick.java
Joystick Joystick.java
import java.util.*;
/**
XML
XML
XML getXXX method

*/
class Joystick {
private String jsname, company, Website,
io, button,hat,throttle,rudder,
price, picture;

/** Constructor
*/
public Joystick (String jsname, String company,
String Website,
String io, String button, String hat,
String throttle,String rudder,
String price, String picture) {
this.jsname = jsname;
this.company = company;
this.Website = Website;
this.io = io;
this.button = button;
this.hat = hat;
this.throttle = throttle;
this.rudder = rudder;
this.price = price;
this.picture = picture;
//... debug
//System.out.println("Joystick.class:"+jsname+","+company
//+","+Website+","+io+","+price+","+picture);
}
123

public String getJsname () { return jsname; }


public String getCompany () { return company;
}
public String getWebsite () { return Website;
}
public String getIo () { return io; }
public String getButton () { return button; }
public String getHat () { return hat; }
public String getThrottle () { return throttle; }
public String getRudder () { return rudder; }
public String getPrice () { return price; }
public String getPicture () { return picture;

}
MyHandler.java
MyHandler.java XML
import com.microstar.xml.XmlHandler;
import com.microstar.xml.XmlParser;
import com.microstar.xml.HandlerBase;
import java.applet.*;
import java.awt.*;
import java.util.*;
class MyHandler extends HandlerBase {
private Choice jschoice;

// awt choice

private Vector js;

// Vector

private String currentElementName;// Event handler


private String jsname;

// XML

private String company, Website;


private String button, hat, throttle, rudder;
private String io, price;
private String picture;
private String attrname;

//

private String attrvalue;

//
124

// Joystick Vector
public MyHandler (Choice jschoice) {
js = new Vector();
this.jschoice = jschoice;
}
// js Vector Joystick method
public Joystick getJs (int index) {
if (index < js.size()) {
// ...debug
System.out.println("Index:"+ new
Integer(index).toString());
return (Joystick) js.elementAt(index);
}
else {
// ...debug
//System.out.println("Index > js no.");
}

// return (Joystick) js.elementAt(index);


}

// HandlerBase method
public void startElement (String name) {
//
currentElementName = name;
// PICTURE picture
if (currentElementName.equals ("PICTURE")) {
picture = attrvalue;
//... debug
System.out.println("PICTURE "+attrname+":"+attrvalue);
}

125

}
// tag Joystick
// XML Joystick
// Joystick js Vector
public void endElement (String name) {

if (name.equals ("JOYSTICK")) {
Joystick j = new Joystick(
jsname, company, Website,
io, button,hat,
throttle,rudder,
price, picture);
js.addElement(j);
//... debug
// System.out.println("new JS was built");
}

}
//
public void attribute(String aname, String avalue,
boolean isSpecified) {
attrname = aname;
attrvalue = avalue;
}
//
public void charData (char ch[], int start, int length) {
String s = new String (ch, start, length);
if (s.trim().length() == 0)
return;
//.. debug
System.out.println("data:"+currentElementName+"("+s+")");
if (currentElementName.equals ("JSNAME"))
jsname = s;
126

else if (currentElementName.equals ("COMPANY"))


company = s;
else if (currentElementName.equals ("WEBSITE"))
Website = s;
else if (currentElementName.equals ("IO"))
io = s;
else if (currentElementName.equals ("BUTTON"))
button = s;
else if (currentElementName.equals ("HAT"))
hat = s;
else if (currentElementName.equals ("THROTTLE"))
throttle = s;
else if (currentElementName.equals ("RUDDER"))
rudder = s;
else if (currentElementName.equals ("PRICE"))
price = s;
}
// XML Vector Joystick
//(jsname) jschoice
public void endDocument () {
Joystick j;
for (int i=0; i<js.size(); i++) {
j = (Joystick) js.elementAt(i);
jschoice.addItem (j.getJsname());
//... debug
System.out.println("Add jsname to choice:"+j.getJsname());
}
}
}
ProductsDemo.java
Applet ProductsDemo.javaApplet
import com.microstar.xml.XmlHandler;
import com.microstar.xml.XmlParser;
import com.microstar.xml.HandlerBase;
import java.applet.*;
import java.net.*;
import java.awt.*;
import java.awt.event.*;
127

import java.util.*;
import java.io.*;
public class ProductsDemo extends Applet implements ItemListener {
private XmlParser parser;

// Alfred

private MyHandler handler;

//
// Alfred

private java.awt.Choice jschoice;

// GUI

private Image pic[];

//

private MediaTracker tracker;


private Hashtable hashtable;
private Dimension dim;
private Graphics offScreenGraphics;
private Image offScreen;
private Joystick curJS;
private String font1;

// Joystick
// HTML

private int picX; // HTML X


private int picY; // HTML Y
// Applet
public void init ()
{
// choice
initGUI();
// XML
handler = new MyHandler(jschoice);
parser = new XmlParser();

// Event Handler

// XML

parser.setHandler(handler); // Event Handler XML


// HTML HTML
// <PARAM NAME="url" VALUE=""> tag
//
String xmldoc = getParameter ("url");
font1 = getParameter ("font1");

// XML

// Applet

// Applet
picX = new Integer( getParameter ("picX") ).intValue();
128

picY = new Integer( getParameter ("picY") ).intValue();


// ... for debug
// System.out.println ("URL: "+xmldoc);
try {
// XML
URL xmlURL = new URL (getDocumentBase(), xmldoc);
//... debug
// System.out.println ("start parse "+xmlURL.toString());
// XML
parser.parse(xmlURL.toString(),
(String)null, (String) null);
//.. debug
// System.out.println ("parse ok "+xmlURL.toString());
} catch (Exception e) {
e.printStackTrace();
}
//
initPics();

}
/** Init GUI of Applet */
// jschoice
private void initGUI () {
this.setLayout (null);
jschoice = new java.awt.Choice();
jschoice.addItem ("......");
this.add (jschoice);
jschoice.addItemListener (this);
jschoice.setBounds (10,40,200,30);
}
/**

*/

private void initPics () {


129

String picfile= new String("");


tracker = new MediaTracker (this);
hashtable = new Hashtable();
//
int itemCount = jschoice.getItemCount();
//
pic= new Image[itemCount-1];
for (int i=0; i<itemCount-1; i++) {
// Joystick
picfile = handler.getJs(i).getPicture();
// for debug
// System.out.println("init Pics: "+picfile);
// pic
pic[i] = getImage (getDocumentBase(),
picfile);
// hashtable
hashtable.put (picfile, new Integer(i));
tracker.addImage (pic[i], i);
}
try {
tracker.waitForAll();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//
public void itemStateChanged (ItemEvent e) {
int index = jschoice.getSelectedIndex();
if (index==0) // jschoice
return;
// Joystick
curJS = (Joystick) handler.getJs (
index-1);
// Applet
repaint();
130

// ... for debug


//System.out.println("jsname:"+curJS.getJsname());
//System.out.println("IO:"+curJS.getIo());
//System.out.println("Com:"+curJS.getCompany());
//System.out.println("Web:"+curJS.getWebsite());
//System.out.println("Pic:"+curJS.getPicture());
//System.out.println("$:"+curJS.getPrice());
// ..............
}

public void paint (Graphics g) {


update (g);
}
// Applet
public void update (Graphics g) {
if (dim==null) {
dim = this.getSize ();
// Java double buffer
offScreen = createImage (dim.width, dim.height);
offScreenGraphics = offScreen.getGraphics();
}
offScreenGraphics.setColor (Color.white);
offScreenGraphics.fillRect (0,0,dim.width, dim.height);
offScreenGraphics.setColor (Color.black);
offScreenGraphics.setFont (new Font
(font1, Font.BOLD, 16));
offScreenGraphics.drawString ("",

10,20);

offScreenGraphics.setColor (new Color (140,30,72));


offScreenGraphics.setFont (new Font (font1, Font.PLAIN, 14));
// Joystick
if (curJS != null) {
offScreenGraphics.drawString (": "+
curJS.getCompany(), 10,100);
offScreenGraphics.setColor (new Color (50,40,151));
131

offScreenGraphics.drawString (": "+


curJS.getWebsite(), 10, 120);
offScreenGraphics.drawString (": "+
curJS.getIo(), 10, 140);
offScreenGraphics.drawString (": "+
curJS.getPrice(), 10, 160);
offScreenGraphics.drawString (": "+
curJS.getButton(), 10,180);
offScreenGraphics.drawString (":"+
curJS.getHat(), 10,200);
offScreenGraphics.drawString (":"+
curJS.getThrottle(), 10,220);
offScreenGraphics.drawString (": "+
curJS.getRudder(), 10,240);
Integer picIndex = (Integer)
hashtable.get(curJS.getPicture());
// ... for debug
//System.out.println("PicIndex="+picIndex.intValue());
offScreenGraphics.drawImage
(pic[picIndex.intValue()], picX,picY, this);
}
//
g.drawImage (offScreen, 0,0, null);
}
}

classpath aelfred.jar
Applet
javac ProductsDemo.java
Joystick.java MyHandler.java ProductsDemo.java

Joystick.class
MyHandler.class
ProductsDemo.class
132

appletviewer
HTML ProdutctsDemo.html Applet
HTML
<HTML>
<HEAD>
<TITLE></TITLE>
</HEAD>
<BODY>
<H3></H3>
<HR>
<APPLET CODE="ProductsDemo.class" WIDTH=350 HEIGHT=380>
<PARAM NAME="url" VALUE="Joystick.xml">
<PARAM NAME="font1" VALUE="">
<PARAM NAME="picX" VALUE="170">
<PARAM NAME="picY" VALUE="160">
</APPLET>
<HR>
</BODY>
</HTML>
JDK appletviewer
appletviewer ProductsDemo.html
applet appletviewer

System.out.println(......);

133

HTML ProductsDemo.html

134

Applet Web Server Web Server


Apache Web Server

Apache Web Server datadirRedHat Linux /home/httpd/html/


Win32 .../Apache group/Apache/htdocs/ AppletTest
copy
ProductsDemo.class
MyHandler.class
Joystick.class
Saitek_X36.gif
Suncom_SFSFC_USB.jpg
CH_F16CS2000.gif
ProductsDemo.html
lfred class aelfred.jar
WinZip Unzip com/microstar/xml/*.class Web Server doc
root AppletTest

135

Apache Web Server http://localhost/AppletTest/ProductsDemo.html

class lfred class jar


class Alfred com/
ProductsDemo.jar
jar cvf ProductsDemo.jar com/ ProductsDemo.class Joystick.class MyHandler.class
jar Java classXML

ProductsDemo.jar AppletTest
HTML
<APPLET CODE=ProductsDemo.class archive="ProductsDemo.jar" WIDTH=350 HEIGHT=380>
archive
ProductsDemo2.html
<HTML>
<HEAD>
<TITLE></TITLE>
</HEAD>
<BODY>
<H3></H3>
<HR>
<APPLET CODE=ProductsDemo.class archive="ProductsDemo.jar" WIDTH=350 HEIGHT=380>
136

<PARAM NAME="url" VALUE="Joystick.xml">


<PARAM NAME="font1" VALUE="">
<PARAM NAME="picX" VALUE="170">
<PARAM NAME="picY" VALUE="160">
</APPLET>
<HR>
</BODY>
</HTML>
http://localhost/AppletTest/ProductsDemo2.html

Java Application XML


Java ApplicationJava Java Java Application Java
Visual MachineJVM JDK java jreJava Runtime Environment
Java Application
Java Application main() method
public static void main(String args[])
Java Application Java main() method
JavaBeans main() method Java Application
JavaBeans

XML

XML JDOM

JDK
XML JDOM Apache Xercesjdom.jarxerces.jar

JDOM
3 SAX DOM SAX DOM
Java
137

SAX
DOM XML

JDOM Java
XML API Brett McLaughlinJason Hunter James Duncan Davidson JDOM
Java API J Java DOM XML
DocumentObject model DOM
JDOM namespaceDTD Java 2 ListMap
JDOM Java XML SAX DOM Java
XML SAX
XML SAX DOM
JDOM http://www.jdom.org
JDOM API
JDOM
org.jdom.input.SAXBuilder SAX
org.jdom.input.DOMBuilder DOM
JDOM JDOM Document model DOM DOMBuilder
SAXBuilder XML

Builder builder = new SAXBuilder(saxDriverClass);


Document doc = builder.build(xmldoc);
Builder build(...) method
File
InputStream
URL
InputStream XML

org.jdom.Element

Element element = new Element(element_name);


attribute
element.addAttribute(attribute_name);

//
List child_elements = element.getChildren();
//
List child_elements = element.getChildren(child_element_name);

138

List attributes = element.getAttributes(attribute_name)

XML
JDOM API XML
org.jdom.output.XMLOutputter

XMLOutputter()
XMLOutputter(String indent)
XMLOutputter(String indent, boolean newlines)
method
output(Document doc, OutputStream out)
XML

XML
XML addressbook.xml DTD
<?xml version='1.0' encoding='Big5' ?>
<!ELEMENT addressbook person+ >
<!ELEMENT person name, address, telo>
<!ELEMENT name #PCDATA>
<!ELEMENT addressbook #PCDATA>
<!ELEMENT telo #PCDATA>
XML
<?xml version="1.0" encoding="Big5"?>
<addressbook>
<person>
<name></name>
<address></address>
<telo>27093666</telo>
</person>
</addressbook>

Person.java
Addressbook.java XML
MyWindowListener.java GUI
ABGUI.java

139

Persion.java
Person.java
/**
* XML Person
*
*/
class Person {
private String name, address, telo;
/** Constructor
*/
public Person (String name,
String address,
String telo) {
this.name = name;
this.address = address;
this.telo = telo;
}
public Person () {
this("","","");
}

public String getName () { return name; }


public String getAddress () { return address; }

140

public String getTelo () { return telo; }


}
getXXX() method

Addressbook.java
Addressbook.java XML
import java.io.*;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.JDOMException;
import org.jdom.input.SAXBuilder;
import org.jdom.output.XMLOutputter;
import java.util.*;
/**
* Addressbook
*
*
*/
public class Addressbook {
// static
public static Addressbook ab = new Addressbook();
// method
public static Addressbook getAddressbook() {
return ab;
}
// JDOM XML Xerces SAX parser
private static final String DEFAULT_SAX_DRIVER_CLASS =
"org.apache.xerces.parsers.SAXParser";
private String saxDriverClass;
private SAXBuilder builder;
//JDOM
private Document doc;
private Element root;
// Person Hashtable
private Hashtable table = new Hashtable();
private String xmldoc = "";
141

// private
private Addressbook() {
this.saxDriverClass = DEFAULT_SAX_DRIVER_CLASS;
builder = new SAXBuilder(saxDriverClass);
}
// XML
public void startParse(String filename)
throws IOException, JDOMException {
this.xmldoc = filename;
// InputStream
FileInputStream fis = new FileInputStream(filename);
// InputStream InputStreamReader
// Big5
InputStreamReader isr = new InputStreamReader(fis, "Big5");
// InputStreamReader JDOM Document
doc = builder.build(isr);
// JDOM Document
root = doc.getRootElement();
// List
List list=root.getChildren();
Element element;
Iterator fields;
String name="";
String address="";
String telo="";
Person newPerson;
// List
//
// Person
if (! list.isEmpty() ) {
Iterator records = list.iterator();
142

while (records.hasNext()) {
element = (Element)records.next();
if (element.getName().equals("person")) {
fields = element.getChildren().iterator();
while (fields.hasNext()) {
element = (Element)fields.next();
if (element.getName().equals("name")) {
name = element.getText();
System.out.println("name="+element.getText());
}
else if (element.getName().equals("address")) {
address = element.getText();
System.out.println("address="+element.getText());
}
else if (element.getName().equals("telo")) {
telo = element.getText();
System.out.println("telo="+element.getText());
}
}
// Person
newPerson = new Person(
name, address, telo);
// Person Hashtable key
table.put(name, newPerson);
}
}
}
}

// xmldoc OutputStream
public void close()
throws IOException, JDOMException {
startOutputXML(new FileOutputStream(xmldoc));
}
143

// XML XMLOutputter OutputStream


private void startOutputXML(OutputStream out)
throws IOException, JDOMException {
// Create an outputter with default formatting
XMLOutputter outputter = getXMLOutputter();
outputter.output(doc, out);
}

// XMLOutputter Big5
private XMLOutputter getXMLOutputter()
throws IOException, JDOMException {
// Create an outputter with certain encoding
XMLOutputter outputter = new XMLOutputter(" ", true, "Big5");
outputter.setTrimText(true);
outputter.setExpandEmptyElements(true);
return outputter;
}
//
public void add(Person p) {
// add Person to Hashtable
table.put(p.getName(), p);
addToXML(p);
}

// JDOM
private void addToXML(Person p) {
Element curPerson =
new Element("person");
Element curName = new Element("name");
curName.addContent(p.getName());
Element curAddress = new Element("address");
curAddress.addContent(p.getAddress());
144

Element curTelo = new Element("telo");


curTelo.addContent(p.getTelo());
curPerson.addContent(curName);
curPerson.addContent(curAddress);
curPerson.addContent(curTelo);
root.addContent(curPerson);
}
//
public Person searchByName(String key) {
// search name in XML tree
Person p = (Person)table.get(key);
return p;
}

//
public void remove(String name) {
Person p = (Person)table.get(name);
if (p==null) {
System.out.println(name+" not found");
return;
};
if (table.remove(name) == null) {
System.out.println("remove "+name+" error!");
return;
}
removeFromXML();
}
// JDOM
private void removeFromXML() {
Enumeration persons = table.elements();
Person p;
//System.out.println("new root");
145

root = new Element("addressbook");


//System.out.println("add elements to root");
while (persons.hasMoreElements() ) {
p = (Person)persons.nextElement();
//System.out.println("add one person: "+p.getName());
addToXML(p);
}
doc.setRootElement(root);
}
}

MyWindowListener.java
Java GUI MyWindowListener.java
import org.jdom.JDOMException;
import java.awt.*;
import java.awt.event.*;
import java.io.IOException;
class MyWindowListener extends WindowAdapter
{
// Addressbook
Addressbook addressbook = Addressbook.getAddressbook();
public void windowClosing(WindowEvent e) {
try {
// XML
addressbook.close();
System.exit(1);
} catch (JDOMException ex) {
System.out.println("JDOM Exception: "+ex.toString());
} catch (IOException ex) {
System.out.println("IO Excption:"+ex.toString());
}
}
}

ABGUI.java
ABGUI.java
import java.awt.*;
import java.awt.event.*;
146

import javax.swing.*;
import java.net.*;
/**
* Addressbook
* Graphic User Interface
*
*
*
*/
public class ABGUI extends JFrame
{
private Person p;
private Addressbook addressbook = Addressbook.getAddressbook();
private String xmldoc = "addressbook.xml";
private Font f1 = new Font("", Font.PLAIN, 16);
private JButton buttonAdd=new JButton("");
private JButton buttonSearchByName=new JButton("");
private JButton buttonRemove =new JButton("");
private JButton buttonClearFields=new JButton("");
private JTextField fieldName=new JTextField("",40);
private JTextField fieldAddress=new JTextField("",40);
private JTextField fieldTelo=new JTextField("",40);
private JLabel labelName = new JLabel(":");
private JLabel labelAddress = new JLabel(":");
private JLabel labelTelo = new JLabel(":");
private JLabel labelMsg = new JLabel("");
private Container c;
public ABGUI()
{
super("");
// XML
try {
147

addressbook.startParse(xmldoc);
} catch (Exception e) {
System.out.println(e.toString());
}
// GUI
c = getContentPane();
c.setLayout(new BorderLayout());
JPanel pn = new JPanel();
JPanel pc = new JPanel();
buttonAdd.setFont(f1);
buttonSearchByName.setFont(f1);
buttonRemove.setFont(f1);
buttonClearFields.setFont(f1);
fieldName.setFont(f1);
fieldAddress.setFont(f1);
fieldTelo.setFont(f1);
labelName.setFont(f1);
labelAddress.setFont(f1);
labelTelo.setFont(f1);
labelMsg.setFont(f1);
pn.add(buttonAdd);
pn.add(buttonSearchByName);
pn.add(buttonRemove);
pn.add(buttonClearFields);
c.add(pn,BorderLayout.NORTH);
pc.add(labelName);
pc.add(fieldName);
pc.add(labelAddress);
pc.add(fieldAddress);
pc.add(labelTelo);
148

pc.add(fieldTelo);
c.add(pc,BorderLayout.CENTER );
c.add(labelMsg,BorderLayout.SOUTH);
setSize(400,250);
setVisible(true);
buttonAdd.addActionListener
(new AppListener());
buttonSearchByName.addActionListener
(new AppListener());
buttonRemove.addActionListener
(new AppListener());
buttonClearFields.addActionListener
(new AppListener());

}
// GUI event Listener
class AppListener implements ActionListener
{
public void actionPerformed(ActionEvent e) {
String name = fieldName.getText();
String address =fieldAddress.getText();
String telo=fieldTelo.getText();

if (e.getSource()==buttonAdd) {
p = new Person(
name, address, telo
);
addressbook.add(p);
} else if(e.getSource()==buttonSearchByName) {
p = addressbook.searchByName(name);
149

if (p!=null) {
fieldName.setText(p.getName());
fieldAddress.setText(p.getAddress());
fieldTelo.setText(p.getTelo());
}
else {
labelMsg.setText("!");
}
} else if (e.getSource()==buttonRemove) {
addressbook.remove(name);
} else if (e.getSource()==buttonClearFields) {
fieldName.setText("");
fieldAddress.setText("");
fieldTelo.setText("");
labelMsg.setText("");
}
}
}

public static void main(String args[])


{
ABGUI app = new ABGUI();
app.addWindowListener(new MyWindowListener());
}
}

CLASSPATH jdom.jarxerces.jarsax2.jar
JDK tools.jar
PATH JDK bin Windows
SET PATH=c:\jdk1.2.2\bin;%PATH%
150


javac ABGUI.java

ABGUI.class
ABGUI$AppListener.class
MyWindowListener.class
Addressbook.class
Person.class

java ABGUI

4.3 Server side Java XML


Server side Java XML

HTTP HTTP

151

HTTP form
CGIcommon gateway interface
URL CGI perl C

CGI
CGI

CGI CGI
CGI

business-to-consumerB2Cbusiness-to-businessB2B

Java Servlet Java

Java servlet XML


Java Applet XML Java
Servlet Java Applet
Java Java Applet Servlet HTML Java
Applet

JDK
JSDK JSWDK Servlet servlet.jar
Tomcat JSDK JSWDK Web Server

XML Sun Jaxp SAX jaxp.jarSAX1 sax.jar


SAX parser.jar

XML
Joystick.xml XML
Saitek_X36.gifCH_F16CS2000.gif Suncom_SFSFC_USB.jpg

152

Products FORM POST


server ShowItem
ShowItem
XML_ReaderSAX Event Handler Item Servlets
Products ShowItem
Item XML

Servlet Products Products XML_ Reader startParse() method


XML Item Vector js Products ShowItem XML_Reader
Vector js

Item
SAX XML Item
Item.java
import java.util.*;
/**
XML
*/
class Item {
private String jsname, company, Website,
io, button,hat,throttle,rudder, programmable,
price, picture;
/** Constructor
*/
public Item (String jsname, String company,
String Website,
String io, String button, String hat,
String throttle,String rudder, String programmable,
String price, String picture) {
153

this.jsname = jsname;
this.company = company;
this.Website = Website;
this.io = io;
this.button = button;
this.hat = hat;
this.throttle = throttle;
this.rudder = rudder;
this.programmable = programmable;
this.price = price;
this.picture = picture;
//... debug
//System.out.println("Item.class:"+jsname+","+company
//+","+Website+","+io+","+price+","+picture);
}

public String getJsname () { return jsname; }


public String getCompany () { return company; }
public String getWebsite () { return Website; }
public String getIo () { return io; }
public String getButton () { return button; }
public String getHat () { return hat; }
public String getThrottle () { return throttle; }
public String getRudder () { return rudder; }
public String getProgrammable() {return programmable;}
public String getPrice () { return price; }
public String getPicture () { return picture;

}
154

Products
Servlet ShowItem
import java.io.*;
import java.lang.*;
import java.net.*;
import java.util.*;
import org.xml.sax.Parser;
import org.xml.sax.AttributeList;
import org.xml.sax.InputSource;
import org.xml.sax.HandlerBase;
import org.xml.sax.SAXException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import javax.xml.parsers.FactoryConfigurationError;
import javax.xml.parsers.ParserConfigurationException;
import javax.servlet.*;
import javax.servlet.http.*;
public class Products extends HttpServlet {
// XML_Reader XML
private XML_Reader xr = XML_Reader.getXr();
//
private Item curJS;

public void init ()


{
// Tomcat conf/web.xml xmldoc XML URL

String xmldoc = getInitParameter("xmldoc");


// debug ....
System.out.println("start:"+xmldoc);
try {
// XML URL URL
URL xmlURL = new URL (xmldoc);
// XML
xr.startParse(xmlURL.openStream());
} catch (MalformedURLException e) {
System.err.println("MalformedURL Exception:"+e.getMessage());
155

} catch (Exception e) {
System.err.println("Exception:"+e.toString());
}
}
public void doPost(HttpServletRequest request,
HttpServletResponse response)
throws IOException, ServletException
{
doGet(request, response);
}
public void doGet(HttpServletRequest request,
HttpServletResponse response)
throws IOException, ServletException
{
// HTML Big5
response.setContentType("text/html;charset=Big5");
PrintWriter out = response.getWriter();
// XML_Reader
int jssize = xr.getJsSize();
int i;
String s = (new Integer(jssize)).toString();
//
// ShowItem
out.println("<html>");
out.println("<body>");
out.println("<head>");
out.println("<title> V1.0</title>");
out.println("</head>");
out.println("<body>");
out.println("<DIV align='center'>");
out.println("<h1></h1>");
out.println("<FORM method='post' action='ShowItem'>");
out.println("<SELECT name='jsselect'>");
String key;
156

for (i=0; i<jssize; i++) {


curJS = xr.getJs(i);
out.println("<option value=");
out.println(i);
out.println(">"+curJS.getJsname()+"</option>");
}
out.println("</select>");
out.println("<INPUT TYPE='SUBMIT' NAME='submit' VALUE=''>");
out.println("</form>");
out.println("</body>");
out.println("</html>");
}
}

XML_Reader
SAX HandlerBase XML Vector js
import java.io.*;
import java.lang.*;
import org.xml.sax.Parser;
import org.xml.sax.AttributeList;
import org.xml.sax.InputSource;
import org.xml.sax.HandlerBase;
import org.xml.sax.SAXException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import javax.xml.parsers.FactoryConfigurationError;
import javax.xml.parsers.ParserConfigurationException;
import java.util.*;
// SAX1 HandlerBase
public class XML_Reader extends HandlerBase
{
// Item Vector
private Vector js;
// SAX
private String currentElementName;
//
private String jsname;
157

private String company, Website;


private String button, hat, throttle, rudder;
private String programmable;
private String io, price;
private String picture;
private String aname;
private String avalue;
// Servlets xr
//
// XML_Reader
//
public static XML_Reader xr = new XML_Reader();
// method
public static XML_Reader getXr() {
return xr;
}
// ....................................
// new private
private XML_Reader() {
js = new Vector();
}
//-------------------------------------------// XML method
public void startParse(InputStreamReader isr)
throws IOException {
startParse(new InputSource( isr ));
}
// XML startParse method
// XSLT
public void startParse(InputStream is)
throws IOException {
startParse(new InputStreamReader(is, "Big5"));
158

}
public void startParse(FileReader fr)
throws IOException {
startParse(new InputSource( fr ));
}
public void startParse(String filename)
throws IOException {
startParse(new FileReader(filename) );
}
// startParse method method
public void startParse(InputSource in) {
boolean isValidating = false;
try {
// SAX
SAXParserFactory factory =
SAXParserFactory.newInstance();
SAXParser

parser = factory.newSAXParser();

factory.setValidating(isValidating);
factory.setNamespaceAware(false);
parser.parse(in, this);
}
catch (SAXException e) {
System.out.println("SAX "+e.getMessage());
}
catch (Exception e) {
System.out.println(""+e.getMessage());
}
}
/* //
public static void main (String args[])
{
boolean isValidating = false;
//....debug....................
159

String p = System.getProperty("javax.xml.parsers.SAXParserFactory");
System.out.println("parser="+p);
//....................
try {
XML_Reader xr = new XML_Reader();
xr.startParse(args[0]);
}
catch (IOException e) {
System.err.println("IO Exception:"+e.getMessage());
}
catch (Exception e) {
System.err.println("Exception:"+e.toString());
}
}
*/
// Vector js Item
public Item getJs (int index) {
if (index < js.size()) {
// ...debug
System.out.println("Index:"+ new Integer(index).toString());
return (Item) js.elementAt(index);
}
else {
// ...debug
//System.out.println("Index > js no.");
}
return (Item) js.elementAt(index);
}
// Vector js
public int getJsSize() {
int ret;
if (js==null) {ret=-1;}
else {ret = js.size();}
return ret;
}
160

// SAX1
public void startElement (String name,
AttributeList atts) {
int i;
currentElementName = name;
if (currentElementName.equals ("PICTURE")) {
for (i = 0; i < atts.getLength(); i++) {
aname = atts.getName(i);
avalue = atts.getValue(i);
//... debug
System.out.println("PICTURE "+aname+":"+avalue);
if (aname.equals ("SOURCE")) {
picture = avalue;
}
}
}
}

// XML JOYSTICK Item


public void endElement (String name) {
if (name.equals ("JOYSTICK")) {
Item j = new Item(
jsname, company, Website,
io, button,hat,
throttle,rudder,programmable,
price, picture);
js.addElement(j);
//... debug
// System.out.println("new JS was built");
}
}
// XML
161

public void characters (char ch[], int start,


int length) {
String s = new String (ch, start, length);
if (s.trim().length() == 0)
return;
//.. debug
System.out.println("data:"+currentElementName+"("+s+")");
if (currentElementName.equals ("JSNAME"))
jsname = s;
else if (currentElementName.equals ("COMPANY"))
company = s;
else if (currentElementName.equals ("WEBSITE"))
Website = s;
else if (currentElementName.equals ("IO"))
io = s;
else if (currentElementName.equals ("BUTTON"))
button = s;
else if (currentElementName.equals ("HAT"))
hat = s;
else if (currentElementName.equals ("THROTTLE"))
throttle = s;
else if (currentElementName.equals ("RUDDER"))
rudder = s;
else if (currentElementName.equals ("PROGRAMMABLE"))
programmable = s;
else if (currentElementName.equals ("PRICE"))
price = s;
}
/*
public void endDocument () {
}
*/
}

ShowItem
import java.io.*;
import java.lang.*;
// import java.net.*;
import java.util.*;
import org.xml.sax.Parser;
162

import org.xml.sax.AttributeList;
import org.xml.sax.InputSource;
import org.xml.sax.HandlerBase;
import org.xml.sax.SAXException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import javax.xml.parsers.FactoryConfigurationError;
import javax.xml.parsers.ParserConfigurationException;
import javax.servlet.*;
import javax.servlet.http.*;
// Products FORM jsselect Servlet
public class ShowItem extends HttpServlet {
//
private Item curJS;
// XML_Reader XML
private XML_Reader xr = XML_Reader.getXr();
public void doPost(HttpServletRequest request,
HttpServletResponse response)
throws IOException, ServletException
{
doGet(request, response);
}
public void doGet(HttpServletRequest request,
HttpServletResponse response)
throws IOException, ServletException
{
// HTML
response.setContentType("text/html;charset=Big5");
PrintWriter out = response.getWriter();
// Servlet Products
int jsNo = (new Integer(request.getParameter("jsselect"))).intValue();
out.println("<html>");
out.println("<body>");
out.println("<head>");
out.println("<title> V1.0</title>");
out.println("</head>");
out.println("<body>");
163

out.println("<DIV align='center'>");
out.println("<h1></h1>");

out.println("<TABLE BORDER CELLPADDING='8' CELLSPACING='4' BGCOLOR=white>");


// XML_Reader Item
curJS = xr.getJs(jsNo);
out.println("<TR><TD>");
out.println(": ");
out.println(curJS.getCompany());
out.println("<br>");
out.println(": "+
curJS.getWebsite()+"<br>");
out.println(": "+
curJS.getIo()+"<br>");
out.println(": "+
curJS.getPrice()+"<br>");
out.println(": "+
curJS.getButton()+"<br>");
out.println(":"+
curJS.getHat()+"<br>");
out.println(":"+
curJS.getThrottle()+"<br>");
out.println (": "+
curJS.getRudder()+"<br>");
out.println (":"+
curJS.getProgrammable()+"<br>");
out.println("</TD><TD>");
out.println("<IMG SRC="+curJS.getPicture()+">");
out.println("</TD><TR>");
out.println("</TABLE>");
out.println("</DIV>");
out.println("</body>");
out.println("</html>");
164

}
}

Classpath
sax.jarSAX1
jaxp.jarSun JAXP
parser.jarSun SAX
servlet.jarSun JSDK JSWDK Servlet

1. Tomcat
2. Tomcat \Jakarta-tomcat

3. *.class products\WEB-INF\classes Joystick.xml products\xml


*.gif *.jpg products\images
4. conf\Web.xml
5. <servlet>
6.

<servlet-name>

7.

products

8.

</servlet-name>

9.

<servlet-class>

10.

Products

11.

</servlet-class>

12.

<init-param>

13.

<param-name>xmldoc</param-name>

14.

<param-value>http://localhost:8080/products/xml/Joystick.xml

15.

</param-value>

16.

</init-param>
</servlet>
165

17. Tomcat startup.bat Classpath jaxp.jarsax.jar parser.jar


set classpath=e:\xml\jaxp.jar;e:\xml\sax.jar;e:\xml\parser.jar;%classpath%

Tomcat

http://localhost:8080/products/servlet/products
products Webapps Web application products
conf\Web.xml servlet-name

Java Server PagesJSP XML


JSP Java Java Servlet
JSP 1999 6 JSP JSP 1.1JSP Java Servlet API
HTMLJava
JSP Scripting languageJSP
JSP JSP JSP JSP Java Servlet
ServletJSP Java ServletJSP Java
JSP JSP Java Servlet
Java BeansJSP Custom Tags JSP JSP
Java Beans Custom Tags JSP
166

Scriptlet Java Beans Custom Tags JSP

JSP1.1 JSP JSP Servlet JSP


application server
JSPServletJava Beans deploy
JSP XML

JSP XML JSP Java


Beans XML Java Beans
XML

JDK
Jakarta Tomcat Apache group JSPServlet
Tomcat
JSDK JSWDK Servlet servlet.jar
Tomcat servlet.jar Tomcat JSWDK
JSP Web Server
XML Apache Xerces SAX XML xerces.jar
XML JDOM jdom.jar

XML
XML catalog.xml
<?xml version="1.0" ?>
<PRODUCTS>
<ITEM>
<NAME>Saitek X36 Flight Controller</NAME>
<ID>SAITEK-X36</ID>
<COMPANY> Saitek </COMPANY>
<WEBSITE>http://www.saitek.com/</WEBSITE>
<IO>USB</IO>
<PROGAMMABLE>Yes</PROGAMMABLE>
<BUTTON>7</BUTTON>
<HAT>3</HAT>
<THROTTLE>Yes</THROTTLE>
<RUDDER>Yes</RUDDER>
<PRICE>3200</PRICE>
167

<PICTURE SOURCE="Saitek_X36.gif"/>
</ITEM>
<ITEM>
<NAME>F-16 CombatStick(R) USB</NAME>
<ID>CH-F16-CS-USB</ID>
<COMPANY>CH Products</COMPANY>
<WEBSITE>http://www.chproducts.com</WEBSITE>
<IO>USB</IO>
<PROGAMMABLE>Yes</PROGAMMABLE>
<BUTTON>6</BUTTON>
<HAT>2</HAT>
<THROTTLE>Yes</THROTTLE>
<RUDDER>No</RUDDER>
<PRICE>2600</PRICE>
<PICTURE SOURCE="CH_F16CS2000.gif"/>
</ITEM>
<ITEM>
<NAME>SFS Flight Controller USB</NAME>
<ID>SFS-FC-USB</ID>
<COMPANY>Suncom Inc.</COMPANY>
<WEBSITE>http://www.suncominc.com</WEBSITE>
<IO>USB</IO>
<PROGAMMABLE>Yes</PROGAMMABLE>
<BUTTON>5</BUTTON>
<HAT>1</HAT>
<THROTTLE>No</THROTTLE>
<RUDDER>No</RUDDER>
<PRICE>3100</PRICE>
<PICTURE

SOURCE="Suncom_SFSFC_USB.jpg"/>

</ITEM>
</PRODUCTS>
Saitek_X36.gifCH_F16CS2000.gif Suncom_SFSFC_ USB.jpg

Item
XML_Reader XML Item Item
Vector
CatalogBean XML_Reader XML Item
CartBean Item
168

JSP
catalog.jsp XML

cart.jsp
checkout.jsp

catalog.jsp catalog.jsp CatalogBean


CatalogBean XML_Reader XML_Reader method startParse() XML
Item XML_Reader Vector
catalog.jsp
cart.jsp
cart.jsp CartBean CartBean
checkout.jsp
checkout.jsp CartBean XML

Item
SAX XML Item
Item.java
package cart;
public class Item {
// ,,,,
String itemname, id, picture, price, qty;
public Item (String itemname,
String id,
String picture,
String price,
String qty )
{
this.itemname = itemname;
169

this.id = id;
this.picture = picture;
this.price = price;
this.qty = qty;
}
public String getItemname() { return itemname; }
public String getId() { return id; }
public String getPicture() {return picture; }
public String getPrice() {return price; }
public String getQty() {return qty; }
public void setQty(String s) {this.qty = s; }
}

XML_Reader
XML Java XML standard extension for XML
JAXPJava API for XML parsing javax.xml.parsers.SAXParser
XML JAXP SAX version 1 XML_Reader SAX1 HandlerBase
JAXP 1.1 SAX 2
package cart;
import java.io.*;
import java.lang.*;
import org.xml.sax.Parser;
import org.xml.sax.AttributeList;
import org.xml.sax.InputSource;
import org.xml.sax.HandlerBase;
import org.xml.sax.SAXException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import javax.xml.parsers.FactoryConfigurationError;
import javax.xml.parsers.ParserConfigurationException;
import java.util.*;
// SAX version 1 HandlerBase
public class XML_Reader extends HandlerBase
{
// Item Vector
private Vector items;
// SAX
private String currentElementName;
//
private String itemname,id;
170

private String price;


private String picture;
private String aname;
private String avalue;
public

XML_Reader() {
items = new Vector();

}
//-------------------------------------------// XML method
public void startParse(InputStreamReader isr)
throws IOException {
if (getCatalogSize() == 0)
startParse(new InputSource( isr ));
}
// XML startParse method
public void startParse(InputStream is)
throws IOException {
startParse(new InputStreamReader(is, "Big5"));
}
public void startParse(FileReader fr)
throws IOException {
startParse(new InputSource( fr ));
}
public void startParse(String filename)
throws IOException {
startParse(new FileReader(filename) );
}

// startParse method method


public void startParse(InputSource in) {
boolean isValidating = false;
171

try {
// JAXP PnP SAX
SAXParserFactory factory =
SAXParserFactory.newInstance();
SAXParser

parser = factory.newSAXParser();

factory.setValidating(isValidating);
factory.setNamespaceAware(false);
parser.parse(in, this);
}
catch (SAXException e) {
System.out.println("SAX "+e.getMessage());
}
catch (Exception e) {
System.out.println(""+e.getMessage());
}
}
/*
// for debug.....
public static void main (String args[])
{
boolean isValidating = false;
//....debug....................
String p = System.getProperty("javax.xml.parsers.SAXParserFactory");
System.out.println("parser="+p);
//....................
try {
XML_Reader xr = new XML_Reader();
xr.startParse(args[0]);
}
catch (IOException e) {
System.err.println("IO Exception:"+e.getMessage());
}
catch (Exception e) {
System.err.println("Exception:"+e.toString());
}
}
*/
172

// Vector item Item


public Item getItem (int index) {
if (index < items.size()) {
// ...debug
System.out.println("Index:"+ new Integer(index).toString());
return (Item) items.elementAt(index);
}
else {
// ...debug
//System.out.println("Index > js no.");
}
return (Item) items.elementAt(index);
}
// Vector items ,
public int getCatalogSize() {
int ret;
if (items==null) {ret=-1;}
else {ret = items.size();}
return ret;
}
// SAX ....
public void startElement (String name,
AttributeList atts) {
int i;
currentElementName = name;
if (currentElementName.equals ("PICTURE")) {
for (i = 0; i < atts.getLength(); i++) {
aname = atts.getName(i);
avalue = atts.getValue(i);
//... debug
System.out.println("PICTURE "+aname+":"+avalue);

if (aname.equals ("SOURCE")) {
picture = avalue;
173

}
}
}
}

// XML ITEM Item


public void endElement (String name) {
if (name.equals ("ITEM")) {
Item item = new Item(
itemname, id, picture,
price, "0");
items.addElement(item);
//... debug
// System.out.println("new JS was built");
}
}
// XML
public void characters (char ch[], int start,
int length) {
String s = new String (ch, start, length);
if (s.trim().length() == 0)
return;
//.. debug
System.out.println("data:"+currentElementName+"("+s+")");
if (currentElementName.equals ("NAME"))
itemname = s;
else if (currentElementName.equals ("ID"))
id = s;
else if (currentElementName.equals ("PRICE"))
price = s;
}
}
174

CatalogBean
catalog.jsp JavaBean Bean Bean
XML_Reader
package cart;
import java.util.Hashtable;
import java.util.Enumeration;
import java.io.*;
import java.net.*;
import javax.servlet.*;
import javax.servlet.http.*;
public class CatalogBean {
//
Hashtable params=new Hashtable();
// XML_Reader
XML_Reader xr = new XML_Reader();
// jsp xmldoc default_xmldoc XML
String xmldoc="";
String default_xmldoc =
"http://localhost:8080/cart/xml/catalog.xml";

// constructor
public CatalogBean() { System.out.println("start CartBean."); }
// JSP xmldoc method
public void setXmldoc(String s) { xmldoc = s; }
public String getXmldoc() { return xmldoc; }
// XML
public void startParse() {
if (xmldoc.equals(""))
xmldoc = default_xmldoc;
System.out.println("xmldoc="+xmldoc);
try {
//.... use URL
URL xmlURL = new URL (xmldoc);
xr.startParse(xmlURL.openStream());
175

} catch (MalformedURLException e) {
System.err.println("MalformedURL Exception:"+
e.getMessage());
} catch (IOException e) {
System.out.println(e.toString());
}
}
// , Hashtable
public void processRequest(HttpServletRequest req) {
Enumeration en = req.getParameterNames();
while (en.hasMoreElements()) {
String varName = (String)en.nextElement();
String[] varValues =
req.getParameterValues(varName);
if (varValues.length > 1) {
params.put(varName, varValues);
}
else {
params.put(varName, varValues[0]);
System.out.println("req:"+varName+
"="+varValues[0]);
}
}
}
// Hashtable
public String getParam(String key) {
return (String)params.get(key);
}
// Hashtable
public void setParam(String key, String value) {
if (params.containsKey(key))
params.put(key, value);
else
System.out.println("no such key:"+
key+" in param Hashtable");
}
176

// Hashtable
public String[] getParamArr(String key) {
return (String[])params.get(key);
}
//
public int getCatalogSize() {
return xr.getCatalogSize();
}
//
public Item getItem(int i) {
return xr.getItem(i);
}
}

CartBean

package cart;
import java.util.Hashtable;
import java.util.Enumeration;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.JDOMException;
import org.jdom.input.SAXBuilder;
import org.jdom.output.XMLOutputter;
import java.io.*;
import java.net.*;
import javax.servlet.*;
import javax.servlet.http.*;
public class CartBean {
Hashtable params=new Hashtable();
Hashtable items=new Hashtable();
private static final String DEFAULT_SAX_DRIVER_CLASS =
"org.apache.xerces.parsers.SAXParser";
private String saxDriverClass;
private SAXBuilder builder;
private Document doc;
private Element root;
//
177

private String xmldoc = "/xml/order.xml";


public CartBean() { System.out.println("start CartBean."); }
/*

// for debug
public static void main(String args[]) {
CatalogBean catalog = new CatalogBean();
CartBean cart = new CartBean();
catalog.startParse();

cart.addItem( catalog.getItem(1) );
cart.addItem( catalog.getItem(2) );
cart.toXML();
}
*/
//
public void processRequest(HttpServletRequest req) {
Enumeration en = req.getParameterNames();
while (en.hasMoreElements()) {
String varName = (String)en.nextElement();
String[] varValues = req.getParameterValues(varName);
if (varValues.length > 1) {
params.put(varName, varValues);
}
else {
params.put(varName, varValues[0]);
System.out.println("req:"+varName+"="+varValues[0]);
}
}
}
public String getParam(String key) {
return (String)params.get(key);
}
178

public void setParam(String key, String value) {


if (params.containsKey(key))
params.put(key, value);
else
System.out.println("no such key:"+key+" in param Hashtable");
}
public String[] getParamArr(String key) {
return (String[])params.get(key);
}
//
public void addItem(Item item) {
items.put(item.getId(),item);
System.out.println("item:"+item.getItemname());
}
//
public Hashtable getItems() {
return items;
}

// save XML data to file


public void close()
throws IOException, JDOMException {
doc.setRootElement(root);
startOutputXML(new FileOutputStream(xmldoc));
}
private void startOutputXML(OutputStream out)
throws IOException, JDOMException {
// Create an outputter with default formatting
XMLOutputter outputter = getXMLOutputter();
outputter.output(doc, out);
}
private XMLOutputter getXMLOutputter()
throws IOException, JDOMException {
179

// Create an outputter with certain encoding


XMLOutputter outputter = new XMLOutputter(" ", true, "Big5");
outputter.setTrimText(true);
outputter.setExpandEmptyElements(true);
return outputter;
}

// XML
private void addToXML(Item item) {
// add one element to XML file
Element curItem = new Element("item");
Element curItemname = new Element("itemname");
curItemname.addContent(item.getItemname());
Element curId = new Element("id");
curId.addContent(item.getId());
Element curQty = new Element("qty");
curQty.addContent(item.getQty());
curItem.addContent(curItemname);
curItem.addContent(curId);
curItem.addContent(curQty);
root.addContent(curItem);
}
// XML
public void toXML() {
this.saxDriverClass = DEFAULT_SAX_DRIVER_CLASS;
builder = new SAXBuilder(saxDriverClass);
Enumeration itemlist = items.elements();
Item item;
//System.out.println("new root");
180

// build new XML doc


root = new Element("order");
doc = new Document(root);
//System.out.println("add elements to root");
while (itemlist.hasMoreElements() ) {
item = (Item)itemlist.nextElement();
System.out.println("add one item: "+item.getItemname());
// save to XML file
addToXML(item);
}
//System.out.println("add ok!");
try {
// XML
close();
} catch (JDOMException e) {
System.out.println(e.toString());
} catch (IOException e) {
System.out.println(e.toString());
}
}
}

catalog.jsp
XML
<HTML>
<HEAD><TITLE>Growbal's SimFan </TITLE>
</HEAD>
<BODY bgcolor="black">
<table WIDTH="100%" COLS="1">
<tr bgcolor="red"><td valign="buttom" align="center">
<font size="3" color="white">Growbal's SimFan </font><br>
<font size="6" color="white"></font>
</td></tr><table>
HTML
<%@ page language="java" import="java.util.*,cart.*" %>
<jsp:useBean id="catalogbean" class="cart.CatalogBean"
181

scope="session" />
<jsp:setProperty name="catalogbean" property="xmldoc"
value="http://localhost:8080/cart/xml/catalog.xml"/>
JSP JavaBean
JSP Java packages
cart.CatalogBean catalogbean session
<jsp:useBean....../> JavaBean id="..."class="..."

scope pagerequestsessionapplication JavaBean


scope="page" JavaBean JavaBean
scope="request" JavaBean HTTP request
redirect JavaBean JSP forward

scope="session" JavaBean session session


session JSP JavaBean
scope
scope="application" JavaBean JSP Server
JavaBean
JavaBean JavaBean
JavaBean
catalogbean xmldoc "http://localhost:8080/cart/xml/catalog.xml"
<jsp:setProperty....../> JavaBean property name="..." JavaBean
property="..."value="..."
xmldoc JavaBean setXmldoc() method JavaBean
inspection
<% catalogbean.startParse(); %>
<%%> JSP scriptlet Java
catalogbean method startParse() XML
<%-- =catalogbean.getXmldoc() --%>
<%
session.setAttribute("catalogb", catalogbean);
%>
<%----%> JSP
session.setAttribute("catalogb", catalogbean)session JSP
session
session.setAttribute catalogbean catalogb session
<form name=catalogForm method="POST" action="cart.jsp">
<table width="100%">
<tr bgcolor="rosybrown">
<td></td><td></td><td></td><td></td>
182

</tr>
<%!
int catalogSize;
int i;
Item item;String curColor, color1, color2;
%>
<%
color1 = "silver";
color2 = "lightsteelblue";
curColor = color1;
catalogSize = catalogbean.getCatalogSize();
for (i=0; i<catalogSize; i++) {
item = catalogbean.getItem(i);
if (item!=null) {
%>
<tr bgcolor=<%=curColor%>>
<td align="center"><%=item.getItemname()%></td>
<td><IMG SRC=/examples/images/<%=item.getPicture()%> ></td>
<td><%=item.getPrice()%></td>
<td><input type='TEXT' name=qty_<%=i%> size=5 ></td>
</tr>
<%
if (curColor.equals(color1)) curColor = color2;
else if (curColor.equals(color2)) curColor = color1;
}
else {
%>
ERROR: get NULL item!!!<br>
<%
}
}
%>
<tr bgcolor="lightgrey">
<td></td><td></td><td></td>
<td><input type="submit"

name="submit" value="">

</td>
</tr>
</table>
</form>
</body>
183

</html>
FORM
catalogbean.getCatalogSize() catalogbean.getItem(i)
itemItem item.getItemname()item.getPicture()item.getPrice()
HTML FORM

cart.jsp
catalog.jsp FORM
cart.jsp
<html><head><TITLE>Growbal's SimFan </TITLE>
</head>
<body bgcolor="gray">

<%@ page language="java" session="true" import="java.util.*,cart.*" %>


<jsp:useBean id="cartbean" class="cart.CartBean" scope="session" />
catalog.jsp cart.jsp cart.CartBean cartbean scope session
<%!
CatalogBean catalogbean;
%>
<%
if (session.getValue("catalogb") == null)
response.sendRedirect("catalog.jsp");
else
catalogbean = (CatalogBean)session.getValue("catalogb");
cartbean.processRequest(request);
%>
session catalogb cart.CatalogBean
catalog.jsp catalog.jsp
catalogbean catalog.jsp cart.jsp gty-1
gty-2 gty-3 cartbean
<table WIDTH="100%" COLS="1">
<tr bgcolor="red"><td valign="buttom" align="center">
<font size="3" color="white">Growbal's SimFan </font><br>
<font size="6" color="white">

</font>
</td></tr></table>
<hr>
<form name=cartForm method="POST" action="checkout.jsp">
<table width="100%" >
<tr bgcolor="white">
184

<td></td><td></td><td></td><td></td>
</tr>
<%!
int i;
int curQty;
Item item;
int sum;
int curPrice;
String qty;
int catalogSize;
String curColor, color1, color2;
%>
<%
color1 = "lightblue";
color2 = "thistle";
curColor = color1;
catalogSize = catalogbean.getCatalogSize();
sum=0;
if (catalogSize == 0) {
%>
Error: No item in catalog?!<br>
<%
}
for (i=0; i<catalogSize; i++) {
qty = cartbean.getParam("qty_"+new Integer(i).toString() );
if (qty==null || qty.equals("")) qty = "0";
curQty = new Integer(qty).intValue();
if ( curQty > 0 ) {
item= catalogbean.getItem(i);
item.setQty(qty);

// String

cartbean.addItem(item);
curPrice = new Integer(
item.getPrice()).intValue();
sum += curQty * curPrice;
%>
<tr bgcolor=<%=curColor%>>
<td align="center"><%=item.getItemname()%></td>
<td><IMG SRC=/examples/images/<%=item.getPicture()%>></td>
185

<td><%=curPrice%></td>
<td><%=curQty%></td>
</tr>
<%
if (curColor.equals(color1)) curColor = color2;
else if (curColor.equals(color2)) curColor = color1;
}
}
session.setAttribute("cartb", cartbean);
%>
<tr bgcolor="white">
<td></td>
<td></td>
<td> : <%=sum%></td>
<td><input type="submit" name="submit" value=""></td>
</tr>
</table>
</form>
</body>
</html>
cartbean session
checkout.jsp

checkout.jsp
<html>
<%@ page language="java" session="true" import="java.util.*,cart.*" %>
<BODY bgcolor="lightgrey">
<table WIDTH="100%" COLS="1">
<tr bgcolor="red"><td valign="buttom" align="center">
<font size="3" color="white">Growbal's SimFan </font><br>
<font size="6" color="white"></font>
</td></tr><table>
<%!
CartBean cartbean;
%>
<%
if (session.getValue("cartb") == null)
response.sendRedirect("catalog.jsp");
else {
cartbean = (CartBean)session.getValue("cartb");
186

cartbean.toXML();
}
%>
<hr>
<table width="100%"><tr><td align="center"><font color="BLACK" size="4">
!
</font>
</td></tr>
</table>
</body>
</html>
session cartbean cartbean.toXML() XML
Server /xml/order.xml CartBean

Classpath
sax2.jarSAX2
xerces.jarApache Xerces
jdom.jarJDOM
servlet.jarSun JSDK JSWDK Servlet
Java e:\dev\jsp\cart
cd \dev\jsp
javac cart\Item.java
cart Package cart.Item
CatalogBeanXML_Reader.javaCartBean

1. Tomcat
2. Tomcat \Jakarta-tomcat

3. JSP cart\jsp cart\WEB-INF\classes\cart Joystick.xml


187

cart\xml cart\images
4. conf/server.xml
5. <Context path="/cart" docBase="Webapps/cart" debug="0"
reloadable="true" > </Context>
6. Tomcat startup.bat Classpathxerces.jarsax2.jar jdom.jar
7. \xml order.xml

Tomcat

http://localhost:8080/cart/jsp/catalog.jsp

188

XML order.xml/xml/
<?xml version="1.0" encoding="Big5"?>
<order>
<item>
<itemname>F-16 CombatStick(R) USB</itemname>
<id>CH-F16-CS-USB</id>
<qty>2</qty>
</item>
<item>
<itemname>Saitek X36 Flight Controller</itemname>
<id>SAITEK-X36</id>
<qty>1</qty>
</item>
</order>

4.4 XSLT XPath


XSLT XPath James Clark's xt
James Clark's xt XSLTXSL Transformations Java 19991105
W3C XSLT PR-xslt-19991008
xt ftp://ftp.jclark.com/pub/xml/xt.zip SAX Java
XML parserJames Clark Java XML parser xp
http://www.jclark.com/xml/xp/index.html

xt
xt
java -Dcom.jclark.xsl.sax.parser=your-sax-driver com.jclark.xsl.sax.Driver
source stylesheet result name=value...

189

name=value xsl stylesheet xsl:param

System propertycom.jclark.xsl.sax.parser xt SAX


org.xml.sax.parser SAX
com.jclark.xml.sax.CommentDriver SAX xp SAX

XML XSL
XML XSL XMlXSL HTML
stockquote.xml
<?xml version="1.0" encoding="Big5"?>
<?xml-stylesheet type="text/xml" href="stockquote.xsl"?>
<stockquote>
<stock>
<name></name>
<code>2303</code>
<last_close>52</last_close>
<open>51</open>
<close>50.50</close>
<change>-1.5</change>
<bid>50.5</bid>
<ask>51.0</ask>
<volume>31963</volume>
</stock>
<stock>
<name></name>
<code>2330</code>
<last_close>90</last_close>
<open>89.5</open>
<close>88.0</close>
<change>-2</change>
<bid>88.5</bid>
<ask>88.0</ask>
<volume>13308</volume>
</stock>
<stock>
<name></name>
<code>2388</code>
<last_close>214</last_close>
<open>208</open>
<close>207</close>
190

<change>-7</change>
<bid>0</bid>
<ask>207</ask>
<volume>6919</volume>
</stock>
<stock>
<name></name>
<code>2342</code>
<last_close>22.6</last_close>
<open>22.6</open>
<close>22.4</close>
<change>-0.2</change>
<bid>22.4</bid>
<ask>0</ask>
<volume>40812</volume>
</stock>
</stockquote>
stockquote.xsl
<?xml version="1.0" encoding="Big5"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<html>
<head>
<title></title>
</head>
<body>
<xsl:apply-templates select="stockquote"/>
</body>
</html>
</xsl:template>
<xsl:template match="stockquote">
<h1></h1>
<table>
<th></th>
<th></th>
<th></th>
<th></th>
<th></th>
<xsl:apply-templates select="stock"/>
191

</table>
</xsl:template>
<xsl:template match="stock">
<tr>
<td><xsl:value-of select="name"/></td>
<td><xsl:value-of select="code"/></td>
<td><xsl:value-of select="last_close"/></td>
<td><xsl:value-of select="open"/></td>
<td><xsl:value-of select="close"/></td>
</tr>
</xsl:template>
</xsl:stylesheet>

classpath xt1.bat
set ClassPath=.;c:\jdk1.2.2\lib\tools.jar;e:\xml\xt.jar;e:\xml\sax.
jar;e:\xml\parser.jar
java -Dcom.jclark.xsl.sax.parser=com.sun.xml.parser.Parser com.
jclark.xsl.sax.Driver %1.xml %1.xsl %1.html

Classpath
xt.jarClark XSLT
sax.jarSAX parser
parser.jarSun jaxp XML parser SAX

xt1 stockquote
HTML stockquote.html xt unicode
<html>
<head>
<title>& #21488;& #21271;& #32929;& #24066;& #36039;& #26009;</title>
</head>
<body>
<h1>& #21488;& #21271;& #32929;& #24066;& #36039;& #26009;</h1>
<table>
<th>& #20844;& #21496;</th><th>& #20195;& #30908;</th><th>& #26152;& #25910;
</th><th>& #38283;& #30436;</th><th>& #25910;& #30436;</th>
<tr>
<td>& #32879;& #38651;</td><td>2303</td><td>52</td><td>51</td><td>50.50</td>
</tr>
192

<tr>
<td>& #21488;& #31309;& #38651;</td><td>2330</td><td>90</td><td>89.5</td>
<td>88.0</td>
</tr>
<tr>
<td>& #23041;& #30427;</td><td>2388</td><td>214</td><td>208</td><td>207</td>
</tr>
<tr>
<td>& #33538;& #30717;</td><td>2342</td><td>22.6</td><td>22.6</td><td>22.4</td>
</tr>
</table>
</body>
</html>

Servlet xt

xt Servlet XSLServlet xt XSLT

XML XSL
jclark xt com.jclark.xsl.sax.XSLServlet Unicode XML XSL
Unicode stockquote-u.xml stockquote-u.xsl
stockquote-u.xml
<?xml version="1.0"?>
193

<stockquote>
<stock>
<name>& #32879;& #38651;</name>
<code>2303</code>
<last_close>52</last_close>
<open>51</open>
<close>50.50</close>
<change>-1.5</change>
<bid>50.5</bid>
<ask>51.0</ask>
<volume>31963</volume>
</stock>
<stock>
<name>& #21488;& #31309;& #38651;</name>
<code>2330</code>
<last_close>90</last_close>
<open>89.5</open>
<close>88.0</close>
<change>-2</change>
<bid>88.5</bid>
<ask>88.0</ask>
<volume>13308</volume>
</stock>
<stock>
<name>& #23041;& #30427;</name>
<code>2388</code>
<last_close>214</last_close>
<open>208</open>
<close>207</close>
<change>-7</change>
<bid>0</bid>
<ask>207</ask>
<volume>6919</volume>
</stock>
<stock>
<name>& #33538;& #30717;</name>
<code>2342</code>
<last_close>22.6</last_close>
<open>22.6</open>
<close>22.4</close>
194

<change>-0.2</change>
<bid>22.4</bid>
<ask>0</ask>
<volume>40812</volume>
</stock>
</stockquote>
stockquote-u.xsl
<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/
XSL/Transform">
<xsl:template match="/">
<html>
<head>
<title>& #21488;& #21271;& #32929;& #24066;& #36039;& #26009;</title>
</head>
<body>
<xsl:apply-templates select="stockquote"/>
</body>
</html>
</xsl:template>
<xsl:template match="stockquote">
<h1>& #21488;& #21271;& #32929;& #24066;& #36039;& #26009;</h1>
<table>
<th>& #20844;& #21496;</th>
<th>& #20195;& #30908;</th>
<th>& #26152;& #25910;</th>
<th>& #38283;& #30436;</th>
<th>& #25910;& #30436;</th>
<xsl:apply-templates select="stock"/>
</table>
</xsl:template>
<xsl:template match="stock">
<tr>
<td><xsl:value-of select="name"/></td>
<td><xsl:value-of select="code"/></td>
<td><xsl:value-of select="last_close"/></td>
<td><xsl:value-of select="open"/></td>
<td><xsl:value-of select="close"/></td>
195

</tr>
</xsl:template>
</xsl:stylesheet>
jakarta-tomcat tomcat
\Jakarta-tomcat\Webapps\ROOT xsl

Tomcat Web.xml
Tomcat conf/Web.xml
<servlet>
<servlet-name>
xslDemo
</servlet-name>
<servlet-class>
com.jclark.xsl.sax.XSLServlet
</servlet-class>
<init-param>
<param-name>stylesheet</param-name>
<param-value>/xsl/stockquote-u.xsl</param-value>
</init-param>
</servlet>

<servlet-mapping>
<servlet-name>
xslDemo
</servlet-name>
<url-pattern>
/xslDemoServlet/*
</url-pattern>
</servlet-mapping>
<url-pattern>/xslDemoServlet/* URL
<strvlet-name> xslDemo <servlet-class> xslDemo
com.jclark.xsl.sax.XSLServlet
Clark xt servlet init parameterstylesheet

<init-param>
<param-name>stylesheet</param-name>
<param-value>/xsl/stockquote-u.xsl</param-value>
</init-param>

Tomcat Classpath xt.jarsax.jarxp.jar


Tomcat
196


http://localhost:8080/xslDemoServlet/xsl/stockquote-u

xt Servlet Big5
XML XSL xt Big5
Unicode entity

James Clarkjclark xt

JDK java.io InputStreamReaderbyte stream


character stream InputStreamReader
InputStreamReader
InputStreamReader isr = new InputStreamReader(is,"Big5");
InputStreamReader() is InputSream ByteArrayInputStream
FileInputStreamFilterInputStreamInputStream, ObjectInputStreamPipedInputStream
SequenceInputStream StringBufferInputStream
UnsupportedEncodingException

XSLServlet Big5XSLServlet
XSLServlet xt XSLServlet xt com\jclark\xsl\sax
XML XSL
197

String stylesheet = getInitParameter("stylesheet");


......
cached.loadStylesheet(new
InputSource(getServletContext().getResource(stylesheet).toString()));
XSL XSL InitParameterstylesheet
javax.servlet.GenericServlet method get ServletContext() ServletContext method
getResource() stylesheet URL URL InputSource
SAX InputSource
XML
File inputFile = new File(request.getPathTranslated());
......
xsl.parse(fileInputSource(inputFile));
request URL XML File inputFile File
fileInputSource()fileInputSource() XSLServlet method File XML
InputSourceorg.xml.sax.InputSource xslXSLProcessor parser method

static public InputSource fileInputSource(File file) {


String path = file.getAbsolutePath();
String fSep = System.getProperty("file.separator");
if (fSep != null && fSep.length() == 1)
path = path.replace(fSep.charAt(0), '/');
if (path.length() > 0 && path.charAt(0) != '/')
path = '/' + path;
try {
return new InputSource(new URL("file", "", path).toString());
}
catch (java.net.MalformedURLException e) {
/* According to the spec this could only happen if the file
protocol were not recognized. */
throw new Error("unexpected MalformedURLException");
}
}
XSL

cached.loadStylesheet(new
InputSource(getServletContext().getResource(stylesheet).toString()));

InputStream is =
getServletContext().getResourceAsStream(stylesheet);
cached.loadStylesheet(new InputSource(
198

new InputStreamReader(is, "Big5")

));

XSL InputSream
ServletContext method getResourceAsStream() InputSreamReader InputSream
Big5 InputSreamReader InputSource
XSL InputSource
XML mothod fileInputSource()
return new InputSource(new URL("file", "", path).toString());

FileInputStream fis = new FileInputStream(file);


InputStreamReader isr = new InputStreamReader(fis,"Big5");
return new InputSource(isr);
XSL
Big5XSLServlet.java
import java.io.IOException;
import java.io.File;
import java.io.Writer;
import java.io.InputStreamReader;
import java.io.InputStream;
import java.io.FileInputStream;
//import java.net.*;
import java.util.Enumeration;
import javax.servlet.*;
import javax.servlet.http.*;
import org.xml.sax.*;
import com.jclark.xsl.sax.*;
/*
read local xsl and xml files, in vitual path format
call by http://localhost:8080/stockquote/xsl/stockquote
v-path
xml-file
v-path should set in Web.xml
real-path should makedir under app's doc root dir,
such as /jakarta-tomcat/Webapps/ROOT/xsl
don't forget put this class in CLASSPATH before startup TOMCAT
*/
public class Big5XSLServlet extends HttpServlet {
private XSLProcessor cached;
public void init() throws ServletException {
String stylesheet = getInitParameter("stylesheet");
199

real-path

if (stylesheet == null)
throw new ServletException("missing stylesheet parameter");
cached = new XSLProcessorImpl();
cached.setParser(createParser());
try {
// modified
InputStream is = getServletContext().getResourceAsStream(stylesheet);
cached.loadStylesheet(new InputSource(
new InputStreamReader(is, "Big5")

));

}
catch (SAXException e) {
throw new ServletException(e);
}
catch (IOException e) {
throw new ServletException(e);
}
}
public void doGet (HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
File inputFile = new File(request.getPathTranslated());
if (!inputFile.isFile()) {
inputFile = new File(request.getPathTranslated() + ".xml");
if (!inputFile.isFile()) {
response.sendError(HttpServletResponse.SC_NOT_FOUND,
"File not found: " + request.getPathTranslated());
return;
}
}

XSLProcessor xsl = (XSLProcessor)cached.clone();


xsl.setParser(createParser());
for (Enumeration e =
request.getParameterNames(); e.hasMoreElements();) {
String name = (String)e.nextElement();
// What to do about multiple values?
xsl.setParameter(name, request.getParameter(name));
200

}
OutputMethodHandlerImpl outputMethodHandler =
new OutputMethodHandlerImpl(xsl);
xsl.setOutputMethodHandler(outputMethodHandler);
outputMethodHandler.setDestination(new
ServletDestination(response));
try {
xsl.parse(fileInputSource(inputFile));
}
catch (SAXException e) {
throw new ServletException(e);
}
}
static Parser createParser() throws ServletException {
String parserClass =
System.getProperty("com.jclark.xsl.sax.parser");
if (parserClass == null)
parserClass = System.getProperty("org.xml.sax.parser");
if (parserClass == null)
parserClass = "com.jclark.xml.sax.CommentDriver";
try {
return (Parser)Class.forName(parserClass).newInstance();
}
catch (ClassNotFoundException e) {
throw new ServletException(e);
}
catch (InstantiationException e) {
throw new ServletException(e);
}
catch (IllegalAccessException e) {
throw new ServletException(e);
}
catch (ClassCastException e) {
throw new ServletException(parserClass +
" is not a SAX driver");
}
}
/**
* Generates an <code>InputSource</code> from a file name.
201

*/
static public InputSource fileInputSource(File file) {
String path = file.getAbsolutePath();
String fSep = System.getProperty("file.separator");
if (fSep != null && fSep.length() == 1)
path = path.replace(fSep.charAt(0), '/');
if (path.length() > 0 && path.charAt(0) != '/')
path = '/' + path;
try {
// modified
FileInputStream fis = new FileInputStream(file);
InputStreamReader isr = new InputStreamReader(fis,"Big5");
return new InputSurce(isr);
// original
// return new InputSource(new URL("file", "", path).toString());
}
// original...
//catch (java.net.MalformedURLException e) {
// modified...
catch (Exception e) {
/* According to the spec this could only happen if the file
protocol were not recognized. */
// modified...
// throw new Error("unexpected MalformedURLException");
throw new Error(e.toString());
}
}
}

classpath xt.jarsax.jarxp.jar SAX1 parser.jar servlet.jar


javac Big5XSLServlet.java

TOMCAT CLASSPATH TOMCAT_HOME\ classes


Big5XSLServlet.class
XML XSL TOMCAT
\Jakarta-tomcat\Webapps\ROOT\ xsl stockquote.xsl
stockquote.xml

Tomcat Web.xml
TOMCAT conf\Web.xml Servlet
<servlet>
202

<servlet-name>
stockquote
</servlet-name>
<servlet-class>
Big5XSLServlet
</servlet-class>
<init-param>
<param-name>stylesheet</param-name>
<param-value>/xsl/stockquote.xsl</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>
stockquote
</servlet-name>
<url-pattern>
/stockquote/*
</url-pattern>
</servlet-mapping>

Tomcat
Tomcat http://localhost:8080/stockquote/xsl/stockquote
HTML Microsoft Internet Explorer 5
Unicode

XSLServlet i18n
XSL XML xt

xt Servlet XSL XML


XSLServlet Big5XSLServlet XML XSL Tomcat server
XML XSL

Big5URLXSLServlet
XML XSL XML XSL
URL XML XSL
XML XSL URL methodxslSource
xmlSource URL XSL XML InputSource

String stylesheet;
String xmldoc;
...
203

stylesheet = getInitParameter("stylesheet");
xmldoc = getInitParameter("xmldoc");
public InputSource xslSource(String xsldoc) {
System.out.println("XSL source:"+xsldoc);
try {
URL xslURL = new URL (xsldoc);
return
new InputSource(
new InputStreamReader(xslURL.openStream(), "Big5") );
} catch (MalformedURLException e) {
System.err.println("MalformedURL Exception:"+
e.getMessage());
} catch (Exception e) {
System.err.println("Exception:"+e.toString());
}
return null;
}
public InputSource xmlSource(String xmldoc) {
System.out.println("XML source:"+xmldoc);
try {
URL xmlURL = new URL (xmldoc);
return
new InputSource(
new InputStreamReader(xmlURL.openStream(), "Big5") );
} catch (MalformedURLException e) {
System.err.println("MalformedURL Exception:"+
e.getMessage());
} catch (Exception e) {
System.err.println("Exception:"+e.toString());
}
return null;
}
Big5URLXSLServlet.java
204

import java.io.IOException;
import java.io.File;
import java.io.Writer;
import java.io.InputStreamReader;
import java.io.InputStream;
import java.net.URL;
import java.net.MalformedURLException;
import java.util.Enumeration;
import javax.servlet.*;
import javax.servlet.http.*;
import org.xml.sax.*;
import com.jclark.xsl.sax.*;
public class Big5URLXSLServlet extends HttpServlet {
private XSLProcessor cached;
private String stylesheet;
private String xmldoc;
public InputSource xslSource(String xsldoc) {
System.out.println("XSL source:"+xsldoc);
try {
URL xslURL = new URL (xsldoc);
return
new InputSource(
new InputStreamReader(xslURL.openStream(), "Big5") );
} catch (MalformedURLException e) {
System.err.println("MalformedURL Exception:"+
e.getMessage());
} catch (Exception e) {
System.err.println("Exception:"+e.toString());
}
return null;
}
public InputSource xmlSource(String xmldoc) {
System.out.println("XML source:"+xmldoc);
try {
URL xmlURL = new URL (xmldoc);
return
205

new InputSource(
new InputStreamReader(xmlURL.openStream(), "Big5") );
} catch (MalformedURLException e) {
System.err.println("MalformedURL Exception:"+
e.getMessage());
} catch (Exception e) {
System.err.println("Exception:"+e.toString());
}
return null;
}
public void init() throws ServletException {
stylesheet = getInitParameter("stylesheet");
xmldoc = getInitParameter("xmldoc");
if (stylesheet == null)
throw new ServletException("missing stylesheet parameter");
if (xmldoc == null)
throw new ServletException("missing xmldoc parameter");
cached = new XSLProcessorImpl();
cached.setParser(createParser());
try {
// modified
cached.loadStylesheet(xslSource(stylesheet));
}
catch (SAXException e) {
throw new ServletException(e);
}
catch (IOException e) {
throw new ServletException(e);
}
}
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
XSLProcessor xsl = (XSLProcessor)cached.clone();
xsl.setParser(createParser());
for (Enumeration e = request.getParameterNames();
e.hasMoreElements();) {
206

String name = (String)e.nextElement();


// What to do about multiple values?
xsl.setParameter(name, request.getParameter(name));
}
OutputMethodHandlerImpl outputMethodHandler =
new OutputMethodHandlerImpl(xsl);
xsl.setOutputMethodHandler(outputMethodHandler);
outputMethodHandler.setDestination(new
ServletDestination(response));
try {
// modified...
xsl.parse(xmlSource(xmldoc));
}
catch (SAXException e) {
throw new ServletException(e);
}
}
static Parser createParser() throws ServletException {
String parserClass =
System.getProperty("com.jclark.xsl.sax.parser");
if (parserClass == null)
parserClass = System.getProperty("org.xml.sax.parser");
if (parserClass == null)
parserClass = "com.jclark.xml.sax.CommentDriver";
try {
return (Parser)Class.forName(parserClass).newInstance();
}
catch (ClassNotFoundException e) {
throw new ServletException(e);
}
catch (InstantiationException e) {
throw new ServletException(e);
}
catch (IllegalAccessException e) {
throw new ServletException(e);
}
catch (ClassCastException e) {
throw new ServletException(parserClass +
" is not a SAX driver");
207

}
}

classpath xt.jarsax.jarxp.jar SAX1 parser.jar servlet.jar


javac Big5URLXSLServlet.java

TOMCAT CLASSPATH TOMCAT_HOME\ classes


Big5URLXSLServlet.class
XML XSL TOMCAT
\Jakarta-tomcat\Webapps\ROOT\ xsl stockquote.xsl
stockquote.xml

Tomcat Web.xml
TOMCAT conf\Web.xml Servlet
<servlet>
<servlet-name>
RemoteStockquote
</servlet-name>
<servlet-class>
Big5URLXSLServlet
</servlet-class>
<init-param>
<param-name>stylesheet</param-name>
<param-value>http://localhost:8080/xsl/stockquote.xsl</param-value>
</init-param>
<init-param>
<param-name>xmldoc</param-name>
<param-value>http://localhost:8080/xsl/stockquote.xml</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>
RemoteStockquote
</servlet-name>
<url-pattern>
/rstockquote
</url-pattern>
</servlet-mapping>

Tomcat
Tomcat http://localhost:8080/rstockquote
208

4.5 XML-RPCRemote Procedure Call


XML-RPCRemote Procedure Call RPC
XML-RPC Remote Procedure Call
XML HTTP

Web Service
XML-RPC 1998 XML HTTP
JavaPHPFrontirePerlTcl
Zope XML-RPC
XML-RPC JavaXML-RPC Library for
Java Userland Java XML-RPC 1.0 beta 4
Hannes Wallnoeferhannes@helma.at http://helma.at/hannes/xmlrpc/
XML-RPC
http://helma.org/lists/listinfo/xmlrpc XML-RPC

XML-RPC
Java XML-RPC
XML-RPC
XML-RPC handler
<i4> <int>

java.lang.Integer

int

<boolean>

java.lang.Boolean

boolean

<string>

java.lang.String

java.lang.String

<double>

java.lang.Double

double

209

<dateTime.iso8601>

java.util.Date

java.util.Date

<struct>

java.util.Hashtable

java.util.Hashtable

<array>

java.util.Vector

java.util.Vector

<base64>

byte[ ]

byte[ ]

<nil/>

null

null

XML-RPC

XML-RPC
Procedure Call XML-RPC Handler Handler XML-RPC
Server XML-RPC Server XML-RPC Client XML-RPC Server

XML-RPC Server XML-RPC Handler


XML-RPC Handler Handler
XML-RPC Client Handler

XML-RPC for Java


http://helma.at/hannes/xmlrpc/xmlrpc-java.zip
1.0 beta 42000-10

xmlrpc-java
xmlrpc-java\doc

Javadoc
210

xmlrpc-java \examples
xmlrpc.jarXML-RPC
openxml-1.2.jar XML
xmlrpc-java\lib
xmlrpc-applet.jar applet XML-RPC client

xmlrpc-java\src

source code

openXML XML
JDK

XML-RPC Server
XML-RPC Server XML-RPC Handler
XML XML

XML-RPC Server
XmlRpcConf SAX HandlerBase
SAX XML
xmlrpc-conf.xml
<?xml version="1.0"?>
<xmlrpc-config>
211

<hostname>localhost</hostname>
<port>8585</port>

<xmlrpc-config-server>
<!-- XML-RPC handlers -->
<handler id="Currency" class="Currency" />
</xmlrpc-config-server>
</xmlrpc-config>
XML-RPC XmlRpcConf.java
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.Hashtable;
import org.xml.sax.Parser;
import org.xml.sax.AttributeList;
import org.xml.sax.InputSource;
import org.xml.sax.HandlerBase;
import org.xml.sax.SAXException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
public class XmlRpcConf extends HandlerBase {
// InputSource
private InputSource in;
// port
private int port;
// hostname
private String hostname;
// XML-RPC hander
private Hashtable handlers;
//
private String curElementName;
// XML-RPC hander
212

private String curIdentifier, curClass;


//
private boolean startConfigCommon, startConfigServer;
//
private XmlRpcConf handler;

public XmlRpcConf(InputSource in)


throws IOException {
this.in = in;
port = 0;
hostname = "";
handlers = new Hashtable();
//
parseConfiguration();
}

public XmlRpcConf(String filename)


throws IOException {
this(new FileReader(filename) );
}

public XmlRpcConf(FileReader fr)


throws IOException {
this(new InputSource( fr ));
}

public int getPort() {


return port;
}
213

public String getHostname() {


return hostname;
}
// XML-RPC handler
public Hashtable getHandlers() {
return handlers;
}

/*
// ....

for debug

public static void main(String args[]) {


//
try {
XmlRpcConf handler =
new XmlRpcConf(args[0]);
}
catch (IOException e) {
System.out.println("IO "+e.getMessage());
}

}
*/
//
private void parseConfiguration() {
boolean isValidating = false;
try {
// SAX
SAXParserFactory factory =
SAXParserFactory.newInstance();
SAXParser

parser = factory.newSAXParser();

factory.setValidating(isValidating);
factory.setNamespaceAware(false);
parser.parse(in, this);
214

}
catch (SAXException e) {
System.out.println("SAX "+e.getMessage());
}
catch (Exception e) {
System.out.println(""+e.getMessage());
}
}

public void startElement (String name,


AttributeList atts)
{
curElementName = name;
String aname;
String avalue;
//...debug
//System.out.println("ele="+name);
if (curElementName == "xmlrpc-config-server") {
startConfigServer = true;
return;
}
if (curElementName == "handler") {
for (int i = 0; i < atts.getLength(); i++) {
aname = atts.getName(i);
avalue = atts.getValue(i);
if (aname == "id") {
curIdentifier = avalue;
}
else if (aname == "class") {
curClass = avalue;
215

}
}
}
}

public void endElement (String name)


{
if (curElementName == "xmlrpc-config-server") {
startConfigServer = false;
}
else if (curElementName == "handler") {
// startConfigHandler = false;
handlers.put(curIdentifier, curClass);
//... debug
//System.out.println("handler id="+curIdentifier);
//System.out.println("

class="+curClass);

}
curElementName = "";
}
public void characters (char ch[], int start,
int length)
{
String s = (new String(ch, start, length)).trim();
if (s.length() == 0)
return;
//... debug
//System.out.println(" char="+s);
if (curElementName == "hostname") {
hostname = s;
//... debug
//System.out.println("hostname="+s);
}
else if (curElementName == "port") {
//... debug
216

//System.out.println("port="+s);
port = (new Integer(s)).intValue();
}
}
}

XML-RPC Server
XML-RPC ServerMyXmlRpcServer.java
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.Enumeration;
import java.util.Hashtable;
// XML-RPC Server
import helma.xmlrpc.XmlRpc;
import helma.xmlrpc.WebServer;
public class MyXmlRpcServer {
// XML-RPC Server
private WebServer server;
//
private XmlRpcConf config;

public MyXmlRpcServer(String configFile)


throws IOException {
//
config = new XmlRpcConf(configFile);
// XML-RPC Server
start();
}

public void start() throws IOException {


try {
// XML-RPC XML
217

XmlRpc.setDriver("com.sun.xml.parser.Parser");
System.out.println("Start XML-RPC Server...");
// XML-RPC Server
server = new WebServer(config.getPort());
// handlers XML-RPC Server
registerHandlers(config.getHandlers());
} catch (ClassNotFoundException e) {
throw new IOException("SAX parser : " +
e.getMessage());
}
}

public static void main(String[] args) {


if (args.length < 1) {
System.out.println(
"Usage: " +
"MyXmlRpcServer " +
"configFile");
System.exit(-1);
}
try {
MyXmlRpcServer server =
new MyXmlRpcServer(args[0]);
} catch (IOException e) {
System.out.println(e.getMessage());
}
}
// XML-RPC handlers XML-RPC Server
private void registerHandlers(Hashtable handlers) {
Enumeration handlerNames = handlers.keys();
// Hashtable XML-RPC handler
//
while (handlerNames.hasMoreElements()) {
String handlerName = (String)handlerNames.nextElement();
String handlerClass = (String)handlers.get(handlerName);
218

try {
// handler server
server.addHandler(handlerName,
Class.forName(handlerClass).newInstance());
System.out.println("handler id="+handlerName);
System.out.println("

class="+handlerClass);

} catch (Exception e) {
System.out.println("Could not register handler " +
handlerName + " with class " +
handlerClass);
System.out.println(e.toString());
}
}
}
}

XML-RPC handler
XML-RPC handler
Currency.xml

<currencytable>
<currency id="EUD" rate="28.18"/>
<currency id="USD" rate="32.79"/>
<currency id="FFranc" rate="4.194"/>
<currency id="SFranc" rate="18.25"/>
<currency id="Yen" rate="0.2887"/>
<currency id="DMark" rate="14.07"/>
<currency id="Can" rate="21.18"/>
<currency id="UKP" rate="46.27"/>
<currency id="Aust" rate="17.07"/>
</currencytable>
XML-RPC Handler Currency.java
import java.util.Hashtable;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import org.xml.sax.Parser;
import org.xml.sax.AttributeList;
import org.xml.sax.InputSource;
219

import org.xml.sax.HandlerBase;
import org.xml.sax.SAXException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
/**
* XML-RPC hander Demo
* for
* Get Currency Data
*
* @author: Growbal Kuo
* @email: growbal@taiwan.com
*/
public class Currency extends HandlerBase {
// InputSource
private InputSource in;
//
private Hashtable currencyTable;
//
private String curElementName;
// private String aname, avalue;
private String curIdentifier, curRate;
//private double USD;
//private double EUD;
//
private String filename = "Currency.xml";
public Currency() throws IOException
{
//
in = new InputSource(
new FileReader(filename)
);
// SAX
System.setProperty("sax.driver","com.sun.xml.parser.Parser");
currencyTable = new Hashtable();
//
parseCurrencyFile();
}
220

public String getCurrency(String currencyId) {


String ret;
//System.out.println(currencyId);
if (currencyTable.containsKey(currencyId)) {
ret = (String)currencyTable.
get(currencyId);
}
else {
ret="0";
}
return ret;
}
// .........................................................
private void parseCurrencyFile() {
boolean isValidating = false;
try {
// SAX
SAXParserFactory factory =
SAXParserFactory.newInstance();
SAXParser

parser = factory.newSAXParser();

factory.setValidating(isValidating);
factory.setNamespaceAware(false);
parser.parse(in, this);
}
catch (SAXException e) {
System.out.println("SAX "+e.getMessage());
}
catch (Exception e) {
System.out.println(""+e.getMessage());
}
221

//..... SAX1 HandlerBase method.....


public void startElement (String name,
AttributeList atts)
{
curElementName = name;
String aname;
String avalue;
//...debug
//System.out.println("ele="+name);
// curIdentifier curRate
if (curElementName == "currency") {
for (int i = 0; i < atts.getLength(); i++) {
aname = atts.getName(i);
avalue = atts.getValue(i);
if (aname == "id") {
curIdentifier = avalue;
}
else if (aname == "rate") {
curRate = avalue;
}
}
}
}

public void endElement (String name)


{
// Hashtable currencyTable
if (curElementName == "currency") {
currencyTable.put(curIdentifier, curRate);
222

}
curElementName = "";
}
}

XML-RPC client
XML-RPC XML-RPC handler client

XML-RPC Client CurrencyClient.java


import java.io.IOException;
import java.net.MalformedURLException;
import java.util.Vector;
import java.util.Hashtable;
import java.util.Enumeration;
import helma.xmlrpc.XmlRpc;
import helma.xmlrpc.XmlRpcClient;
import helma.xmlrpc.XmlRpcException;
public class CurrencyClient {
XmlRpcClient client;
public CurrencyClient(String[] args) {
try {
// XML-RPC Client XML-RPC Server port
// http://localhost:8585/
client =
new XmlRpcClient("http://localhost:8585/");
// RPC
startRPC(args);
} catch (MalformedURLException e) {
System.out.println(
"Incorrect URL of XML-RPC server: " +
e.getMessage());
} catch (IOException e) {
System.out.println("IO Exception: " +
e.getMessage());
}

catch (Exception e) {
System.out.println(e.toString());

}
223

}
public static void main(String args[]) {
if (args.length < 1) {
System.out.println(
"Usage: java -Dsax.driver=your.favorite.driver "+
"CurrencyClient currencyId");
System.exit(-1);
}
try {
CurrencyClient cc =
new CurrencyClient(args);
}

catch (Exception e) {
System.out.println(e.toString());

}
}

// XML-RPC
public void startRPC(String[] args) {
// Create request
Vector params = new Vector();
String currencyId = args[0].trim();
try {
// XML-RPC Vector
params.addElement(currencyId);
// XML-RPC ret
Object ret =
client.execute("Currency.getCurrency",
params);
System.out.println(ret);
224

if (ret.equals("0")) {
System.out.println
("No such currencyId:"+
currencyId);
}
else {
System.out.println("Currency of "+
currencyId+" = "+ret);
}
} catch (MalformedURLException e) {
System.out.println(
"Incorrect URL of XML-RPC server: " +
e.getMessage());
} catch (XmlRpcException e) {
System.out.println("XML-RPC Exception: " +
e.getMessage());
} catch (IOException e) {
System.out.println("IO Exception: " +
e.getMessage());
}

catch (Exception e) {
System.out.println(e.toString());

}
}
}

JDK classpath xmlrpc.jarjaxp.jarsax.jarparser.jar SAX

javac MyXmlRpcServer.java
javac XmlRpcConf.java
javac Currency.java
javac CurrencyClient.java

MyXmlRpcServer.class
XmlRpcConf.class
Currency.class
CurrencyClient.class

225

XML-RPC ServerMyXmlRpcServer.classXmlRpcConf.class
XML-RPC HandlerCurrency.classXML-RPC ClientCurrencyClient.class

Classpath XML XML-RPC


set classpath=e:\xml\jaxp.jar;e:\xml\sax.jar;e:\xml\parser.jar;e:
\xmlrpc.jar;%classpath%
XML-RPC Server
runs.bat XML-RPC server
java -Dsax.driver=com.sun.xml.parser.Parser MyXmlRpcServer xmlrpcconf.xml
runs.bat XML-RPC Server

XML-RPC Client
XML-RPC Server Classpath
runc2.bat
java -Dsax.driver=com.sun.xml.parser.Parser CurrencyClient %1 %2 %3 %4
runc2.bat Currency.xml
runc2 EUD

XML-RPC PHP XML-RPC


XML-RPC XML HTTP PHP
XML-RPC Client Java XML-RPC Server XML-RPC Handler XML-RPC

226

Apache Web Server


http://www.php.net PHP
Apache http.conf
PHP3
AddType application/x-httpd-php3

.php3 .php

PHP4
AddType application/x-httpd-php

.php3 .php

Windows 9x/NT/2000 PHP "c:\Program Files\PHP\" PHP CGI


Apache Apache httpd.conf
PHP3
scriptAlias /php3/ "c:\Program Files\PHP\"
AddType application/x-httpd-php3 .php3 .php
Action application/x-httpd-php3 "/php3/php.exe"
PHP4
scriptAlias /php/ "c:\Program Files\PHP\"
AddType application/x-httpd-php .php3 .php
Action application/x-httpd-php "/php/php.exe"
Apache PHP test.php3
<?php
phpinfo();
?>
Apache Linux /home/httpd/html Windows c:\Program Files\Apache
Group\Apache\htdocs
Apache Web Server
Windows
Apache server
"C:\Apache Group\Apache\Apache.exe"

-d "C:\Program Files\Apache

Group\Apache" -k shutdown
Apache server
"C:\Apache Group\Apache\Apache.exe" -f "C:\Apache
Group\Apache\conf\httpd.conf"
Linux
ps -aux httpd ID Apache server
kill httpd ID
227

Apache server
httpd
Apache Server
http://localhost
PHP

PHP XML-RPC client


XML-RPC for PHP http://xmlrpc.usefulinc.com/php.html xmlrpc1b8.zip
xmlrpc.inc XML-RPC client Apache
xml-rpc\ PHP XML-RPC Client

PHP XML-RPC client


HTML currencyclient.html
<html><body>
<DIV ALIGN=center>
<h1></h1>
<h3>by Growbal Kuo</h3>
<h5>modified in 2000</h5>
<h3>www.softchina.com.tw</h3>
<hr>
<form method="POST" action="currencyclient2.php3">
<SELECT
NAME="currencyId"
SIZE="1"
>
<OPTION value="USD"></OPTION>
<OPTION value="EUD"></OPTION>
<OPTION value="FFranc"></OPTION>
<OPTION value="SFranc"></OPTION>
<OPTION value="Yen"></OPTION>
<OPTION value="DMark"></OPTION>
228

<OPTION value="Can"></OPTION>
<OPTION value="UKP"></OPTION>
<OPTION value="Aust"></OPTION>
</SELECT>
<INPUT TYPE="SUBMIT"
NAME="submit"
VALUE=""
>
</form>
</DIV>
</html></body>
currencyclient2.php3
XML-RPC Client

PHP XML-RPC Client


<?php
// XML-RPC
include("xmlrpc.inc");
function getCurrencyName($id) {
if ($id=="USD") $ret = "";
else if ($id=="EUD") $ret = "";
else if ($id=="FFranc") $ret = "";
else if ($id=="SFranc") $ret = "";
else if ($id=="Yen") $ret = "";
else if ($id=="DMark") $ret = "";
else if ($id=="Can") $ret = "";
else if ($id=="UKP") $ret = "";
else if ($id=="Aust") $ret = "";
return $ret;
}
// ........................................
$msg=new xmlrpcmsg('Currency.getCurrency',
array(new xmlrpcval($currencyId)));
$client=new xmlrpc_client("/", "localhost", 8585);
// $c->setDebug(1);
$resp = $client->send($msg);
$value = $resp->value();
229

printf("<html><body>
<DIV ALIGN=center>
<h1></h1>
<h3>by Growbal Kuo</h3>
<h5>modified in 2000</h5>
<h3>www.softchina.com.tw</h3><hr>");
if (!$resp->faultCode()) {
$currencyName = getCurrencyName($currencyId);
printf("<h3>%s %s </h3><BR>", $currencyName,
$value->scalarval() );
} else {
print "XML-RPC : ";
print "<br>Code: " . $resp->faultCode() .
" Reason '" .$resp->faultString()."'<BR>";
printf("<br>%s",$v);
}
printf('<A href="javascript:location.href=window.history.go(-1)"></A>');
printf("</body></html>");
?>
PHP XML-RPC
$client=new xmlrpc_client("/", "localhost", 8585);
XML-RPC Client http://localhost XML-RPC ServerServer port 8585
"/" XML-RPC Server Java "/"
$msg=new xmlrpcmsg('Currency.getCurrency',
array(new xmlrpcval($currencyId)));
XML-RPC Currency.getCurrency xmlrpcval

$resp = $client->send($msg);
$value = $resp->value();
XML-RPC Server$resp
$value->scalarval()

currencyclient.html currencyclient2.php3 Apache Web Server


xml-rpc/

230

XML-RPC Java
Classpath Thin-client

Web Server PHP XML-RPC Server XML-RPC


Handler Web Service
XML-RPC Web Server XML-RPC Server
Service Web Service

Web Server XML-RPC server

Java XML-RPC Server runs.bat


Apache Web Server
Apache Web Server http://localhost/xml-rpc/currencyclient.html

231

4.6 SOAPSimple Object Access Protocol

SOAPSimple Object Access Protocol SOAP

SOAP XML SOAP


HTTP

SOAP
SOAP 1998 HTTP RPCRemote Procedure Call
SOAP SOAP
Microsoft DCOM
SOAP UserLand 1998 XML-RPC
1999 SOAP 1999 12 IETFInternet Engineering Task Force
SOAP 1.0 SOAP for Java DevelopMentor
2000 4 SOAP 1.1 IBMMicrosoftDevelopMentorUserLand
SOAPIBM alphaworks SOAP4J SOAP Java 2000 6
Apache Group SOAP Apache XML Project http://xml.apache.org

SOAP

232

Web
application
Web ServiceWeb Service
providor
Web Service Web Service

Web Service

Web Service

Web Service out-sourcing

XML SOAP XML XML


message SOAP SOAP
SOAP
Business-to-business
loosely coupledSOAP
XML SOAP RPC Web Service

SOAP

233

SOAP SOAP
SOAP SOAP-RPC SOAP Server
GetLastTradePrice
POST /StockQuote HTTP/1.1
Host: www.stockquoteserver.com
Content-Type: text/xml; charset="utf-8"
Content-Length: nnnn
SOAPAction: "Some-URI"
<SOAP-ENV:Envelope
xmlns:SOAP-ENV=http://schemas.xmlsoap.org/soap/envelope/
SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<SOAP-ENV:Body>
<m:GetLastTradePrice xmlns:m="TradePriceInfoServer">
<symbol>DIS</symbol>
</m:GetLastTradePrice>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
Server SOAP-RPC
HTTP/1.1 200 OK
Content-Type: text/xml; charset="utf-8"
Content-Length: nnnn
<SOAP-ENV:Envelope
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
<SOAP-ENV:Body>
<m:GetLastTradePriceResponse xmlns:m=" TradePriceInfoServer ">
<Price>123</Price>
</m:GetLastTradePriceResponse>
234

</SOAP-ENV:Body>
</SOAP-ENV:Envelope>

Java SOAP http://xml.apache.org/soap/ soap-bin-2.0.tar.gz


2.0 Apache Group Java SOAP
lib soap.jar
Webapps\soap\ jakarta-tomcat Webapps jakarta-tomcat\Webapps\soap
soap\ admin SOAP service deploy

Java SOAP
SOAP
1. soap.jar
2. Apache xerces parserxerces.jar
SOAP
1. soap.jar
2. Apache xerces parserxerces.jar
3. Servlet JSP Tomcat

235


SOAP

SOAP service WareHouse.java


SOAP client service RPC client SetItem.java
GetItem.javaGetAll.javaAddQty.java

SOAP service
SOAP service
Hashtable Hashtable

persistence layer
Tomcat server SOAP service
persistence layer
import java.util.*;
import org.apache.soap.util.xml.*;
/**
* SOAP service
*
* @author Growbal Kuo
*/
public class WareHouse
{
private Hashtable Items=new Hashtable();
public WareHouse() {
System.out.println("Start of WareHouse Service V.1.0");
}
// SOAP service 4 RPC--setItem, getQty, addQty, getAll
public void setItem(String name, String qty)
{
System.out.println("setItem:"+name+", "+qty);
Items.put(name, qty);
showItems();
}

public String getQty(String name)


236

throws IllegalArgumentException
{
String ret;
if (name == null)
{
throw new IllegalArgumentException
("Argument 'name' must not be null.");
}
System.out.println("Get:"+name);
if (Items.containsKey(name)) {
ret= (String)Items.get(name);
System.out.println("Qty of "+name+"="+ret);
}
else {
System.out.println("No such item:"+name);
ret="-1";
}
return ret;
}
public String addQty(String name, String qty)
throws IllegalArgumentException
{
String newQty;
if (name == null || qty==null)
{
throw new IllegalArgumentException
("Argument 'name' and 'qty' must not be null.");
}

if (Items.containsKey(name)) {
int curQty =
Integer.parseInt( (String)Items.get(name) );
237

int change = Integer.parseInt(qty);


newQty = (new Integer(curQty + change)).toString();
Items.put(name, newQty);
System.out.println("Qty of "+name+"="+newQty);
}
else {
System.out.println("No such item:"+name);
newQty="-1";
}
return newQty;
}
public String getAll()
{
System.out.println("GetAll");
showItems();
return (Items!=null?Items.toString():
"No item!");
}

// getall method
public void showItems() {
Enumeration itemNames = Items.keys();
String itemName;
String itemQty;
if (Items.isEmpty()) {
System.out.println("No item!");
return;
}
while (itemNames.hasMoreElements()) {
itemName = (String)itemNames.nextElement();
238

itemQty = Items.get(itemName).toString();
System.out.println("item name="+
itemName+", qty="+itemQty);
}
}
}

SOAP client
SOAP service RPC setItemgetAllgetQtyaddQty Client
RPC
SetItem.java
import java.io.*;
import java.util.*;
import java.net.*;
import org.apache.soap.util.xml.*;
import org.apache.soap.*;
import org.apache.soap.encoding.*;
import org.apache.soap.encoding.soapenc.*;
import org.apache.soap.rpc.*;
/**
*
*
* @author Growbal Kuo
*/
public class SetItem
{
public static void main(String[] args) throws Exception
{
// RPC Router Servlet URL
URL url = new URL(args[0]);
//
String name = args[1];
String qty = args[2];
String encodingStyleURI = Constants.NS_URI_SOAP_ENC;

// Build the call.


Call call = new Call();
// SOAP Service
239

call.setTargetObjectURI("urn:WareHouse");
// RPC
call.setMethodName("setItem");
call.setEncodingStyleURI(encodingStyleURI);
// RPC
Vector params = new Vector();
params.addElement(new Parameter("name", String.class,
name, null));
params.addElement(new Parameter("qty", String.class,
qty, null));
call.setParams(params);
// RPC
System.out.println("ready to call invoke-->setItem: "+name+", "+qty);
Response resp;
try
{
resp = call.invoke(url, "");
}
catch (SOAPException e)
{
System.err.println("Caught SOAPException (" +
e.getFaultCode() + "): " +
e.getMessage());
return;
}
catch (Exception e) {
System.out.println(e.toString());
return;
}
//
if (!resp.generatedFault())
{
System.out.println(name + " has been added.");
}
else
{
240

Fault fault = resp.getFault();


System.err.println("Generated fault: ");
System.out.println (" Fault Code

= " + fault.getFaultCode());

System.out.println (" Fault String = " + fault.getFaultString());


}
}
}
GetAll.java
import java.io.*;
import java.util.*;
import java.net.*;
import org.apache.soap.util.xml.*;
import org.apache.soap.*;
import org.apache.soap.encoding.*;
import org.apache.soap.encoding.soapenc.*;
import org.apache.soap.rpc.*;
public class GetAll
{
private String result = null;
private URL url;
private Call call;
public GetAll(String arg) throws MalformedURLException {
url = new URL(arg);
start();
execRPC();
}
private void start() {
String encodingStyleURI = Constants.NS_URI_SOAP_ENC;
SOAPMappingRegistry smr = new SOAPMappingRegistry();
BeanSerializer beanSer = new BeanSerializer();
// Build the call.
call = new Call();
241

call.setTargetObjectURI("urn:WareHouse");
call.setMethodName("getAll");
call.setEncodingStyleURI(encodingStyleURI);
}

private void execRPC() {


Response resp;
try
{
resp = call.invoke(url, "");
}
catch (SOAPException e)
{
System.err.println("Caught SOAPException (" +
e.getFaultCode() + "): " +
e.getMessage());
return;
}
catch (Exception e) {
System.out.println(e.toString());
return;
}
if (!resp.generatedFault())
{

Parameter ret = resp.getReturnValue();


Object value = ret.getValue();
if (value != null) {
result = value.toString();
System.out.println("result:"+result+"\n");
System.out.println("RPC response:"+resp.toString());
242

}
else {
System.out.println("null result value");
}
}
else
{
Fault fault = resp.getFault();
System.err.println("Generated fault: ");
System.out.println (" Fault Code

= " + fault.getFaultCode());

System.out.println (" Fault String = " + fault.getFaultString());


}
}
public static void main(String[] args) throws Exception
{
new GetAll(args[0]);

}
GetQty.java
import java.io.*;
import java.util.*;
import java.net.*;
//import org.w3c.dom.*;
import org.apache.soap.util.xml.*;
import org.apache.soap.*;
import org.apache.soap.encoding.*;
import org.apache.soap.encoding.soapenc.*;
import org.apache.soap.rpc.*;
public class GetQty
{
public static void main(String[] args) throws Exception
{
243

if (args.length != 2
&& (args.length != 3 || !args[0].startsWith("-")))
{
System.exit (1);
}
URL url = new URL(args[0]);
String nameToLookup = args[1];
String encodingStyleURI = Constants.NS_URI_SOAP_ENC;
Call call = new Call();
call.setTargetObjectURI("urn:WareHouse");
call.setMethodName("getQty");
call.setEncodingStyleURI(encodingStyleURI);
Vector params = new Vector();
params.addElement(new Parameter("name", String.class,
nameToLookup, null));
call.setParams(params);
Response resp;
try
{
resp = call.invoke(url, "");
}
catch (SOAPException e)
{
System.err.println("Caught SOAPException (" +
e.getFaultCode() + "): " +
e.getMessage());
return;
}
if (!resp.generatedFault())
{
Parameter ret = resp.getReturnValue();
Object value = ret.getValue();
System.out.println(value != null ? "\n" + value : "I don't know.");
244

}
else
{
Fault fault = resp.getFault();
System.err.println("Generated fault: ");
System.out.println (" Fault Code

= " + fault.getFaultCode());

System.out.println (" Fault String = " + fault.getFaultString());


}
}
}
AddQty.java
import java.io.*;
import java.util.*;
import java.net.*;
// import org.w3c.dom.*;
import org.apache.soap.util.xml.*;
import org.apache.soap.*;
import org.apache.soap.encoding.*;
import org.apache.soap.encoding.soapenc.*;
import org.apache.soap.rpc.*;
public class AddQty
{
private static String name, qty;
private String result = null;
private URL url;
private Call call;
public AddQty(String arg) throws MalformedURLException {
url = new URL(arg);
start();
execRPC();
}
private void start() {
String encodingStyleURI = Constants.NS_URI_SOAP_ENC;
245

call = new Call();


call.setTargetObjectURI("urn:WareHouse");
call.setMethodName("addQty");
call.setEncodingStyleURI(encodingStyleURI);
Vector params = new Vector();
params.addElement(new Parameter("name", String.class,
name, null));
params.addElement(new Parameter("qty",
String.class, qty, null));
call.setParams(params);
}

private void execRPC() {


Response resp;
try
{
resp = call.invoke(url, "");
}
catch (SOAPException e)
{
System.err.println(
"Caught SOAPException (" +
e.getFaultCode() + "): " +
e.getMessage());
return;
}
catch (Exception e) {
System.out.println(e.toString());
return;
}
if (!resp.generatedFault())
{
Parameter ret = resp.getReturnValue();
246

Object value = ret.getValue();


if (value != null) {
result = value.toString();
System.out.println("result:"+
result+"\n");
System.out.println("RPC response:"+
resp.toString());
}
else {
System.out.println(
"null result value");

}
}
else
{
Fault fault = resp.getFault();
System.err.println("Generated fault: ");
System.out.println (" Fault Code

="+

fault.getFaultCode());
System.out.println (" Fault String = " +
fault.getFaultString());
}
}
public static void main(String[] args) throws Exception
{
name = args[1];
qty = args[2];
new AddQty(args[0]);
}

247

classpath xerces.jar soap.jar


javac WareHouse.java
javac SetItem.java
javac GetAll.java
javac GetQty.java
javac AddQty.java

SOAP service SOAP RPC Router


Tomcat \conf\Web.xml Tomcat URI
http://localhost:8080/servlet/rpcrouter SOAP Client RPC Router Servletsoap.jar
org.apache.soap.server.http.RPCRouterServlet

<servlet>
<servlet-name>
rpcrouter
</servlet-name>
<servlet-class>
org.apache.soap.server.http.RPCRouterServlet
</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>
rpcrouter
</servlet-name>
<url-pattern>
/servlet/*
</url-pattern>
</servlet-mapping>
Tomcat bin/startup.batxerces.jarsoap.jar SOAP service
WareHouse.class e:\dev\soap\WareHouse Classpath

set classpath=e:\xml\xerces.jar;e:\xml\soap.jar;e:\dev\soap\WareHouse;%classpath%
bin/startup.bat bin/Tomcat.bat

set CLASSPATH=%CLASSPATH%;%cp%

set CLASSPATH=%cp%;%CLASSPATH%
xerces.jar xerces

deploy SOAP service


Tomcat
248

SOAP service
http://localhost:8080/soap/admin/

Deploy SOAP serviceWareHouse

ID urn:WareHouse
Scope SOAP service application
Method List SOAP servic RPC setItem getQty getAll
addQty
Provider Type Java
Provider Class WareHouse

List SOAP Service

249


Tomcat server shutdown.bat Tomcat server startup.bat
SOAP service
SOAP client SOAP service RPC Router URI RPC Router SOAP
service
1. setitem.bat
2. @echo off
3. set RPCRouter=http://localhost:8080/servlet/rpcrouter
java SetItem %RPCRouter% %1 %2
4. getall.bat
5. @echo off
6. set RPCRouter=http://localhost:8080/servlet/rpcrouter
java GetAll %RPCRouter%
7. addqty.bat
8. @echo off
9. set RPCRouter=http://localhost:8080/servlet/rpcrouter
java AddQty %RPCRouter% %1 %2
10. getqty.bat
11. @set RPCRouter=http://localhost:8080/servlet/rpcrouter
@java GetQty %RPCRouter% %1

setitem item1 11

setitem item2 22

250

getall

addqty item1 2

getqty item1

GUI SOAP client


Graphic User
Interface Java swing GUI
WareHouseClient SOAP Client SOAP Client
WHGUI GUI WareHouseClient SOAP RPC

SOAP Client
WareHouseClient.java
import java.io.*;
251

import java.util.*;
import java.net.*;
import org.apache.soap.util.xml.*;
import org.apache.soap.*;
import org.apache.soap.encoding.*;
import org.apache.soap.encoding.soapenc.*;
import org.apache.soap.rpc.*;
/**
* SOAP Client of WareHouse
*
* @author Growbal Kuo
* @email growbal@taiwan.com
*/
public class WareHouseClient
{
private String result = null;
private URL url;
private Call call;
// RPCRouterServlet URI
public WareHouseClient(String arg) throws
MalformedURLException
{
url = new URL(arg);
}
private void start(String method) {
String encodingStyleURI =
Constants.NS_URI_SOAP_ENC;
// RPC
call = new Call();
// SOAP service
call.setTargetObjectURI("urn:WareHouse");
// RPC
call.setMethodName(method);
call.setEncodingStyleURI(encodingStyleURI);
252

}
// RPC Vector
private void setParameters(String name, String qty) {
Vector params = new Vector();
params.addElement(new Parameter("name",
String.class, name, null));
params.addElement(new Parameter("qty",
String.class, qty, null));
call.setParams(params);
}
private void setParameters(String name) {
Vector params = new Vector();
params.addElement(new Parameter("name",
String.class, name, null));
call.setParams(params);
}
// SOAP RPC
private void execRPC() {
// start RPC
Response resp;
Object value;
try
{
resp = call.invoke(url, "");
}
catch (SOAPException e)
{
System.err.println
("Caught SOAPException ("+
e.getFaultCode() + "): " +
e.getMessage());
253

return;
}
catch (Exception e) {
System.out.println(e.toString());
return;
}
//
if (!resp.generatedFault())
{
System.out.println("RPC response:"+
resp.toString());
Parameter ret = resp.getReturnValue();
if (ret == null) {
System.out.println
("null result value");
return;
}
else {
value = ret.getValue();
}
if (value != null) {
result = value.toString();
System.out.println
("result:"+result+"\n");
}
else {
System.out.println
("null result value");
}
}
else
{
Fault fault = resp.getFault();
System.err.println("Generated fault: ");
254

System.out.println (" Fault Code

="+

fault.getFaultCode());
System.out.println (" Fault String = " +
fault.getFaultString());
}
}
// GUI method
public String getResult(String method) {
try {
start(method);
execRPC();
} catch (Exception e) {
System.out.println(e.toString());
}
return result;
}
public String getResult(String method, String item, String qty) {
try {
start(method);
setParameters(item, qty);
execRPC();
System.out.println(item+","+qty);
} catch (Exception e) {
System.out.println(e.toString());
}
return result;
}
public String getResult(String method, String item) {
try {
start(method);
setParameters(item);
execRPC();
255

} catch (Exception e) {
System.out.println(e.toString());
}
return result;
}
}

GUI
WindowListener MyWindowListener
import java.awt.*;
import java.awt.event.*;
class MyWindowListener extends WindowAdapter
{
public void windowClosing(WindowEvent e)
{
System.exit(1);
}
}
GUI WHGUI
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import MyWindowListener;
import WareHouseClient;
import java.net.*;
/**
* Warehouse SOAP Client
* with
* Graphic User Interface
*
* @author: Growbal Kuo
* @email: growbal@taiwan.com
* Dec. 2, 2000
*
*/
public class WHGUI extends JFrame
{
private static String RPCRouter;
256

WareHouseClient WHClient;
Font f1 = new Font("", Font.PLAIN, 16);
// RPC
JButton buttonGetAll=new JButton("");
JButton buttonGetQty=new JButton("");
JButton buttonSetItem=new JButton("");
JButton buttonAddQty=new JButton("");
//
JTextField fieldItem=new JTextField("",30);
JTextField fieldQty=new JTextField("",10);
JTextArea textArea=new JTextArea(2,20);
JLabel labelItem = new JLabel(":");
JLabel labelQty = new JLabel(":");
Container c;
public WHGUI()
{
super("WareHouse GUI");
c = getContentPane();
c.setLayout(new FlowLayout());
buttonGetAll.setFont(f1);
buttonGetQty.setFont(f1);
buttonSetItem.setFont(f1);
buttonAddQty.setFont(f1);
fieldItem.setFont(f1);
fieldQty.setFont(f1);
labelItem.setFont(f1);
labelQty.setFont(f1);
c.add(buttonGetAll);
c.add(buttonSetItem);
c.add(buttonGetQty);
c.add(buttonAddQty);
c.add(labelItem);
c.add(fieldItem);
c.add(labelQty);
c.add(fieldQty);
257

c.add(textArea);
setSize(450,250);
setVisible(true);
buttonGetAll.addActionListener
(new AppListener());
buttonSetItem.addActionListener
(new AppListener());
buttonGetQty.addActionListener
(new AppListener());
buttonAddQty.addActionListener
(new AppListener());
try {
WHClient= new
WareHouseClient(RPCRouter);
} catch (MalformedURLException e) {
System.out.println(e.toString());
}
}
class AppListener implements ActionListener
{
public void actionPerformed(ActionEvent e) {
String ret = "";
String item ="", qty ="";
// WareHouseClient
// RPC
if (e.getSource()==buttonGetAll) {
ret = WHClient.getResult("getAll");
textArea.setText
(":"+ret);
} else if(e.getSource()==buttonSetItem) {
item = fieldItem.getText();
qty = fieldQty.getText();
258

WHClient.getResult
("setItem",item, qty);
textArea.setText("");
} else if (e.getSource()== buttonGetQty) {
item = fieldItem.getText();
ret = WHClient.getResult
("getQty",item);
textArea.setText(":"+ret);
} else if (e.getSource()==buttonAddQty) {
item = fieldItem.getText();
qty = fieldQty.getText();
ret = WHClient.getResult
("addQty",item, qty);
textArea.setText(":"+ret);
}
}
}

public static void main(String args[])


{
if (args.length ==0) {
System.out.println(
"Usage: java WHGUI URI_of_RPCRouter");
}
// RPC Router servlet URI
RPCRouter = args[0];
WHGUI app = new WHGUI();
app.addWindowListener(new MyWindowListener());
}
}

259

Classpath xerces.jarsoap.jar
javac WareHouseClient.java
javac MyWindowListener.java
javac WHGUI.java

WareHouseClient.class
MyWindowListener.class
WHGUI.class
WHGUI$AppListenser.class

wh.hat
@echo off
set RPCRouter=http://localhost:8080/servlet/rpcrouter
java WHGUI %RPCRouter%
wh.bat

SOAP
SOAP Serialize

SOAP
SOAP HTTP Header Content-Type utf-8 Big5
"text/xml; charset=Big5"
SOAP
SOAP
SOAP Base64
org.apache.soap.encoding.soapenc.Base64
260

byte Base64 encode


Base64 decodebyte
name

byte[] ChByte = name.getBytes();


base64 name1
String name1 = new Base64().encode(ChByte);

String name1 = new Base64().encode(name.getBytes());


SOAP
Base64 result SOAP Base64
decode
byte[] ChByte = new Base64().decode(result)

String result = new String(ChByte);

String result = new String( new Base64().decode(result) );

WareHouseClient.java
private void setParameters(String name, String qty) {

Vector params = new Vector();

// Base64
String name1 = new Base64().encode(name.getBytes());

params.addElement(new Parameter("name",
String.class,
name1, null));

params.addElement(new Parameter("qty",
String.class, qty, null));
call.setParams(params);
261

}
private void setParameters(String name) {
Vector params = new Vector();
// Base64
String name1 = new Base64().encode(name.getBytes());
params.addElement(new Parameter("name",
String.class,
name1, null));
call.setParams(params);
}
public String getResult(String method) {
try {
start(method);
execRPC();
} catch (Exception e) {
System.out.println(e.toString());
}
// Base64
result = new String( new Base64().decode(result) );
return result;
}
WareHouse.java
public void setItem(String name, String qty)
{
//SOAP Service Base64
byte[] b1 = new Base64().decode(name);
String name1 = new String(b1);
System.out.println("setItem:"+name1+", "+qty);
Items.put(name1, qty);
showItems();
}

public String getQty(String name)


262

throws IllegalArgumentException
{
String ret;

if (name == null)
{
throw new IllegalArgumentException
("Argument 'name' must not be null.");
}

// Base64
String name1 = new String(new Base64().decode(name));
System.out.println("Get:"+name1);
if (Items.containsKey(name1)) {
ret= (String)Items.get(name1);
System.out.println("Qty of "+name1+"="+ret);
}
else {
System.out.println("No such item:"+name1);
ret="-1";
}
return ret;
}
public String addQty(String name, String qty)
throws IllegalArgumentException
{
String newQty;
if (name == null || qty==null)
{
throw new IllegalArgumentException
("Argument 'name' and 'qty' must not be null.");
}
263

// Base64
byte[] b1 = new Base64().decode(name);
String name1 = new String(b1);
if (Items.containsKey(name1)) {
int curQty =
Integer.parseInt( (String)Items.get(name1) );
int change = Integer.parseInt(qty);
newQty = (new Integer(curQty + change)).toString();
Items.put(name1, newQty);
System.out.println("Qty of "+name1+"="+newQty);
}
else {
System.out.println("No such item:"+name1);
newQty="-1";
}
return newQty;
}
public String getAll()
{
System.out.println("GetAll");
showItems();
return (Items!=null?
new Base64().encode(Items.toString().getBytes()):
"No item!");
}

Web Service
SOAP sevice SOAP client SOAP for Java SOAP
client request SOAP serviceSOAP service response SOAP client
Web Service SOAP service SOAP service

264

IBM Web Services Architecture Team Web Service


Web Service service providerservice
brokerservice requesterpublishbind
find

WWWrequest service
Internet
Web ServiceWeb Service

...
JClark XT XSLServlet il8n

265

5.1 e-CommerceEDIEAI
...
XML Java XML
Internet

SOAP
Web Service
WAP

Linux

e-CommerceEDIEAI
EAI
e

XML
EAI

B2C e-Commerce
B2C WWW Internet WWW
Internet B2C
B2C
B2C
B2C

266

B2B e-Commerce EDI


EDI B2B
Internet B2B

XML
EDI
B2B EAI
B2C B2B
B2C B2B

XML B2B

Remote Procedure CallRPC


RPC
CORBACommon Object Request Broker Architecture Java RMIRemote Method
InvocationJava RMI
Java
XML over HTTP RPC XML
XML HTTP RPC
XML-RPC SOAP XML over HTTP RPC
XML XML over HTTP RPC

CORBA Java RMI serialization


XML over HTTP Web server CORBA
RMI

267

5.2
JDK
4

Jakarta-Tomcat Server
4
Tomcat classpath bin\startup.bat Win32
Linux bin/startup.sh classpath
set classpath=e:\dev\b2b2c; e:\xml\sax2.jar; e:\xml\xerces.jar; e:\xml\jdom.
jar; e:\xml\soap.jar; e:\xml\mm.mysql.jdbc-1.2c; e:\xml\xt.jar e:\xml\xp.jar

Tomcat conf/Web.xml SOAP RPCRouter servlet 4 SOAP

SAX2 parser package


SAX version 2 XML
http://www.megginson.com

Apache Xerces parser package


Apache Xerces Java XML
http://xml.apache.org/dist/xerces-j/

Apache-SOAP package
Apache-SOAP 2.0
http://xml.apache.org/soap

JDOM parser package


JDOM XML b5
http://jdom.org

Servlet package
Sun JSDKJava Servlet Development Kit JSWDKJavaServer Web Development Kit
Servlet 2.1
http://java.sun.com
Jakarta Tomcat servlet.jar 2.2 Servlet API

Clark's XP XT
XML XSL
4 XSLT Clark's XT XML XP
http://www.jclark.com/xml/xp/index.html

268

Clark's XT XSLT 4
Clark's XT XSLServlet Big5XSLServlet
XSLXML XML WML
Clark XT
XSL/XML WML
Apache Group Xalan XSLT XT Apache
Group

MySQL

Linux MySQL
MySQL
http://www.mysql.com
RedHat Linux MySQL MySQL
MySQL

MySQL JDBC driver


Java MySQL MySQL JDBC JDBC

MySQL JDBC Mark Matthews mm-MySQL 1.2c


GNU public license
JDBC Type 4 JDBC driver pure Java

http://www.worldserver.com/mm.mysql/

mm.mysql.jdbc-1.2c.tar.gz
mm.mysql.jdbc-1.2c/ JDBC driver jar JDBC
driver MySQL classpath

WAP
XSL+XML HTML WMLWireless Markup Language WAPWireless
Application Protocol
WAP NokiaEricssonMotorola WAP
phone.com WAP WAP WML
WML WML
phone.com UP SDK 4.x WAP http://www.phone.com

UP
UP SDK 4.x UP Simulator WAP

269

SettingUP.Link Settings
HTTP Direct URLOK

SettingDevice Settings
Language (zh) ChineseCharset Traditional Chinese (Big5) Big5

5.3

e
database server
database enginedatabasetable
recordrowfield

270

Oracle
memberDB
saleDB
memberDB
personalInfoTable
personalProfitTable
personalInfoTable
nameCHAR 20
birthdayDATE
idCHAR 10

SQL
SQL
SQL SQL
SQL SQL

CREATE DATABASE <>

CREATE DATABASE warehouse;


warehouse

DROP DATABASE <>

DROP DATABASE warehouse;


271

warehouse

USE <>

USE warehouse;
warehouse

CREATE TABLE

<> (

,
........
)

CREATE TABLE membership (


name CHAR(20),
birthday DATE,
password CHAR(20),
address CHAR(60),
tel1

CHAR(20)

);
membership namebirthdaypasswordaddresstel1

SQL
INT
DOUBLE
FLOAT
DECIMAL(, )
NUMERIC(, )
CHAR()
VARCHAR()
DATE
TIME
TIMESTAMP
DATETIME
BLOB

DROP TABLE

<>
272


DROP TABLE

membership;

membership

DELETE FROM <> [WHERE.....]


membership
DELETE FROM membership;

DELETE FROM membership WHERE name='Alex';


membership name Alex

SELECT <> FROM <> [WHERE .....]

membership
SELECT * FROM membership;

SELECT address, tel1, password

FROM membership WHERE name='arthur';

membership name arthur address, tel1, password

INSERT INTO <> () VALUES ()

membership
INSERT INTO membership (name, birthday, password, address, tel1)
VALUES ('arthur', '1960-01-26', 'tseng', '.....', '.......');

UPDATE <> SET =, =,.....


WHERE <>

UPDATE membership SET tel1='02-27093611', address='....'


WHERE name='emily';
membership name emily tel1 address

MySQL
MySQL MySQL
MySQL PHP
273

MySQL MySQL MySQL

Linux MySQL Windows

MySQL http://www.mysql.com

MySQL
http://www.mysql.com MySQLLinux MySQL RPM
MySQL-3.22.32-1.i386.rpm MySQL
MySQL-client-3.22.32-1.i386.rpm MySQL client

rpm -ivh [RPM ]


Source
MySQL-3.22.32-1.src.rpm

MySQL
Linux MySQL RPM
/usr/share/mysql/mysql.server
MySQL server
/usr/share/mysql/mysql.server stop

/usr/share/mysql/mysql.server start

MySQL root
MySQL client root MySQL server
mysql -u root
MySQL

mysql> create database warehouse;


warehouse MySQL
warehouse RPMMySQL /var/lib/mysql

MySQL
GRANT growbal localhost javaxml
warehouse
mysql> GRANT ALL PRIVILEGES ON warehouse.*
TO growbal@localhost
IDENTIFIED BY 'javaxml';
274

SQL

USE warehouse;
membership mysql>
create table membership (
username char(20),
password char(20),
address char(60),
tel1 char(20)
);
SQL MySQL client mysql>
MySQL client SQL
SQL SQL insert_membership.sql
insert into membership
(username, password, address, tel1) values
('arthur','tseng',' 50 10 ','2311-8765');
insert into membership
(username, password, address, tel1) values
('emily','huang',' 50 10 ','2311-8765');
insert into membership
(username, password, address, tel1) values
('growbal','javaxml',' 50 10 ','2311-8765');
SQL Linux shell
mysql -u root warehouse < insert_membership.sql
Win32 MySQL MySQL client mysql> SOURCE <
>
SOURCE insert_membership.sql
MySQL client mysql>
SELECT * FROM membership;

275

5.4 JDBC
JDBC JDBC
JDBCJava Database Connectivity Java API java.sql
SQL
ODBCOpen Database Connectivitynative code
SQL Windows ODBC driver MS
SQL serverOracleSybase Microsoft Office ExceldBASE ODBC
driver ODBC driver SQL
JDBC JDBC Java
SQL
JDBC driver Sun
JDBC-ODBC bridge Java JDBC-ODBC bridge driver ODBC driver
ODBC driver Java
JDBC
JDBC-ODBC bridge ODBC Java Virtual Machine
Java
JDBC Java JDBC driver

JDBC JDBC driver MySQL JDBC driver


org.gjt.mm.mysql.Driver
Class.forName("org.gjt.mm.mysql.Driver").newInstance();
JDBC URL
localhost MySQL warehouse
jdbc:mysql://localhost/warehouse
URL
jdbc:mysql://localhost/warehouse?user=growbal&password=javaxml

Connection con = DriverManager.getConnection(


"jdbc:mysql://localhost/warehouse?user=growbal?password=javaxml");

SQL
JDBC Statement
276

Statement stmt = con.createStatement();


Statement SQL
SELECT ResultSet
ResultSet rs = stmt.executeQuery("SELECT * FROM membership");
ResultSet method next()
while (rs.next()) {
System.out.println("NAME="+rs.getString(1));
}
1 2 method
CHAR getString(index)INT getInt(index)
SQL Prepared statement SQL
SQL
java.sql PreparedStatement SQL
SQL

PreparedStatement pstmt = con.prepareStatement(


"SELECT name FROM membership WHERE name=?");

pstmt.setString(1, "arthur");
CHAR setString() INT setInt()
SQL 2
PreparedStatement
PreparedStatement SQLexcuteQuery()
ResultSet rs = pstmt.executeQuery();
ResultSet

SQL
SQL UPDATEINSERTDELETE method excuteUpdate()
SQL

Statement stmt = con.createStatement();


int rowCount = stmt.excuteUpdate("update stock set qty=30 where
id='X1000'");
Prepared Statement
PreparedStatement pstmt = con.prepareStatement("update stock set
qty=? where id=?");
pstmt.setInt(1, newQty);
pstmt.setString(2, id);
int rowCount = pstmt.executeUpdate();

SQL
277

SQL SELECT UPDATEINSERTDELETE

java.sql.Statement method excute() SQL boolean true


SQL ResultSet false ResultSet

// SQL
String sqlStmt = "SELECT * FROM membership "
Statement stmt = con.createStatement();
boolean isResultSet = stmt.excute ( sqlStmt );
if ( isResultSet )
// isResultSet true ResultSet
ResultSet rs = stmt.getResultSet();
else
// isResultSet false
int rowCount = stmt.getUpdateCount();
PreparedStatement excute() excute() SQL
PreparedStatement

// SQL
String sqlStmt = "SELECT * FROM membership "
Statement pstmt = con.prepareStatement( sqlStmt );
boolean isResultSet = pstmt.excute ();
if ( isResultSet )
// isResultSet true ResultSet
ResultSet rs = pstmt.getResultSet();
else
// isResultSet false
int rowCount = pstmt.getUpdateCount();

5.5 B2B2C
B2B2C growbal-SimFan.com

278


deliver.com

deliver.com Web

SOAP RPC Web Service SOAP

game-supply.com

SOAP RPC SOAP


XML DTD

5.6 B2C
B2C
growbal-SimFan.com

XML catalog.xml
JSP Java JSP JavaBean
JSP Java

279

XML
XML catalog.xml XML DTD catalog.dtd

catalog.dtd
<?xml version="1.0" ?>
<!ELEMENT PRODUCTS (ITEM+)>
<!ELEMENT ITEM (NAME, ID, COMPANY, WEBSITE, IO, PROGRAMMABLE,
BUTTON, HAT, THROTTLE, RUDDER, PRICE, PICTURE)>
<!ELEMENT NAME (#PCDATA)>
<!ELEMENT ID (#PCDATA)>
<!ELEMENT COMPANY (#PCDATA)>
<!ELEMENT WEBSITE (#PCDATA)>
<!ELEMENT IO (#PCDATA)>
<!ELEMENT PROGRAMMABLE (#PCDATA)>
<!ELEMENT BUTTON (#PCDATA)>
<!ELEMENT HAT (#PCDATA)>
<!ELEMENT THROTTLE (#PCDATA)>
<!ELEMENT RUDDER (#PCDATA)>
<!ELEMENT PRICE (#PCDATA)>
<!ELEMENT PICTURE (#PCDATA)>
<!ATTLIST PICTURE SOURCE CDATA #REQUIRED>

catalog.xml
<?xml version="1.0" ?>
<PRODUCTS>
<ITEM>
<NAME>Saitek X36 Flight Controller</NAME>
<ID>SAITEK-X36</ID>
<COMPANY> Saitek </COMPANY>
<WEBSITE>http://www.saitek.com/</WEBSITE>
<IO>USB</IO>
<PROGAMMABLE>Yes</PROGAMMABLE>
280

<BUTTON>7</BUTTON>
<HAT>3</HAT>
<THROTTLE>Yes</THROTTLE>
<RUDDER>Yes</RUDDER>
<PRICE>3200</PRICE>
<PICTURE SOURCE="Saitek_X36.gif"/>
</ITEM>
<ITEM>
<NAME>F-16 CombatStick(R) USB</NAME>
<ID>CH-F16-CS-USB</ID>
<COMPANY>CH Products</COMPANY>
<WEBSITE>http://www.chproducts.com</WEBSITE>
<IO>USB</IO>
<PROGAMMABLE>Yes</PROGAMMABLE>
<BUTTON>6</BUTTON>
<HAT>2</HAT>
<THROTTLE>Yes</THROTTLE>
<RUDDER>No</RUDDER>
<PRICE>2600</PRICE>
<PICTURE SOURCE="CH_F16CS2000.gif"/>
</ITEM>
<ITEM>
<NAME>SFS Flight Controller USB</NAME>
<ID>SFS-FC-USB</ID>
<COMPANY>Suncom Inc.</COMPANY>
<WEBSITE>http://www.suncominc.com</WEBSITE>
<IO>USB</IO>
<PROGAMMABLE>Yes</PROGAMMABLE>
<BUTTON>5</BUTTON>
<HAT>1</HAT>
<THROTTLE>No</THROTTLE>
<RUDDER>No</RUDDER>
<PRICE>3100</PRICE>
<PICTURE

SOURCE="Suncom_SFSFC_USB.jpg"/>

</ITEM>
</PRODUCTS>

warehouse

1. MySQL client root MySQL server


281

mysql -u root
MySQL
mysql>
2.
mysql> create database warehouse;
warehouse

warehouse growbal javaxml


mysql> GRANT ALL PRIVILEGES ON warehouse.*
TO growbal@localhost
IDENTIFIED BY 'javaxml';
username password MySQL warehouse

membership stock customorder


customorderitem
tablemembershipusernamepasswordaddress
tel1

create table membership (


username char(20),
password char(20),
address
tel1

char(60),
char(20)

);
insert into membership
(username, password, address, tel1) values
('arthur','tseng',' 50 10 ','2311-8765');
insert into membership
(username, password, address, tel1) values
('emily','huang',' 50 10 ','2311-8765');
insert into membership
(username, password, address, tel1) values
('growbal','javaxml',' 50 10 ','2311-8765');
282

stockidqty
create table stock (
id char(20),
qty int
);
insert into stock (id, qty)

values ('SAITEK-X36', 123);

insert into stock (id, qty) values ('CH-F16-CS-USB', 456);


insert into stock (id, qty)

values ('SFS-FC-USB', 789);

tablecustomordernameaddressorderno
table primary key
create table customorder (
name char(20),
address char(60),
orderno char(12) primary key
);
tablecustomorderitemidqty
orderno
create table customorderitem (
id char(20),
qty int,
orderno char(12)
);

login.jsp
HTML
username1 password1 loginauth.jsp
<HTML>
<HEAD><TITLE>Growbal's SimFan </TITLE>
</HEAD>
<BODY bgcolor="black">
<table WIDTH="100%" COLS="1">
<tr bgcolor="red"><td valign="buttom" align="center">
<font size="3" color="white">Growbal's SimFan </font><br>
<font size="6" color="white"></font>
</td></tr><table>
<form method=post action=loginauth.jsp>
<table width="100%">
<tr><td align="center"><font size="3" color="white">
: </font>
<INPUT TYPE=text SIZE=20 MAXLENGTH=20 NAME='username1'>
283

</td></tr>
<tr><td align="center"><font size="3" color="white">
: </font>
<INPUT TYPE=password SIZE=20 MAXLENGTH=20 NAME='password1'>
</td></tr>
<tr><td align="center">
<INPUT TYPE=submit NAME="loginsubmit" VALUE="">
</td></tr>
</table>
</form>
</body>
</html>

loginauth.jsp
JSP b2b2c.LoginAuthBean
<%@ page language="java" import="java.util.*,b2b2c.*" %>
<jsp:useBean id="loginauth"

class="b2b2c.LoginAuthBean"

scope="session" />
<%
// login.jsp username1 password1
loginauth.processRequest(request);
if (loginauth.checkPassword()) {
//
// Java Bean session
session.setAttribute("loginb", loginauth);
//
response.sendRedirect("catalog.jsp");
}
else // ,
response.sendRedirect("login.jsp");
%>

LoginAuthBean.java
Java Bean
method
package b2b2c;
import java.util.Hashtable;
import java.util.Enumeration;

import java.io.*;
284

import java.net.*;
import java.sql.*;
import javax.servlet.*;
import javax.servlet.http.*;
/**
*
*

B2B2C Demo

*
*

Author: Growbal Kuo

*/
public class LoginAuthBean {
Hashtable params=new Hashtable();
//... JDBC ....
private Connection con;
private PreparedStatement pstmt_select_password;
//.....
String password, address, tel1;
// constructor
public LoginAuthBean() {
// SQL
createConnection();
password = null;
address = null;
tel1 = null;
System.out.println("start LoginAuthBean.");
}

/*
// for debug
public static void main(String args[]) {
//CatalogBean catalog = new CatalogBean();
285

LoginAuthBean loginauth = new LoginAuthBean();


}
*/

public void processRequest(HttpServletRequest req) {


Enumeration en = req.getParameterNames();
while (en.hasMoreElements()) {
String varName = (String)en.nextElement();
String[] varValues = req.getParameterValues(varName);
if (varValues.length > 1) {
params.put(varName, varValues);
}
else {
params.put(varName, varValues[0]);
System.out.println("req:"+varName+"="+varValues[0]);
}
}
}
public String getParam(String key) {
return (String)params.get(key);
}
public void setParam(String key, String value) {
if (params.containsKey(key))
params.put(key, value);
else
System.out.println("no such key:"+key+" in param Hashtable");
}
public String[] getParamArr(String key) {
return (String[])params.get(key);
}
286

//................
public String getUsername() {return getParam("username1"); }
public String getAddress() {return address; }
public String getTel1() {return tel1; }
//.... JDBC ......
public boolean checkPassword() {
return checkPassword (getParam("username1"), getParam("password1"));
}

public boolean checkPassword(String uname, String pword) {


boolean ret = false;
System.out.println("checkPassword: name="+uname+",pw="+pword);
try {
//String password;
// SQL table membership
pstmt_select_password.setString(1, uname);
ResultSet rs = pstmt_select_password.executeQuery();
if (rs.next()) {
password = rs.getString(1);
address = rs.getString(2);
tel1 = rs.getString(3);
System.out.println("pw(input)="+pword+",
(db)="+password);
System.out.println("address="+address+",
tel1="+tel1);
//
if (password.equals(pword)) {
ret = true;
}
else {
ret = false;
System.out.println("password error");
}
}
else
287

{
System.out.println("No such username");
ret = false;
}
rs.close();
} catch (SQLException ex) {
System.out.println(ex.toString());
}
catch (Exception ex) {
System.out.println(ex.toString());
}
return ret;
}

public void createConnection() {


try {
Class.forName("org.gjt.mm.mysql.Driver").newInstance();
}
catch (Exception E) {
System.err.println("Unable to load driver.");
E.printStackTrace();
}

try {
con = DriverManager.getConnection("jdbc:mysql://
localhost/warehouse?user=growbal&password=javaxml");
pstmt_select_password = con.prepareStatement("select
password,address,tel1 from membership where username=?");

288

} catch (SQLException ex) {


System.out.println(ex.toString());
}
catch (Exception ex) {
System.out.println(ex.toString());
}

//
public void close() {
//.... close database .....
try {
pstmt_select_password.close();
con.close();
} catch (SQLException ex) {
System.out.println(ex.toString());
}
catch (Exception ex) {
System.out.println(ex.toString());
}
}

catalog.jsp

<HTML>
<HEAD><TITLE>Growbal's SimFan </TITLE>
</HEAD>
<BODY bgcolor="black">
<table WIDTH="100%" COLS="1">
289

<tr bgcolor="red"><td valign="buttom" align="center">


<font size="3" color="white">Growbal's SimFan </font><br>
<font size="6" color="white"></font>
</td></tr><table>
JSP
<jsp:useBean ....... >
b2b2c.CatalogBean
<jsp:setProperty ......> Java Bean xmldoc XML URL
http://localhost:8080/b2b2c/xml/catalog.xml
<%@ page language="java" import="java.util.*,b2b2c.*" %>
<jsp:useBean id="catalogbean"

class="b2b2c.CatalogBean"

scope="session" />
<jsp:setProperty name="catalogbean" property="xmldoc"
value="http://localhost:8080/b2b2c/xml/catalog.xml"/>
session Java BeanLoginAuthBean LoginAuthBean login.jsp
catalog.jsp login.jsp
CatalogBean XML
CatalogBean session JSP Bean
<%!
LoginAuthBean loginbean;
%>
<%
if (session.getValue("loginb") == null)
response.sendRedirect("login.jsp");
else {
loginbean = (LoginAuthBean)session.getValue("loginb");
}
catalogbean.startParse();
session.setAttribute("catalogb", catalogbean);
%>

CatalogBean XML CatalogBean method


getItems(index) Item Item
Item getItemname()
getPrice()
getPicture()
cart.jsp
290

<form name=catalogForm method="POST" action="cart.jsp">


<table width="100%">
<tr bgcolor="rosybrown">
<td></td><td></td><td></td><td></td>
</tr>
<%!
int catalogSize;
int i;
Item item;String curColor, color1, color2;
%>
<%
color1 = "silver";
color2 = "lightsteelblue";
curColor = color1;
catalogSize = catalogbean.getCatalogSize();
for (i=0; i<catalogSize; i++) {
item = catalogbean.getItem(i);
if (item!=null) {
%>
<tr bgcolor=<%=curColor%>>
<td align="center"><%=item.getItemname()%></td>
<td><IMG SRC=/b2b2c/images/<%=item.getPicture()%> ></td>
<td><%=item.getPrice()%></td>
<td><input type='TEXT' name=qty_<%=i%> size=5 ></td>
</tr>
<%
if (curColor.equals(color1)) curColor = color2;
else if (curColor.equals(color2)) curColor = color1;
}
else {
%>
ERROR: get NULL item!!!<br>
<%
}
}
%>
<tr bgcolor="lightgrey">
291

<td></td><td></td><td></td>
<td><input type="submit"

name="submit" value="">

</td>
</tr>
</table>
</form>
</body>
</html>

Item.java
XML catalog.xml
package b2b2c;
public class Item {
// ,,,,
String itemname, id, picture, price, qty;
public Item(String itemname,
String id,
String picture,
String price,
String qty )
{
this.itemname = itemname;
this.id = id;
this.picture = picture;
this.price = price;
this.qty = qty;
}
public String getItemname() { return itemname; }
public String getId() { return id; }
public String getPicture() {return picture; }
public String getPrice() {return price; }
public String getQty() {return qty; }
public void setQty(String s) {this.qty = s; }
}

CatalogBean.java
catalog.jsp Java Bean XML_Reader XML

package b2b2c;
import java.util.Vector;
292

import java.util.Hashtable;
import java.util.Enumeration;
import java.io.*;
import java.net.*;
import javax.servlet.*;
import javax.servlet.http.*;
public class CatalogBean {
//
Hashtable params=new Hashtable();
// XML_Reader
XML_Reader xr = new XML_Reader();
// jsp xmldoc default_xmldoc XML
String xmldoc="";
String default_xmldoc =
"http://localhost:8080/cart/xml/catalog.xml";
// constructor
public CatalogBean() { System.out.println("start CartBean."); }
// xmldoc method
public void setXmldoc(String s) { xmldoc = s; }
public String getXmldoc() { return xmldoc; }
// XML
// XML_Reader method startParse() XML
// XML_Reader
// XML
public void startParse() {
startParse(false);
}
public void startParse(boolean isValidating) {
if (xmldoc.equals(""))
xmldoc = default_xmldoc;
System.out.println("xmldoc="+xmldoc);
try {
//.... use URL
URL xmlURL = new URL (xmldoc);
xr.startParse(xmlURL.openStream(), isValidating);
293

} catch (MalformedURLException e) {
System.err.println("MalformedURL Exception:"+
e.getMessage());
} catch (IOException e) {
System.out.println(e.toString());
}
}
// , Hashtable
public void processRequest(HttpServletRequest req) {
Enumeration en = req.getParameterNames();
while (en.hasMoreElements()) {
String varName = (String)en.nextElement();
String[] varValues =
req.getParameterValues(varName);
if (varValues.length > 1) {
params.put(varName, varValues);
}
else {
params.put(varName, varValues[0]);
System.out.println("req:"+varName+
"="+varValues[0]);
}
}
}
// Hashtable
public String getParam(String key) {
return (String)params.get(key);
}
// Hashtable
public void setParam(String key, String value) {
if (params.containsKey(key))
params.put(key, value);
else
System.out.println("no such key:"+
key+" in param Hashtable");
294

}
// Hashtable
public String[] getParamArr(String key) {
return (String[])params.get(key);
}
//
// XML XML_Reader
// XML_Reader method getCatalogSize()
public int getCatalogSize() {
return xr.getCatalogSize();
}
//
public Item getItem(int i) {
return xr.getItem(i);
}
//
// Item Vector
public Vector getItems() {
return xr.getItems();
}
}

XML_Reader.java
XML CatalogBean
package b2b2c;
import java.io.*;
import java.lang.*;
import org.xml.sax.Parser;
import org.xml.sax.AttributeList;
import org.xml.sax.InputSource;
import org.xml.sax.HandlerBase;
import org.xml.sax.SAXException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
295

import javax.xml.parsers.FactoryConfigurationError;
import javax.xml.parsers.ParserConfigurationException;
import java.util.*;
// SAX version 1 HandlerBase
public class XML_Reader extends HandlerBase
{
// Item Vector
private Vector items;
// SAX
private String currentElementName;
//
private String itemname,id;
private String price;
private String picture;
private String aname;
private String avalue;

public

XML_Reader() {
items = new Vector();

}
//-------------------------------------------// XML method
public void startParse(InputStreamReader isr)
throws IOException {
if (getCatalogSize() == 0)
startParse(new InputSource( isr ), false);
}
// XML startParse method
public void startParse(InputStream is)
throws IOException {
startParse(new InputStreamReader(is, "Big5"), false);
}
public void startParse(FileReader fr)
throws IOException {
296

startParse(new InputSource( fr ), false);


}
public void startParse(String filename)
throws IOException {
startParse(new FileReader(filename), false );
}
//..............................
public void startParse(InputStreamReader isr, boolean isValidating)
throws IOException {
if (getCatalogSize() == 0)
startParse(new InputSource( isr ), isValidating);
}
// XML startParse method
public void startParse(InputStream is, boolean isValidating)
throws IOException {
startParse(new InputStreamReader(is, "Big5"), isValidating);
}
public void startParse(FileReader fr, boolean isValidating)
throws IOException {
startParse(new InputSource( fr ), isValidating);
}
public void startParse(String filename, boolean isValidating)
throws IOException {
startParse(new FileReader(filename), isValidating );
}
// startParse method method
public void startParse(InputSource in, boolean isValidating)

try {
// JAXP PnP SAX
SAXParserFactory factory =
SAXParserFactory.newInstance();
SAXParser

parser = factory.newSAXParser();

factory.setValidating(isValidating);
factory.setNamespaceAware(false);
parser.parse(in, this);
297

}
catch (SAXException e) {
System.out.println("SAX "+e.getMessage());
}
catch (Exception e) {
System.out.println(""+e.getMessage());
}
}

/*
// for debug.....
public static void main (String args[])
{
boolean isValidating = false;
//....debug....................
String p = System.getProperty("javax.xml.parsers.SAXParserFactory");
System.out.println("parser="+p);
//....................
try {
XML_Reader xr = new XML_Reader();
xr.startParse(args[0]);
}
catch (IOException e) {
System.err.println("IO Exception:"+e.getMessage());
}
catch (Exception e) {
System.err.println("Exception:"+e.toString());
}
}
*/

// Vector item Item


public Item getItem (int index) {
if (index < items.size()) {
// ...debug
System.out.println("Index:"+
new Integer(index).toString());
298

return (Item) items.elementAt(index);


}
else {
// ...debug
//System.out.println("Index > js no.");
}
return (Item) items.elementAt(index);
}
// Vector item Item
public Vector getItems () {
return items;
}
// Vector items ,
public int getCatalogSize() {
int ret;
if (items==null) {ret=-1;}
else {ret = items.size();}
return ret;
}
// SAX ....
public void startElement (String name,
AttributeList atts) {
int i;
currentElementName = name;
if (currentElementName.equals ("PICTURE")) {
for (i = 0; i < atts.getLength(); i++) {
aname = atts.getName(i);
avalue = atts.getValue(i);
//... debug
System.out.println("PICTURE "+aname+":"+avalue);
if (aname.equals ("SOURCE")) {
picture = avalue;
}
}
}
}
299

public void endElement (String name) {


if (name.equals ("ITEM")) {
Item item = new Item(
itemname, id, picture,
price, "0");
items.addElement(item);
//... debug
// System.out.println("new JS was built");
}
}

public void characters (char ch[], int start,


int length) {
String s = new String (ch, start, length);
if (s.trim().length() == 0)
return;
//.. debug
System.out.println("data:"+currentElementName+"("+s+")");
if (currentElementName.equals ("NAME"))
itemname = s;
else if (currentElementName.equals ("ID"))
id = s;
else if (currentElementName.equals ("PRICE"))
price = s;
}
}

cart.jsp

jsp
b2b2c.CartBean
<html><head><TITLE>Growbal's SimFan </TITLE>
</head>
<body bgcolor="gray">
300

<%@ page language="java" session="true"


import="java.util.*,b2b2c.*" %>
<jsp:useBean id="cartbean" class="b2b2c.CartBean" scope="session" />
session CatalogBean LoginAuthBean
CartBean method init()
CartBean processRequest()qty_1, qty_2,...
hashtable
<%!
CatalogBean catalogbean;
LoginAuthBean loginbean;
%>
<%
if (session.getValue("loginb") == null)
response.sendRedirect("login.jsp");
else {
loginbean = (LoginAuthBean)session.getValue("loginb");
catalogbean = (CatalogBean)session.getValue("catalogb");
}
cartbean.init();
cartbean.processRequest(request);
%>
LoginBean getUsername()

<table WIDTH="100%" COLS="1">


<tr bgcolor="red"><td valign="buttom" align="center">
<font size="3" color="white">Growbal's SimFan </font><br>
<font size="6" color="white">
<%=loginbean.getUsername()%>
</font>
</td></tr></table>
<hr>

CatalogBean getCatalogSize()
error1.jsp
CatalogBean getItems() Item Vector items
CartBean addItems() CatalogBean Vector items catalog.jsp
qty_0, qty_1,..... CartBean Vector Item
301

catalog.jsp cart.jsp error2.jsp


catalog.jsp
CartBean checkout.jsp
<form name=cartForm method="POST" action="checkout.jsp">
<table width="100%" >
<tr bgcolor="white">
<td></td><td></td><td></td><td></td>
</tr>
<%!
int i;
int curQty;
Item item;
int sum;
int curPrice;
String qty;
int catalogSize;
String curColor, color1, color2;
%>
<%
String ErrorMsg;
color1 = "lightblue";
color2 = "thistle";
curColor = color1;
//
catalogSize = catalogbean.getCatalogSize();
String qtyParam;
sum=0;
// error1.jsp
if (catalogSize == 0) {
ErrorMsg = "Error: No item in catalog?!";
response.sendRedirect("error1.jsp?msg="+ErrorMsg);
}
// CartBean CartBean.java
Vector items = catalogbean.getItems();
302

cartbean.addItems(items);

//
int cartSize = cartbean.getCartSize();
// 0
if (cartSize==0) {
ErrorMsg = "No input, try again!";
response.sendRedirect("error2.jsp?msg="+ErrorMsg+"&url=catalog.jsp");
}
//
for (i=0; i<cartSize; i++) {
item = cartbean.getItem(i);
curQty = new Integer(
item.getQty()).intValue();
curPrice = new Integer(
item.getPrice()).intValue();
//
sum += curQty * curPrice;
%>
<tr bgcolor=<%=curColor%>>
<td align="center"><%=item.getItemname()%></td>
<td><IMG SRC=/b2b2c/images/<%=item.getPicture()%>></td>
<td><%=curPrice%></td>
<td><%=curQty%></td>
</tr>
<%
if (curColor.equals(color1)) curColor = color2;
else if (curColor.equals(color2)) curColor = color1;
}
session.setAttribute("cartb", cartbean);
%>
<tr bgcolor="white">
<td></td>
303

<td></td>
<td> : <%=sum%></td>
<td><input type="submit" name="submit" value=""></td>
</tr>
</table>
</form>
</body>
</html>

error1.jsp
cart.jsp
ErrorBean
<%@ page language="java" import="java.util.*,b2b2c.*"
contentType="text/html; charset=Big5"%>
<jsp:useBean id="errbean" class="b2b2c.ErrorBean" scope="request" />
<%
errbean.processRequest(request);
%>
<html><head><TITLE>Growbal's SimFan </TITLE>
</head>
<table WIDTH="100%" COLS="1">
<tr bgcolor="red"><td valign="buttom" align="center">
<font size="3" color="white">Growbal's SimFan </font><br>
<font size="6" color="white">

</font>
</td></tr></table>
<hr>
<h2>
<%=errbean.getParam("msg")%>
</h2>
</body>
</html>

error2.jsp
cart.jsp catalog.jsp
catalog.jsp
304

HTML tag
<META HTTP-EQUIV="Refresh" CONTENT="3;URL=http:
<%=errbean.getParam("url")%>
">
ErrorBean
<%@ page language="java" import="java.util.*,b2b2c.*"
contentType="text/html; charset=Big5"%>
<jsp:useBean id="errbean" class="b2b2c.ErrorBean" scope="request" />
<%
errbean.processRequest(request);
%>
<html><TITLE>Growbal's SimFan </TITLE>
<head>
<META HTTP-EQUIV="Refresh" CONTENT="3;URL=http:
<%=errbean.getParam("url")%>
">
</head>
<table WIDTH="100%" COLS="1">
<tr bgcolor="red"><td valign="buttom" align="center">
<font size="3" color="white">Growbal's SimFan </font><br>
<font size="6" color="white">

</font>
</td></tr></table>
<hr>
<h2>
<%=errbean.getParam("msg")%>
</h2>
</body>
</html>

ErrorBean.java
error1.jsp error2.jsp
package b2b2c;
import java.util.Hashtable;
import java.util.Enumeration;
305

import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
public class ErrorBean {
Hashtable params=new Hashtable();

//----------------------------------public ErrorBean() { System.out.println("start ErrorBean."); }

// , Hashtable
public void processRequest(HttpServletRequest req) {
Enumeration en = req.getParameterNames();
while (en.hasMoreElements()) {
String varName = (String)en.nextElement();
String[] varValues = req.getParameterValues(varName);
if (varValues.length > 1) {
params.put(varName, varValues);
}
else {
params.put(varName, varValues[0]);
System.out.println("req:"+varName+"="+varValues[0]);
}
}
}
public String getParam(String key) {
return (String)params.get(key);
}
public void setParam(String key, String value) {
if (params.containsKey(key))
params.put(key, value);
else
System.out.println("no such key:"+key+" in param Hashtable");
306

}
public String[] getParamArr(String key) {
return (String[])params.get(key);
}

CartBean.java
cart.jsp checkout.jsp
XML
package b2b2c;
import java.util.Hashtable;
import java.util.Vector;
import java.util.Enumeration;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.JDOMException;
import org.jdom.input.SAXBuilder;
import org.jdom.output.XMLOutputter;
import java.io.*;
import java.net.*;
import java.sql.*;
import java.lang.System;
import javax.servlet.*;
import javax.servlet.http.*;
public class CartBean {
Hashtable params=new Hashtable();
Vector items = new Vector();
private static final String DEFAULT_SAX_DRIVER_CLASS =
"org.apache.xerces.parsers.SAXParser";
private String saxDriverClass;
private SAXBuilder builder;
private Document doc;
private Element root;
307

//
private String xmldoc = "/xml/order.xml";
private String orderNo;
//... JDBC ....
private Connection con;
private PreparedStatement pstmt_update_stock_qty;
private PreparedStatement pstmt_select_stock_qty;
private PreparedStatement pstmt_insert_order;
private PreparedStatement pstmt_insert_orderitem;
//----------------------------------public CartBean() { System.out.println("start CartBean."); }

/*

// for debug
public static void main(String args[]) {
CatalogBean catalog = new CatalogBean();
CartBean cart = new CartBean();
catalog.startParse();

cart.addItem( catalog.getItem(1) );
cart.addItem( catalog.getItem(2) );
cart.toXML();
}
*/

// , Hashtable
public void processRequest(HttpServletRequest req) {
Enumeration en = req.getParameterNames();
while (en.hasMoreElements()) {
String varName = (String)en.nextElement();
String[] varValues = req.getParameterValues(varName);
308

if (varValues.length > 1) {
params.put(varName, varValues);
}
else {
params.put(varName, varValues[0]);
System.out.println("req:"+varName+"="+varValues[0]);
}
}
}
public String getParam(String key) {
return (String)params.get(key);
}
public void setParam(String key, String value) {
if (params.containsKey(key))
params.put(key, value);
else
System.out.println("no such key:"+key+" in param Hashtable");
}
public String[] getParamArr(String key) {
return (String[])params.get(key);
}
//...............................................
//.... CartBean
public void init() {
// Cart
items.clear();
}

//
public void addItems(Vector items) {
// items
309

String qtyParamValue;
//int qty;
Item item;
for (int i=0; i<items.size(); i++) {
qtyParamValue = getParam("qty_"+
new Integer(i).toString() );
if (qtyParamValue!=null && !qtyParamValue.equals(""))
{
item= (Item)items.get(i);
item.setQty(qtyParamValue); // String
addItem(item);
}
}
}

// Vector
public void addItem(Item item) {
items.add(item);
// modify warehouse database stock table
if (con == null) {
createConnection();
}
modifyStock(item.getId(), Integer.parseInt(item.getQty()));
System.out.println("item:"+item.getItemname());
}
//
public Vector getItems() {
return items;
}
//
public Item getItem(int index) {
return (Item)items.get(index);
310

}
//
public int getCartSize() {
return items.size();
}
//
public String getOrderno() {
return orderNo;
}
//.... JDBC ......
//
public void modifyStock(String id, int qty) {
try {
int oldQty = 0;
pstmt_select_stock_qty.setString(1, id);
ResultSet rs = pstmt_select_stock_qty.executeQuery();
if (rs.next()) {
oldQty = rs.getInt(1);
System.out.println("old QTY="+oldQty);
}
int newQty = oldQty - qty;
pstmt_update_stock_qty.setInt(1, newQty);
pstmt_update_stock_qty.setString(2, id);
pstmt_update_stock_qty.executeUpdate();
rs.close();
} catch (SQLException ex) {
System.out.println(ex.toString());
}
catch (Exception ex) {
System.out.println(ex.toString());
}
}
//
public void modifyOrder(String name, String address)
311

{
try {
pstmt_insert_order.setString(1, name);
pstmt_insert_order.setString(2, address);
pstmt_insert_order.setString(3, orderNo);
pstmt_insert_order.executeUpdate();

} catch (SQLException ex) {


System.out.println(ex.toString());
}
catch (Exception ex) {
System.out.println(ex.toString());
}
}
//
public void modifyOrderItem(Item item)
{
try {
pstmt_insert_orderitem.setString(1, item.getId());
pstmt_insert_orderitem.setInt(2,
Integer.parseInt(item.getQty()));
pstmt_insert_orderitem.setString(3, orderNo);
pstmt_insert_orderitem.executeUpdate();

} catch (SQLException ex) {


System.out.println(ex.toString());
}
catch (Exception ex) {
System.out.println(ex.toString());
}
}
312

// prepared statement
public void createConnection() {
try {
Class.forName("org.gjt.mm.mysql.Driver").newInstance();
}
catch (Exception E) {
System.err.println("Unable to load driver.");
E.printStackTrace();
}

try {
con = DriverManager.getConnection("jdbc:mysql://
localhost/warehouse?user=growbal&password=javaxml");

pstmt_update_stock_qty = con.prepareStatement("update
stock set qty=? where id=?");
pstmt_select_stock_qty = con.prepareStatement("select
qty from stock where id=?");

pstmt_insert_order =
con.prepareStatement("insert into customorder
(name, address, orderno) values (?,?,?)");
pstmt_insert_orderitem =
con.prepareStatement("insert into customorderitem
(id, qty, orderno) values (?,?,?)");

} catch (SQLException ex) {


System.out.println(ex.toString());
}
catch (Exception ex) {
System.out.println(ex.toString());
313

// XML /xml/order.xml,
public void close()
throws IOException, JDOMException {
doc.setRootElement(root);
startOutputXML(new FileOutputStream(xmldoc));
//.... close database .....
try {
pstmt_update_stock_qty.close();
pstmt_select_stock_qty.close();
con.close();
} catch (SQLException ex) {
System.out.println(ex.toString());
}
catch (Exception ex) {
System.out.println(ex.toString());
}
}
private void startOutputXML(OutputStream out)
throws IOException, JDOMException {
// Create an outputter with default formatting
XMLOutputter outputter = getXMLOutputter();
outputter.output(doc, out);
}

private XMLOutputter getXMLOutputter()


throws IOException, JDOMException {
// Create an outputter with certain encoding
XMLOutputter outputter = new XMLOutputter(" ", true, "Big5");
outputter.setTrimText(true);
outputter.setExpandEmptyElements(true);
return outputter;
314

// XML
private void addToXML(Item item) {
// add one element to XML file
Element curItem =
new Element("item");
Element curItemname = new Element("itemname");
curItemname.addContent(item.getItemname());
Element curId = new Element("id");
curId.addContent(item.getId());
Element curQty = new Element("qty");
curQty.addContent(item.getQty());
curItem.addContent(curItemname);
curItem.addContent(curId);
curItem.addContent(curQty);
root.addContent(curItem);
}

// XML ,
public void toXML(String name, String address) {
this.saxDriverClass = DEFAULT_SAX_DRIVER_CLASS;
builder = new SAXBuilder(saxDriverClass);
Item item;
// build new XML doc
root = new Element("order");
doc = new Document(root);
// add timestamp as order's serial number
Element elemOrderNo = new Element("orderno");
orderNo = String.valueOf( java.lang.System.currentTimeMillis() );
elemOrderNo.addContent( orderNo );
root.addContent(elemOrderNo);
//System.out.println("add elements to root");
for (int i=0; i<getCartSize(); i++) {
315

item = (Item)getItem(i);
System.out.println("add one item: "+item.getItemname());
// save to XML file
addToXML(item);
// modify customorderitem table
modifyOrderItem(item);
}
//..... modify customorder table
modifyOrder(name, address);

//System.out.println("add ok!");
try {
close();
} catch (JDOMException e) {
System.out.println(e.toString());
} catch (IOException e) {
System.out.println(e.toString());
}
}
}

checkout.jsp
cart.jsp
CartBean XML server /xml/order.xml tablestock
customorder customorderitem
CartBean getOrderno()
B2C
<html>
<%@ page language="java" session="true" import="java.util.*,b2b2c.*" %>
<BODY bgcolor="lightgrey">
<table WIDTH="100%" COLS="1">
<tr bgcolor="red"><td valign="buttom" align="center">
<font size="3" color="white">Growbal's SimFan </font><br>
<font size="6" color="white"></font>
</td></tr><table>
<%!
CartBean cartbean;
LoginAuthBean loginbean;
316

%>

<%
if (session.getValue("loginb") == null)
response.sendRedirect("login.jsp");
else {
loginbean = (LoginAuthBean)session.getValue("loginb");
cartbean = (CartBean)session.getValue("cartb");
cartbean.toXML(loginbean.getUsername(), loginbean.getAddress());
}
%>

<hr>
<table width="100%">
<tr><td align="center"><font color="BLACK" size="4">
Dear <%=loginbean.getUsername()%>, <br>
<%=cartbean.getOrderno()%><br>
<br>

</font>
</td></tr>
</table>
</body>
</html>

XML
CartBean toXML() XML /xml/order.xml

<?xml version="1.0" encoding="Big5"?>


<order>
<orderno>980181772210</orderno>
<item>
<itemname>Saitek X36 Flight Controller</itemname>
<id>SAITEK-X36</id>
<qty>1</qty>
</item>
<item>
<itemname>SFS Flight Controller USB</itemname>
317

<id>SFS-FC-USB</id>
<qty>3</qty>
</item>
</order>

5.7 Web Service


Web Service
deliver.com Web Service

deliver.com CheckOrder.java
SOAP service RPC
public String checkOrderStatus(String orderNo)

import java.util.*;
import org.apache.soap.util.xml.*;
import org.apache.soap.encoding.soapenc.*;
/**
* SOAP service
*
* @author Growbal Kuo
*/
public class CheckOrder
318

{
public CheckOrder() {
System.out.println("Start of CheckOrder Service V.1.0");
}
// SOAP-RPC ,
//
// , base64 , SOAP
//
public String checkOrderStatus(String orderNo)
throws IllegalArgumentException
{
String ret;
if (orderNo == null)
{
throw new IllegalArgumentException
("Argument 'name' must not be null.");
}
System.out.println("order no:"+orderNo);
ret = processCheckOrderStatus();
// Base64
ret = new Base64().encode(ret.getBytes());
return ret;
}

//
//
//
public String processCheckOrderStatus() {
double r = java.lang.Math.random();
String ret;
if (r < 0.25)
ret = "";
else if (r >=0.25 && r < 0.5)
319

ret = "";
else if (r >=0.5 && r < 0.75)
ret = "";
else
ret = "";
//System.out.println("processCheckOrderStatus(): ret="+ret);
// ret = new Base64().encode(ret.getBytes());
//System.out.println("processCheckOrderStatus(): ret(base64)="+ret);
return ret;
}
}

growbal-SimFan.com
growbal-SimFan.com deliver.com Web Service

JSP HTML HTML

checkorder.jsp
processcheckorder.jsp
<HTML>
<HEAD><TITLE>Growbal's SimFan </TITLE>
</HEAD>
<BODY bgcolor="lightgrey">
<table WIDTH="100%" COLS="1">
<tr bgcolor="green"><td valign="buttom" align="center">
<font size="3" color="white">Growbal's SimFan </font><br>
<font size="6" color="white"></font>
</td></tr><table>
<form method=post action=processcheckorder.jsp>
<table width="100%">
<tr><td align="center"><font size="3" color="black">
</font>
<INPUT TYPE=text SIZE=20 MAXLENGTH=20 NAME='ordernum'>
</td></tr>
<tr><td align="center">
<INPUT TYPE=submit NAME="loginsubmit" VALUE="">
</td></tr>
</table>
</form>
</body>
</html>
320

processcheckorder.jsp
jsp CheckOrderBean
jsp
contentType="text/html; charset=Big5"
JSP
<%=ChineseStringVariable %>
<%=MethodReturnChinese() %>
CheckOrderBean method getOrdercond() CheckOrderClien method getResult()
SOAP RPC CheckOrder Web Service Web Service
processcheckorder.jsp
CheckOrderBean method getOrderitems() SQL customorderitem
processcheckorder.jsp
<%@ page language="java" import="java.util.*,b2b2c.*"
contentType="text/html; charset=Big5"%>
<jsp:useBean id="chkorder" class="b2b2c.CheckOrderBean"
scope="session" />
<%
chkorder.processRequest(request);
chkorder.initAll("http://localhost:8080/servlet/rpcrouter");
if ( ! chkorder.checkOrderNo() )
// ,
response.sendRedirect("checkorder.jsp");
%>
<html>
<META content='text/html; charset=Big5' http-equiv=Content-Type>
<BODY bgcolor="lightgrey">
<table WIDTH="100%" COLS="1">
<tr bgcolor="green"><td valign="buttom" align="center">
<font size="3" color="white">Growbal's SimFan </font><br>
<font size="6" color="white"></font>
</td></tr></table>
<font size="4">Dear <%=chkorder.getUsername()%>,<br><br>
<li><font color=blue><%=chkorder.getOrderno()%></font>
<br><br>
321

<li></font>
<table border=1>
<tr><td></td><td></td></tr>
<%

Vector items = chkorder.getOrderitems();


OrderItem item;
for (int i=0; i<items.size(); i++) {
item = (OrderItem)items.get(i);

%>
<tr><td><%=item.getId() %></td>
<td><%=item.getQty() %></td></tr>
<%
}
%>
</table><br>
<font size="4"><li><font color=blue><%=chkorder.
getOrdercond()%></font><br>
<br>
</font>
</body>
</html>

CheckOrderBean.java
Java checkorder.jsp
SOAP client
package b2b2c;
import java.util.Hashtable;
import java.util.Enumeration;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.JDOMException;
import org.jdom.input.SAXBuilder;
import org.jdom.output.XMLOutputter;
import java.io.*;
import java.net.*;
import java.sql.*;
import java.util.Vector;
import java.lang.System;
322

import javax.servlet.*;
import javax.servlet.http.*;
public class CheckOrderBean {
// Hashtable
Hashtable params=new Hashtable();
private String username;
// SOAP client
CheckOrderClient checker;
//... JDBC ....
private Connection con;
private PreparedStatement pstmt_select_order;
private PreparedStatement pstmt_select_orderitem;
//----------------------------------public CheckOrderBean() { System.out.println("start CheckOrderBean.");
}
//
public void initAll(String RPCRouter) {
// SOAP client, RPCRouter URL SOAP client
try {
checker = new CheckOrderClient(RPCRouter);
} catch (MalformedURLException e) {
System.out.println(e.toString());
}
// , SQL
createConnection();
// set init value

this.username = null;
}

323

//...
public void processRequest(HttpServletRequest req) {
Enumeration en = req.getParameterNames();
while (en.hasMoreElements()) {
String varName = (String)en.nextElement();
String[] varValues = req.getParameterValues(varName);
if (varValues.length > 1) {
params.put(varName, varValues);
}
else {
params.put(varName, varValues[0]);
System.out.println("req:"+varName+"="+varValues[0]);
}
}
}
public String getParam(String key) {
return (String)params.get(key);
}
public void setParam(String key, String value) {
if (params.containsKey(key))
params.put(key, value);
else
System.out.println("no such key:"+key+" in param Hashtable");
}
public String[] getParamArr(String key) {
return (String[])params.get(key);
}
//.... JDBC ......

// JDBC PreparedStatement
public void createConnection() {
324

try {
Class.forName("org.gjt.mm.mysql.Driver").newInstance();
}
catch (Exception E) {
System.err.println("Unable to load driver.");
E.printStackTrace();
}
try {
con = DriverManager.getConnection("jdbc:mysql://
localhost/warehouse?user=growbal&password=javaxml");
pstmt_select_order = con.prepareStatement("select name
from customorder where orderno=?");
pstmt_select_orderitem = con.prepareStatement("select
id,qty from customorderitem where orderno=?");

} catch (SQLException ex) {


System.out.println(ex.toString());
}
catch (Exception ex) {
System.out.println(ex.toString());
}

public void close()


throws IOException {
//.... close database .....
try {
pstmt_select_order.close();
con.close();
325

} catch (SQLException ex) {


System.out.println(ex.toString());
}
catch (Exception ex) {
System.out.println(ex.toString());
}
}
//..........................................................
//
public String getUsernameFromDB() {
String name=null;
try {
pstmt_select_order.setString(1, getParam("ordernum"));
ResultSet rs = pstmt_select_order.executeQuery();
if (rs != null) {
rs.next();
name = rs.getString(1);
this.username = name;
rs.close();
}
} catch (SQLException ex) {
System.out.println(ex.toString());
}
catch (Exception ex) {
System.out.println("getUsernameFromDB():"+ex.toString());
}

return name;
}
//
public boolean checkOrderNo() {
boolean ret=false;;
if (this.username ==null) {
if (getUsernameFromDB()!=null) {
326

System.out.println("get name from db");


ret = true;
}
else
System.out.println("no name in db");
}
else ret = true;
return ret;
}
// customorderitem SQL
// Item Vector
public Vector getOrderitems() {
Vector items = new Vector();
String id;
int qty;
try {
// prepared statement
// ordernum
pstmt_select_orderitem.setString(1,
ResultSet rs = pstmt_select_orderitem.executeQuery();
if (rs != null) {
while ( rs.next() ) {
id = rs.getString(1);
qty = rs.getInt(2);
items.add( new OrderItem(id, qty) );
}
rs.close();
}
} catch (SQLException ex) {
System.out.println(ex.toString());
}
catch (Exception ex) {
System.out.println("getUsernameFromDB():"+ex.toString());
327

}
return items;
}
//
public String getUsername() {
return username;
}
//
public String getOrderno() {
return ( getParam("ordernum") );
}
// SOAP Client , SOAP RPC
public String getOrdercond() {
String ret =
checker.getResult("checkOrderStatus",
getParam("ordernum") );
//System.out.println("getOrdercond(): ret="+ret);
return ret;
}

}
//=======================================

CheckOrderClient.java
SOAP Client
package b2b2c;
import java.io.*;
import java.util.*;
import java.net.*;
import org.apache.soap.util.xml.*;
import org.apache.soap.*;
import org.apache.soap.encoding.*;
import org.apache.soap.encoding.soapenc.*;
import org.apache.soap.rpc.*;
328

import org.apache.soap.transport.http.*;
/**
* SOAP Client of CheckOrder
*
* @author Growbal Kuo
* @email growbal@taiwan.com
*/
public class CheckOrderClient
{
private String result = null;
private URL url; // RPCRouter URL
private Call call;
// arg RPCRouter URL
public CheckOrderClient(String arg) throws
MalformedURLException
{
url = new URL(arg);
}
private void start(String method) {
String encodingStyleURI =
Constants.NS_URI_SOAP_ENC;

// Build the call.


call = new Call();
call.setTargetObjectURI("urn:CheckOrder");
call.setMethodName(method);
call.setEncodingStyleURI(encodingStyleURI);
}

// SOAP
329

private void setParameters(String orderNo) {


Vector params = new Vector();
//String name1 = new Base64().encode(name.getBytes());
// SOAP Vector
params.addElement(new Parameter("orderno",
String.class,
orderNo, null));
// Vector SOAP
call.setParams(params);
}

// SOAP RPC, result


private void execRPC() {
// start RPC
Response resp;
Object value;
try
{
System.out.println("CALL: "+call.toString());
// SOAP ,RPCRouter URL url
// resp SOAP Response
resp = call.invoke(url, "");
}
catch (SOAPException e)
{
System.err.println
("Caught SOAPException ("+
e.getFaultCode() + "): " +
e.getMessage());
return;
}
catch (Exception e) {
System.out.println(e.toString());
return;
}
330

// SOAP resp
if (!resp.generatedFault()) // resp
{
System.out.println("RPC response:"+
resp.toString());
// SOAP Response ,
// Parameter Parameter.getValue()
Parameter ret = resp.getReturnValue();
if (ret == null) {
System.out.println
("null result value");
return;
}
else {
value = ret.getValue();
}
if (value != null) {
result = value.toString();
System.out.println
("result:"+result+"\n");
}
else {
System.out.println
("null result value");
}
}
else // SOAP
{
Fault fault = resp.getFault();
System.err.println("Generated fault: ");
System.out.println (" Fault Code

="+

fault.getFaultCode());
System.out.println (" Fault String = " +
fault.getFaultString());
}
}
331

// SOAP RPC ,,SOAP service


// base64 ,
// base64 ,.
public String getResult(String method, String orderNo) {
try {
start(method);
setParameters(orderNo);
execRPC();
} catch (Exception e) {
System.out.println(e.toString());
}
//System.out.println("getResult(): result="+result);
result = new String( new Base64().decode(result) );
//System.out.println("getResult(): result(base64 decode)="+result);
return result;
}
}

XSL-HTML growbal-SimFan.com

XSL XSL XML

Clark's XT XSLT 4 Big5XSLServlet

checkorder2.jsp
processcheckorder2.jsp
<HTML>
<HEAD><TITLE>Growbal's SimFan </TITLE>
</HEAD>
332

<BODY bgcolor="lightgrey">
<table WIDTH="100%" COLS="1">
<tr bgcolor="green"><td valign="buttom" align="center">
<font size="3" color="white">Growbal's SimFan </font><br>
<font size="6" color="white"></font>
</td></tr><table>
<form method=post action=processcheckorder2.jsp>
<table width="100%">
<tr><td align="center"><font size="3" color="black">
</font>
<INPUT TYPE=text SIZE=20 MAXLENGTH=20 NAME='ordernum'>
</td></tr>
<tr><td align="center">
<INPUT TYPE=submit NAME="loginsubmit" VALUE="">
</td></tr>
</table>
</form>
</body>
</html>

processcheckorder2.jsp
Server XML CheckOrderBean2
method toXML() Servlet URL XSLT
<%@ page language="java" import="java.util.*,b2b2c.*" %>
<jsp:useBean id="chkorder2" class="b2b2c.CheckOrderBean2"
scope="session" />
<%
//
//
//
chkorder2.processRequest(request);
//
//

b2b2c.CheckOrderBean2.initAll():

//

SOAP RPC Router URL

//

Server XML
333

//
chkorder2.initAll("http://localhost:8080/servlet/rpcrouter",
"/jakarta-tomcat/Webapps/b2b2c/xsl/");
//
//
if ( ! chkorder2.checkOrderNo() )
// ,
response.sendRedirect("checkorder2.jsp");
else {
// , XML
chkorder2.toXML();
// XML XSL
response.sendRedirect("http://localhost:8080/checkorder/b2b2c/xsl/
"+chkorder2.getXmlfilename());
}
%>

CheckOrderBean2.java
CheckOrderBean XML
package b2b2c;
import java.util.Hashtable;
import java.util.Enumeration;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.JDOMException;
import org.jdom.input.SAXBuilder;
import org.jdom.output.XMLOutputter;
import java.io.*;
import java.net.*;
import java.sql.*;
import java.util.Vector;
import java.lang.System;
import javax.servlet.*;
import javax.servlet.http.*;
334

public class CheckOrderBean2 {


// Hashtable
Hashtable params=new Hashtable();
// XML
private static final String DEFAULT_SAX_DRIVER_CLASS =
"org.apache.xerces.parsers.SAXParser";
private String saxDriverClass;
private SAXBuilder builder;
private Document doc;
private Element root;
// , xmlpath server
// XML ,
// xmldoc
private String xmlpath;
private String xmldoc;
private String username;
private String orderNo;
// SOAP client
CheckOrderClient checker;
//... JDBC ....
private Connection con;
private PreparedStatement pstmt_select_order;
private PreparedStatement pstmt_select_orderitem;
//----------------------------------public CheckOrderBean2() { System.out.println("start CheckOrderBean.");
}
//
public void initAll(String RPCRouter,
String XmlPath) {
// server
335

// XML
this.xmlpath = XmlPath;
// SOAP client, RPCRouter URL SOAP client
try {
checker = new CheckOrderClient(RPCRouter);
} catch (MalformedURLException e) {
System.out.println(e.toString());
}
// , SQL
createConnection();
// init value
this.username = null;
}

//
public void processRequest(HttpServletRequest req) {
Enumeration en = req.getParameterNames();
while (en.hasMoreElements()) {
String varName = (String)en.nextElement();
String[] varValues = req.getParameterValues(varName);
if (varValues.length > 1) {
params.put(varName, varValues);
}
else {
params.put(varName, varValues[0]);
System.out.println("req:"+varName+"="+varValues[0]);
}
}
}
public String getParam(String key) {
return (String)params.get(key);
}
336

public void setParam(String key, String value) {


if (params.containsKey(key))
params.put(key, value);
else
System.out.println("no such key:"+key+" in param Hashtable");
}
public String[] getParamArr(String key) {
return (String[])params.get(key);
}
//.... JDBC ......

// JDBC PreparedStatement
public void createConnection() {
try {
Class.forName("org.gjt.mm.mysql.Driver").newInstance();
}
catch (Exception E) {
System.err.println("Unable to load driver.");
E.printStackTrace();
}
try {
con = DriverManager.getConnection("jdbc:mysql://
localhost/warehouse?user=growbal&password=javaxml");
pstmt_select_order = con.prepareStatement("select
name from customorder where orderno=?");
pstmt_select_orderitem = con.prepareStatement("select
id,qty from customorderitem where orderno=?");

} catch (SQLException ex) {


System.out.println(ex.toString());
}
catch (Exception ex) {
337

System.out.println(ex.toString());
}

}
// XML
public String getXmlfilename() {
return getOrderno()+".xml";
}

// XML ,
public void close()
throws IOException, JDOMException {
doc.setRootElement(root);
xmldoc = xmlpath + getXmlfilename();
System.out.println("xmldoc="+xmldoc);
startOutputXML(new FileOutputStream(xmldoc));
//.... close database .....
try {
pstmt_select_order.close();
con.close();
} catch (SQLException ex) {
System.out.println(ex.toString());
}
catch (Exception ex) {
System.out.println(ex.toString());
}
}
//..........................................................
//
public String getUsernameFromDB() {
338

String name=null;
try {
pstmt_select_order.setString(1, getParam("ordernum"));
ResultSet rs = pstmt_select_order.executeQuery();
if (rs != null) {
rs.next();
name = rs.getString(1);
this.username = name;
rs.close();
}
} catch (SQLException ex) {
System.out.println(ex.toString());
}
catch (Exception ex) {
System.out.println("getUsernameFromDB():"+ex.toString());
}

return name;
}
//
public boolean checkOrderNo() {
boolean ret=false;;
if (this.username ==null) {
if (getUsernameFromDB()!=null) {
System.out.println("get name from db");
ret = true;
}
else
System.out.println("no name in db");
}
else ret = true;
return ret;
}
//
339

public Vector getOrderitems() {


Vector items = new Vector();
String id;
int qty;
try {
pstmt_select_orderitem.setString(1,
getParam("ordernum"));
ResultSet rs = pstmt_select_orderitem.executeQuery();
if (rs != null) {
while ( rs.next() ) {
id = rs.getString(1);
qty = rs.getInt(2);
items.add( new OrderItem(id, qty) );
}
rs.close();
}
} catch (SQLException ex) {
System.out.println(ex.toString());
}
catch (Exception ex) {
System.out.println("getUsernameFromDB():"+ex.toString());
}
return items;
}
//
public String getUsername() {
return username;
}
//
public String getOrderno() {
return ( getParam("ordernum") );
340

}
// SOAP Client , SOAP RPC
public String getOrdercond() {
String ret =
checker.getResult("checkOrderStatus",
getParam("ordernum") );
//System.out.println("getOrdercond(): ret="+ret);
return ret;
}

// XML
private void startOutputXML(OutputStream out)
throws IOException, JDOMException {
XMLOutputter outputter = getXMLOutputter();
outputter.output(doc, out);
}

private XMLOutputter getXMLOutputter()


throws IOException, JDOMException {
// Big5 XMLOutputter
XMLOutputter outputter = new XMLOutputter(" ", true, "Big5");
outputter.setTrimText(true);
outputter.setExpandEmptyElements(true);
return outputter;
}

// XML
private Element addToXML(Element curItems, OrderItem item) {
Element curItem =
341

new Element("orderitem");
Element curId = new Element("id");
curId.addContent(item.getId());
Element curQty = new Element("qty");
curQty.addContent(new Integer(item.getQty()).toString());
curItem.addContent(curId);
curItem.addContent(curQty);
curItems.addContent(curItem);
return curItems;
}

// XML ,
public void toXML() {
this.saxDriverClass = DEFAULT_SAX_DRIVER_CLASS;
builder = new SAXBuilder(saxDriverClass);
Vector items = getOrderitems();
OrderItem item;
// JDOM XML
//
// order
root = new Element("order");
doc = new Document(root);
// name, orderno, orderitems
Element curName =
new Element("name");
curName.addContent( getUsername() );
root.addContent(curName);
Element curOrderno =
new Element("orderno");
342

curOrderno.addContent( getOrderno() );
root.addContent( curOrderno );
Element curItems =
new Element("orderitems");
// orderitems orderitem
for (int i=0; i<items.size(); i++) {
item = (OrderItem)items.get(i);
System.out.println("add one item: "+item.getId());
// OrderItem XML orderitem
curItems = addToXML(curItems, item);
}
root.addContent( curItems );
// XML status
// SOAP
Element curStatus =
new Element("status");
curStatus.addContent( getOrdercond() );
root.addContent( curStatus );

// XML
try {
close();
} catch (JDOMException e) {
System.out.println(e.toString());
} catch (IOException e) {
System.out.println(e.toString());
}
}
}
//=======================================

XML
343

processcheckorder2.jsp CheckOrderBean2.toXML() XML server b2b2c/xsl

<?xml version="1.0" encoding="Big5"?>


<order>
<name>arthur</name>
<orderno>980745289955</orderno>
<orderitems>
<orderitem>
<id>SAITEK-X36</id>
<qty>2</qty>
</orderitem>
<orderitem>
<id>CH-F16-CS-USB</id>
<qty>4</qty>
</orderitem>
<orderitem>
<id>SFS-FC-USB</id>
<qty>5</qty>
</orderitem>
</orderitems>
<status></status>
</order>

checkorder.xsl
XML HTML XSL
<?xml version="1.0" encoding="Big5"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<html>
<head>
<title>Order</title>
</head>
<body bgcolor="lightgrey">
<table WIDTH="100%" COLS="1" border="0">
<tr bgcolor="green"><td valign="buttom" align="center">
<font size="3" color="white">Growbal's SimFan
</font>
<br/>
<font size="6" color="white"></font>
</td></tr></table>
344

<xsl:apply-templates select="order"/>
</body>
</html>
</xsl:template>
<xsl:template match="order">
<xsl:apply-templates select="name"/>
<xsl:apply-templates select="orderno"/>
<xsl:apply-templates select="orderitems"/>
<xsl:apply-templates select="status"/>
</xsl:template>

<xsl:template match="name">
<table border="0"><tr><td>
<font size="4">Dear </font>
<font size="4" color="blue"><xsl:value-of select="/order/name"/>,
</font>
</td></tr></table>
</xsl:template>
<xsl:template match="orderno">
<table border="0"><tr><td>*</td><td>
<font size="4"></font>
<font size="4" color="blue"><xsl:value-of select="/order/orderno"/>
</font>
</td></tr></table>
</xsl:template>
<xsl:template match="orderitems">
<table border="0"><tr><td>*</td><td>
<font size="4"></font>
</td></tr></table>
<table border="1">
<tr><td></td><td></td></tr>
<xsl:apply-templates select="orderitem"/>
</table>
</xsl:template>
345

<xsl:template match="orderitem">
<tr>
<td><font size="4" color="blue"><xsl:value-of select="id"/></font></td>
<td><font size="4" color="blue"><xsl:value-of select="qty"/>
</font></td>
</tr>
</xsl:template>
<xsl:template match="status">
<table border="0"><tr><td>*</td><td>
<font size="4"></font><font size="4" color="blue">
<xsl:value-of select="/order/status"/>
</font>
</td></tr></table>
<font size="4"></font>
</xsl:template>
</xsl:stylesheet>

WML
WAPWAP Wireless
Application Protocol Web
WAP PDA
WAP WebWML HTMLWML Wireless Markup Language
WAP
<?xml version="1.0" encoding="Big5"?>
<!DOCTYPE wml PUBLIC "-//WAPFORUM//DTD WML 1.1//EN" "http://www.
wapforum.org/DTD/wml_1.1.xml">
<wml>
<card title="MyTestPage1" id="mypage1">
<p align='center'>WML </p>
<p align='left'>WML XML<br/>
XML </p>
</card>
<card title="MyTestPage2" id="mypage2">
<p align='center'>WML </p>
<p align='left'> WML<br/>
XML </p>
</card>
</wml>
346

WML XML Well-formed WML


DTD
MIME MIME Multipurpose Internet Mail Extension Web
MIME type
HTML text/html
text/plain
GIF image/gif
JPG image/jpg
WML MIME type text/vnd.wap.wml MIME type WML

WML HTML HTTP server WML


WML HTTP WAP Gateway
WML WTP
WAP Gateway HTML WML HTML
WAP HTML
WAP WML
WAP
WAP http://www.wapforum.org

XSL-WML growbal-SimFan.com
XSL XML WML WAP PDA

XSLT Clark's XT
XT
XT WML

Big5XSLServlet.java
4 Big5XSLServlet WML
import java.io.IOException;
import java.io.File;
347

import java.io.Writer;
import java.io.InputStreamReader;
import java.io.InputStream;
import java.io.FileInputStream;
//import java.net.*;
import java.util.Enumeration;
import javax.servlet.*;
import javax.servlet.http.*;
import org.xml.sax.*;
import com.jclark.xsl.sax.*;
/*
read local xsl and xml files, in virtual path format
call by http://localhost:8080/stockquote/xsl/stockquote
virtual-path
v-path should set in Web.xml
real-path should makedir under app's doc root dir,
such as /jakarta-tomcat/Webapps/ROOT/xsl
don't forget put this class in CLASSPATH of TOMCAT's
startup batch file
*/
/**
*
* Clark's XT com.jclark.xsl.sax.XSLServlet
*
*/
public class Big5XSLServlet extends HttpServlet {
private XSLProcessor cached;
public void init() throws ServletException {
String stylesheet = getInitParameter("stylesheet");
System.out.println("Start of Big5XSLServlet....");
if (stylesheet == null) {
System.out.println("Big5XSLServlet: init() stylesheet=NULL");
throw new ServletException("missing stylesheet parameter");
}
348

real-path

xml-file

cached = new XSLProcessorImpl();


cached.setParser(createParser());
try {
/**
* XSL
*
*/
System.out.println("Big5XSLServlet: init()

begin load

xsl="+stylesheet);
InputStream is = getServletContext().getResourceAsStream
(stylesheet);
System.out.println("Big5XSLServlet: init()

load xsl as

stream ok");
cached.loadStylesheet(new InputSource(
new InputStreamReader(is, "Big5")

));

System.out.println("Big5XSLServlet: init()

load xsl ok");

}
catch (SAXException e) {
System.out.println("Big5XSLServlet: init() SAX ex:"+e.
toString());
}
catch (IOException e) {
System.out.println("Big5XSLServlet: init() IO ex:"+e.
toString());
}
catch (Exception e) {
System.out.println("Big5XSLServlet: init() EX:"+e.toString());
}
}

public void doPost(HttpServletRequest request,


HttpServletResponse response)
throws ServletException, IOException {
System.out.println("Big5XSLServlet: doPost()");
doGet(request, response);
}
349

public void doGet(HttpServletRequest request,


HttpServletResponse response)
throws ServletException, IOException {
System.out.println("Big5XSLServlet: doGet()");
File inputFile = new File(request.getPathTranslated());
if (!inputFile.isFile()) {
inputFile = new File(request.getPathTranslated() + ".xml");
if (!inputFile.isFile()) {
response.sendError(HttpServletResponse.SC_NOT_FOUND,
"File not found: " + request.getPathTranslated());
return;
}
}

XSLProcessor xsl = (XSLProcessor)cached.clone();


xsl.setParser(createParser());
for (Enumeration e = request.getParameterNames();
e.hasMoreElements();) {
String name = (String)e.nextElement();
// What to do about multiple values?
xsl.setParameter(name, request.getParameter(name));
}
/**
* OutputMethodHandlerImpl OutputMethodHandlerImpl2
* XSL + XML WML
*/
OutputMethodHandlerImpl2 outputMethodHandler = new
OutputMethodHandlerImpl2(xsl);
xsl.setOutputMethodHandler(outputMethodHandler);
outputMethodHandler.setDestination(new ServletDestination
(response));
System.out.println("Big5XSLServlet: start XSL Transformation");
try {
xsl.parse(fileInputSource(inputFile));
350

}
catch (SAXException e) {
System.out.println("Big5XSLServlet:

SAX Exception:"+e.toString());

//throw new ServletException(e);


}
}
static Parser createParser() throws ServletException {
String parserClass = System.getProperty("com.jclark.xsl.sax.parser");
if (parserClass == null)
parserClass = System.getProperty("org.xml.sax.parser");
if (parserClass == null)
parserClass = "com.jclark.xml.sax.CommentDriver";
try {
return (Parser)Class.forName(parserClass).newInstance();
}
catch (ClassNotFoundException e) {
throw new ServletException(e);
}
catch (InstantiationException e) {
throw new ServletException(e);
}
catch (IllegalAccessException e) {
throw new ServletException(e);
}
catch (ClassCastException e) {
throw new ServletException(parserClass + " is not a SAX driver");
}
}
/**
* Generates an <code>InputSource</code> from a file name.
*/
static public InputSource fileInputSource(File file) {
String path = file.getAbsolutePath();
String fSep = System.getProperty("file.separator");
InputStreamReader isr = null;
if (fSep != null && fSep.length() == 1)
351

path = path.replace(fSep.charAt(0), '/');


if (path.length() > 0 && path.charAt(0) != '/')
path = '/' + path;
try {
/**
* Big5 InputStreamReader
*/
FileInputStream fis = new FileInputStream(file);
isr = new InputStreamReader(fis,"Big5");
// --- original
// return new InputSource(new URL("file", "", path).toString());
}
catch (IOException e) {
System.out.println("Big5XSLServlet: fileInputSource() IOException:");
System.out.println(e.toString());
}
catch (Exception e) {
System.out.println("Big5XSLServlet: fileInputSource() Exception:");
System.out.println(e.toString());
}
return new InputSource(isr);
}
}

OutputMethodHandlerImpl2.java
OutputMethodHandlerImpl XSLServlet XMLHTML
TEXTXML XMLOutput Handler MIME type application/xml XML
WML XML XMLOutputHandler MIME typetest/vnd.wap.wml
WML
wml XSL <xsl:output method="wml".....>
WMLOutputHandler
import com.jclark.xsl.sax.*;
import org.xml.sax.*;
import java.io.IOException;
/**
352

* com.jclark.xsl.sax.OutputMethodHandlerImpl
* WML
*
* by Growbal
*/
public class OutputMethodHandlerImpl2 implements OutputMethodHandler {
private XSLProcessor processor;
private Destination dest;
public OutputMethodHandlerImpl2(XSLProcessor processor) {
this.processor = processor;
}
public OutputMethodHandler createOutputMethodHandler(String uri) {
Destination d = dest.resolve(uri);
if (d == null)
return null;
OutputMethodHandlerImpl2 om = new OutputMethodHandlerImpl2(processor);
om.setDestination(d);
return om;
}
public void setDestination(Destination dest) {
this.dest = dest;
}
static private final String JAVA_OUTPUT_METHOD = "http://www.
jclark.com/xt/java";
public DocumentHandler createDocumentHandler(String name,
AttributeList atts) throws SAXException, IOException {
DocumentHandler handler = null;
if (name == null)
;
else if (name.startsWith(JAVA_OUTPUT_METHOD)
&& (name.lastIndexOf(namespaceSeparator)
== JAVA_OUTPUT_METHOD.length())) {
try {
Class cls = Class.forName(name.substring(JAVA_OUTPUT_METHOD.
length() + 1));
handler = (DocumentHandler)cls.newInstance();
353

}
catch (ClassNotFoundException e) { }
catch (InstantiationException e) { }
catch (IllegalAccessException e) { }
catch (ClassCastException e) { }
}
else if (name.equals("http://www.jclark.com/xt"
+ namespaceSeparator
+ "nxml"))
handler = new NXMLOutputHandler();
else if (name.equals("html"))
handler = new HTMLOutputHandler();
//<xsl:output method="wml" ....>
//WMLOutputHandler() Clark XMLOutputHandler
//
else if (name.equals("wml")) // modified
handler = new WMLOutputHandler();
else if (name.equals("text"))
handler = new TextOutputHandler();
if (handler == null)
handler = new XMLOutputHandler();
if (handler instanceof OutputDocumentHandler)
handler = ((OutputDocumentHandler)handler).init(dest, atts);
return handler;
}
}

WMLOutputHandler.java
XMLOutputHandler J.Clark
import com.jclark.xsl.sax.*;
import org.xml.sax.*;
import java.io.CharConversionException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.IOException;
/**
* Clark's XT com.jclark.xsl.sax.XMLOutputHandler ,
* XMLOutputHandler OutputStream,
* , WML OutputStreamWriter
*
354

* by Growbal
*/
public class WMLOutputHandler
implements OutputDocumentHandler,
CommentHandler, RawCharactersHandler {
// OutputStreamWriter
private OutputStreamWriter out = null;
private OutputStream outs = null;
private boolean keepOpen;
private boolean inStartTag = false;
private boolean omitXmlDeclaration = false;
private String standalone;
private static final int DEFAULT_BUF_LENGTH = 8*1024;
//
// OutputStream byte ,
// OutputStreamWriter ,
// OutputStreamWriter char ,
// byte byte[] char char[]
//
private char[] buf = new char[DEFAULT_BUF_LENGTH];
private int bufUsed = 0;
private String lineSeparator;
private byte minimize = MINIMIZE_EMPTY_ELEMENTS;
private String doctypeSystem;
private String doctypePublic;
private boolean outputDoctype = false;
static final public byte MINIMIZE_NONE = 0;
static final public byte MINIMIZE_EMPTY_ELEMENTS = 1;
static final public byte MINIMIZE_EMPTY_ELEMENTS_HTML = 2;
public WMLOutputHandler() {
lineSeparator = System.getProperty("line.separator");
}

355

/**
* WMLOutputHandler(OutputStream out),
* OutputStreamWriter
*/
public WMLOutputHandler(OutputStreamWriter out) {
this();
this.out = out;
}
public DocumentHandler init(Destination dest, AttributeList atts)
throws IOException {
// original
//
// this.out = dest.getOutputStream("application/xml", null);
//

MIME type application/xml

//

WML WAP .

//

MIME type , XSL :

//
//<xsl:output method="text"
//

media-type="text/vnd.wap.wml"

//

omit-xml-declaration="no" encoding="Big5"

//

doctype-public="//WAPFORUM//DTD WML 1.1//EN"

//

indent="yes"/>

//
// MINE type "text/vnd.wap.wml"
//
String mediaType = atts.getValue("media-type");
//
// OutputStreamWriter
//
this.out = new OutputStreamWriter(
dest.getOutputStream(mediaType, null),
"Big5");
this.keepOpen = dest.keepOpen();
if ("yes".equals(atts.getValue("omit-xml-declaration")))
omitXmlDeclaration = true;
this.standalone = atts.getValue("standalone");
this.doctypeSystem = atts.getValue("doctype-system");
356

this.doctypePublic = atts.getValue("doctype-public");
if (this.doctypeSystem != null || this.doctypePublic != null)
outputDoctype = true;
if ("yes".equals(atts.getValue("indent")))
return new Indenter(this, this);
return this;
}
public void setMinimize(byte minimize) {
this.minimize = minimize;
}
public void startDocument() throws SAXException {
// XSL omit-xml-declaration="no"
// XML PI
if (!omitXmlDeclaration) {
writeRaw("<?xml version=\"1.0\" encoding=\"Big5\"");
if (standalone != null) {
writeRaw(" standalone=\"");
writeRaw(standalone);
put((char)'"');
}
writeRaw("?>");
writeRaw(lineSeparator);
}
}
public void characters(char cbuf[], int off, int len)
throws SAXException {
if (len == 0)
return;
if (inStartTag)
finishStartTag();
do {
char c = cbuf[off++];
switch (c) {
case '\n':
writeRaw(lineSeparator);
break;
case '&':
357

writeRaw("&");
break;
case '<':
writeRaw("<");
break;
case '>':
writeRaw(">");
break;
default:
put((char)c);
break;
// ASCII ,
// ,
//
/*
if (c < 0x80)
put((char)c);
else {
try {
writeMB(c);
}
catch (CharConversionException e) {
if (len-- == 0)
throw new SAXException(e);
writeSurrogatePair(cbuf[off - 1], cbuf[off]);
off++;
}
} */
}
} while (--len > 0);
}
public void rawCharacters(String chars) throws SAXException {
if (inStartTag)
finishStartTag();
writeRaw(chars);
}
358

public void ignorableWhitespace (char ch[], int start, int length)


throws SAXException {
for (; length > 0; length--, start++)
put((char)ch[start]);
}
private void writeRaw(String str) throws SAXException {
final int n = str.length();
for (int i = 0; i < n; i++) {
char c = str.charAt(i);
put((char)c);
/*
if (c < 0x80)
put((char)c);
else {
try {
writeMB(str.charAt(i));
}
catch (CharConversionException e) {
if (++i == n)
throw new SAXException(e.getMessage());
writeSurrogatePair(c, str.charAt(i));
}
}
*/
}
}
private final void writeMB(char c)
throws SAXException, CharConversionException {
switch (c & 0xF800) {
case 0:
put((char)(((c >> 6) & 0x1F) | 0xC0));
put((char)((c & 0x3F) | 0x80));
break;
default:
put((char)(((c >> 12) & 0xF) | 0xE0));
359

put((char)(((c >> 6) & 0x3F) | 0x80));


put((char)((c & 0x3F) | 0x80));
break;
case 0xD800:
throw new CharConversionException("invalid surrogate pair");
}
}
private final void writeSurrogatePair(char c1, char c2)
throws SAXException {
if ((c1 & 0xFC00) != 0xD800 || (c2 & 0xFC00) != 0xDC00)
throw new SAXException("invalid surrogate pair");
int c = ((c1 & 0x3FF) << 10) | (c2 & 0x3FF);
c += 0x10000;
put((char)(((c >> 18) & 0x7) | 0xF0));
put((char)(((c >> 12) & 0x3F) | 0x80));
put((char)(((c >> 6) & 0x3F) | 0x80));
put((char)((c & 0x3F) | 0x80));
}
public void startElement(String name, AttributeList atts)
throws SAXException {
if (inStartTag)
finishStartTag();
if (outputDoctype) {
outputDoctype = false;
writeRaw("<!DOCTYPE ");
writeRaw(name);
if (doctypePublic != null) {
writeRaw(" PUBLIC ");
char lit = doctypePublic.indexOf('"') >= 0 ? (char)'\'' : (char)'"';
put((char)lit);
writeRaw(doctypePublic);
put((char)lit);
}
else
writeRaw(" SYSTEM");
if (doctypeSystem != null) {
360

char lit = doctypeSystem.indexOf('"') >= 0 ? (char)'\'' : (char)'"';


put((char)' ');
put((char)lit);
writeRaw(doctypeSystem);
put((char)lit);
}
put((char)'>');
writeRaw(lineSeparator);
}
put((char)'<');
writeRaw(name);
int n = atts.getLength();
for (int i = 0; i < n; i++) {
put((char)' ');
writeRaw(atts.getName(i));
put((char)'=');
put((char)'"');
attributeValue(atts.getValue(i));
put((char)'"');
}
inStartTag = true;
}
protected void attributeValue(String value) throws SAXException {
int valueLength = value.length();
for (int j = 0; j < valueLength; j++) {
char c = value.charAt(j);
switch (c) {
case '\n':
writeRaw("&#10;");
break;
case '&':
writeRaw("&amp;");
break;
case '<':
writeRaw("&lt;");
break;
case '"':
writeRaw("&quot;");
break;
361

case '\r':
writeRaw("&#13;");
break;
case '\t':
writeRaw("&#9;");
break;
default:
put((char)c);
/*
if (c < 0x80)
put((char)c);
else {
try {
writeMB(c);
}
catch (CharConversionException e) {
if (++j == valueLength)
throw new SAXException(e.getMessage());
writeSurrogatePair(value.charAt(j - 1), value.charAt(j));
}
}
*/
break;
}
}
}
private final void finishStartTag() throws SAXException {
inStartTag = false;
put((char)'>');
}
public void endElement(String name) throws SAXException {
if (inStartTag) {
inStartTag = false;
if (minimize != MINIMIZE_NONE) {
if (minimize == MINIMIZE_EMPTY_ELEMENTS_HTML)
put((char)' ');
put((char)'/');
362

put((char)'>');
return;
}
put((char)'>');
}
put((char)'<');
put((char)'/');
writeRaw(name);
put((char)'>');
}
public void processingInstruction(String target, String data)
throws SAXException {
if (target == null) {
comment(data);
return;
}
if (inStartTag)
finishStartTag();
put((char)'<');
put((char)'?');
writeRaw(target);
if (data.length() > 0) {
put((char)' ');
writeMarkup(data);
}
put((char)'?');
put((char)'>');
}
public void markup(String chars) throws SAXException {
if (inStartTag)
finishStartTag();
writeMarkup(chars);
}
public void comment(String body) throws SAXException {
if (inStartTag)
finishStartTag();
writeRaw("<!--");
363

writeMarkup(body);
writeRaw("-->");
}
private void writeMarkup(String str) throws SAXException {
int len = str.length();
for (int i = 0; i < len; i++) {
char c = str.charAt(i);
if (c == '\n')
writeRaw(lineSeparator);
else if (c < 0x80)
put((char)c);
else {
try {
writeMB(c);
}
catch (CharConversionException e) {
if (++i == len)
throw new SAXException(e);
writeSurrogatePair(c, str.charAt(i));
}
}
}
}
private final void put(char b) throws SAXException {
// private final void put(byte b) throws SAXException {
if (bufUsed == buf.length)
flushBuf();
buf[bufUsed++] = b;
}
private final void flushBuf() throws SAXException {
try {
out.write(buf, 0, bufUsed);
bufUsed = 0;
}
catch (java.io.IOException e) {
throw new SAXException(e);
}
364

}
public void setDocumentLocator(Locator loc) { }
public void endDocument() throws SAXException {
if (bufUsed != 0)
flushBuf();
try {
if (out != null) {
if (keepOpen)
out.flush();
else
out.close();
out = null;
}
}
catch (java.io.IOException e) {
throw new SAXException(e);
}
out = null;
buf = null;
}
}

checkorderwml.jsp
XSL-HTML WAP WAP
<%@ page language="java" session="true"
contentType="text/vnd.wap.wml" %>
<?xml version="1.0" encoding="Big5"?>
<!DOCTYPE wml PUBLIC "-//WAPFORUM//DTD WML 1.1//EN"
"http://www.wapforum.org/DTD/wml_1.1.xml">
<wml>
<card title="card0" id="card0">
<do type="accept" label="Submit">
<go href="processcheckorderwml.jsp?ordernum=$(ordernum)"/>
</do>
<p>Growbal's SimFan<br/>
<br/>
</p>
<p><br/>
<input type="text" name="ordernum"/></p>
365

</card>
</wml>

processcheckorderwml.jsp
XSL-HTML CheckOrderBean2.toXML() XML Servlet URL
XSLT
<%@ page language="java" import="java.util.*,b2b2c.*"
contentType="text/vnd.wap.wml; charset=Big5"%>
<jsp:useBean id="chkorder2" class="b2b2c.CheckOrderBean2"
scope="session" />
<%
chkorder2.processRequest(request);
//

SOAP RPC Router URL

//

Server XML

//
chkorder2.initAll("http://localhost:8080/servlet/rpcrouter",
"/Xml/jakarta-tomcat/Webapps/b2b2c/xsl/");
if ( ! chkorder2.checkOrderNo() )
// ,
response.sendRedirect("checkorderwml.jsp");
else {
chkorder2.toXML();
response.sendRedirect("http://localhost:8080/checkorderwml/b2b2c/
xsl/"+chkorder2.getXmlfilename());
}
%>

checkorderWML.xsl
XML WML XSL <xsl:output....>method "wml"media-type
MIME type"text/vnd.wap.wml; charset=Big5"
OutputMethodHandlerImple2.java WMLOutput Handler.java

<?xml version="1.0" encoding="Big5"?>


<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/
XSL/Transform">
<xsl:output method="wml"
media-type="text/vnd.wap.wml; charset=Big5"
omit-xml-declaration="no" encoding="Big5"
366

doctype-public="-//WAPFORUM//DTD WML 1.1//EN"


doctype-system="http://www.wapforum.org/DTD/wml_1.1.xml"
indent="yes"/>
<xsl:template match="/">
<wml>
<card title="card1" id="card1">
<p>Growbal's SimFan </p>
<p></p>
<xsl:apply-templates select="order"/>
</card>
</wml>
</xsl:template>
<xsl:template match="order">
<xsl:apply-templates select="name"/>
<xsl:apply-templates select="orderno"/>
<xsl:apply-templates select="orderitems"/>
<xsl:apply-templates select="status"/>
</xsl:template>

<xsl:template match="name">
<p> Dear <xsl:value-of select="/order/name"/>,</p>
</xsl:template>
<xsl:template match="orderno">
<p>
<xsl:value-of select="/order/orderno"/></p>
</xsl:template>
<xsl:template match="orderitems">
<p></p>
<xsl:apply-templates select="orderitem"/>
</xsl:template>
367

<xsl:template match="orderitem">
<p><xsl:value-of select="id"/><xsl:value-of select="qty"/>
</p>
</xsl:template>
<xsl:template match="status">
<p></p>
<p><xsl:value-of select="/order/status"/></p>
<p></p>
</xsl:template>
</xsl:stylesheet>

5.8 B2B
B2B
growbal-SimFan.com game-supply.com SOAP Web
Service
SOAP client SOAP service
Web SOAP service

game-supply.com ComOrder.java
SOAP service SOAP RPC
368

public String xmlComOrder(String order)

import java.util.*;
import java.io.*;
import org.apache.soap.util.xml.*;
import org.apache.soap.encoding.soapenc.*;
/**
* SOAP service for B2B order
*
* @author Growbal Kuo
*/
public class ComOrder
{
//
private String xmldoc = "/xml/comorder.xml";

public ComOrder() {
System.out.println("Start of ComOrder Service V.1.0");
}

// ..... SOAP RPC method


// , XML
// SOAP client
public String xmlComOrder(String order)
throws IllegalArgumentException
{
String ret;
if (order == null)
{
throw new IllegalArgumentException
("Argument 'order' must not be null.");
369

}
//..... umark this if Big5 char is used in XML doc
// order = new String(new Base64().decode(order));
// System.out.println("order:"+order);
ret = processXmlComOrder(order);
return ret;
}

// ,
public String processXmlComOrder(String order) {
System.out.println("Class ComOrder: comorder=\n"+order);
//.... if wrong order ......
if (order.trim().equals("")) {
return "";
}

//.... /xml/comorder.xml .....


try {
FileOutputStream fos = new FileOutputStream(xmldoc);
fos.write(order.getBytes());
fos.close();
} catch (Exception e) {
System.out.println("processXmlComOrder(): "+e.toString());
}

//.... .....
String orderNo =
String.valueOf( java.lang.System.currentTimeMillis() );
return orderNo;
}
}

growbal-SimFan.com stockmanage.jsp
growbal-SimFan.com

<HTML>
370

<HEAD><TITLE>Growbal's SimFan </TITLE>


</HEAD>
<BODY bgcolor="gray">
<table WIDTH="100%" COLS="1">
<tr bgcolor="blue"><td valign="buttom" align="center">
<font size="3" color="white">Growbal's SimFan </font><br>
<font size="6" color="white"></font>
</td></tr></table>
JSP b2b2c.StockBean
SOAP RPCRouter URL JSP b2b2c.StockBean.initAll() b2b2c.StockBean
SOAP service
<%@ page language="java" import="java.util.*,b2b2c.*" %>
<jsp:useBean id="stockbean" class="b2b2c.StockBean" scope="session" />

<%
session.setAttribute("stockb", stockbean);
stockbean.initAll("http://localhost:8080/servlet/rpcrouter");
%>
comorder.jsp
<form name=catalogForm method="POST" action="comorder.jsp">
<table width="100%">
<tr bgcolor="rosybrown">
<td></td><td></td><td></td>
</tr>
<%
String curColor, color1, color2;
color1 = "silver";
color2 = "white";
curColor = color1;
Vector items = stockbean.getItems();
OrderItem item;
for (int i=0; i<items.size(); i++) {
item = (OrderItem)items.get(i);
%>
<tr bgcolor=<%=curColor%>>
<td align="center"><%=item.getId()%></td>
371

<td><%=item.getQty()%></td>
<td><input type='TEXT' name=qty_<%=i%> size=10 ></td>
</tr>
<%
if (curColor.equals(color1)) curColor = color2;
else if (curColor.equals(color2)) curColor = color1;
}
%>
<tr bgcolor="lightgrey">
<td></td><td></td>
<td><input type="submit"

name="submit" value="">

</td>
</tr>
</table>
</form>
</body>
</html>

comorder.jsp
JSP session StockBean StockBean stockmanage.jsp
XML ComOrderClient ComOrder SOAP
service
<html><head><TITLE>Growbal's SimFan </TITLE>
</head>
<body bgcolor="white">
<%@ page language="java" session="true" import="java.util.*,b2b2c.*" %>
<%!
StockBean stockbean;
%>
<%
if (session.getValue("stockb") == null)
response.sendRedirect("stockmanage.jsp");
else {
stockbean = (StockBean)session.getValue("stockb");
}
stockbean.processRequest(request);
// ..... SOAP RPC
String orderNo = stockbean.sendComOrder();
372

%>
<table WIDTH="100%" COLS="1">
<tr bgcolor="blue"><td valign="buttom" align="center">
<font size="3" color="white">Growbal's SimFan </font><br>
<font size="6" color="white">

</font>
</td></tr></table>
<center>
<font size="4">
<% if (! orderNo.equals("")) {
%>
<br>
<font color="blue"><%=orderNo %></font><br>
<% } else {
%>

<% }
%>
</font>
</center>
</body>
</html>

OrderItem.java
B2B
package b2b2c;
// B2B
public class OrderItem {
String id;
int qty;
public OrderItem(String id, int qty) {
this.id = id;
this.qty = qty;
}
public String getId() { return id;}
public int getQty() {return qty; }
373

public void setId(String id) {this.id = id; }


public void setQty(int qty) {this.qty = qty; }
}

StockBean.java
B2B

package b2b2c;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.JDOMException;
import org.jdom.input.SAXBuilder;
import org.jdom.output.XMLOutputter;
import java.io.*;
import java.net.*;
import java.sql.*;
import java.util.Hashtable;
import java.util.Enumeration;
import java.util.Vector;
//import java.lang.System;
import javax.servlet.*;
import javax.servlet.http.*;
/**
*

Bean for stockmanage.jsp and comorder.jsp

*
*

@author: Growbal Kuo

in Jan. 2000

*/
public class StockBean {
Hashtable params=new Hashtable();
private static final String DEFAULT_SAX_DRIVER_CLASS =
"org.apache.xerces.parsers.SAXParser";
private String saxDriverClass;
private SAXBuilder builder;
private Document doc;
374

private Element root;

// SOAP client
ComOrderClient sender;
//... JDBC ....
private Connection con;
private PreparedStatement pstmt_select_stock;
//----------------------------------public StockBean() { System.out.println("start StockBean."); }
// StockBean
public void initAll(String RPCRouter) {
// SOAP client
try {
sender = new ComOrderClient(RPCRouter);
} catch (MalformedURLException e) {
System.out.println(e.toString());
}
// .....
createConnection();
}

// ......

HTTP request .....

public void processRequest(HttpServletRequest req) {


Enumeration en = req.getParameterNames();
while (en.hasMoreElements()) {
String varName = (String)en.nextElement();
String[] varValues = req.getParameterValues(varName);
if (varValues.length > 1) {
params.put(varName, varValues);
}
else {
params.put(varName, varValues[0]);
375

System.out.println("req:"+varName+"="+varValues[0]);
}
}
}
public String getParam(String key) {
return (String)params.get(key);
}
public void setParam(String key, String value) {
if (params.containsKey(key))
params.put(key, value);
else
System.out.println("no such key:"+key+" in param Hashtable");
}
public String[] getParamArr(String key) {
return (String[])params.get(key);
}
//.... JDBC ......
public void createConnection() {
//..... MySQL JDBC driver
try {
Class.forName("org.gjt.mm.mysql.Driver").newInstance();
}
catch (Exception E) {
System.err.println("Unable to load MySQL driver.");
E.printStackTrace();
}

//..... SQL
try {
con = DriverManager.getConnection("jdbc:mysql://
localhost/warehouse?user=growbal&password=javaxml");
376

pstmt_select_stock = con.prepareStatement("select id,


qty from stock");
} catch (SQLException ex) {
System.out.println(ex.toString());
}
catch (Exception ex) {
System.out.println(ex.toString());
}

//
public void close()
throws IOException, JDOMException {
//.... close database .....
try {
pstmt_select_stock.close();
con.close();
} catch (SQLException ex) {
System.out.println(ex.toString());
}
catch (Exception ex) {
System.out.println(ex.toString());
}
}
//..........................................................
//
public Vector getItems() {
Vector items = new Vector();
String id;
int qty;
377

try {
ResultSet rs = pstmt_select_stock.executeQuery();
if (rs != null) {
while ( rs.next() ) {
id = rs.getString(1);
qty = rs.getInt(2);
System.out.println("add id="+id+",
qty="+qty);
items.add( new OrderItem(id, qty) );
}
rs.close();
}
} catch (SQLException ex) {
System.out.println(ex.toString());
}
catch (Exception ex) {
System.out.println("getItems():"+ex.toString());
}
return items;
}

// stockmanage.jsp ,
// OrderItem , Vector
private Vector buildNewItems() {
Vector items = getItems();
Vector newItems = new Vector();
OrderItem

item;

int curQty;
String sCurQty;
for (int i=0; i<items.size(); i++) {
sCurQty = getParam("qty_"+i);
if (! sCurQty.trim().equals("") ) {
curQty = Integer.parseInt( sCurQty );
378

item = (OrderItem)items.get(i);
item.setQty(curQty);
//item = new OrderItem(item.getId(), curQty );
System.out.println("new item:"+item.getId()+",
"+curQty);
newItems.add(item);
}
}
return newItems;
}
// XML ,
// SOAP client ComOrderClient SOAP RPC
// SOAP service ComOrder,
// SOAP RPC xmlComOrder
public String sendComOrder() {
// , Vector
Vector newItems = buildNewItems();
// XML
toXML(newItems);
// XML JDOM
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
try {
buffer = (ByteArrayOutputStream)startOutputXML(buffer);
} catch (JDOMException e) {
System.out.println("toXML(): JDOM exception:"+e.toString());
} catch (Exception e) {
System.out.println("toXML(): Exception:"+e.toString());
}
String orderxml = buffer.toString();
//

SOAP RPC, XML ,

//

String ret =
sender.getResult("xmlComOrder",orderxml );
//System.out.println("sendComOrder(): ret="+ret);
379

return ret;
}

// XML
private void addToXML(OrderItem item) {
// add one element to XML file
Element curItem =
new Element("item");
Element curId = new Element("id");
curId.addContent(item.getId());
Element curQty = new Element("qty");
curQty.addContent(new Integer(item.getQty()).toString());
curItem.addContent(curId);
curItem.addContent(curQty);
root.addContent(curItem);
}

// XML
public void toXML(Vector items) {
this.saxDriverClass = DEFAULT_SAX_DRIVER_CLASS;
builder = new SAXBuilder(saxDriverClass);
OrderItem item;
//System.out.println("new root");
// build new XML doc
root = new Element("comorder");
doc = new Document(root);
//System.out.println("add elements to root");
for (int i=0; i<items.size(); i++) {
item = (OrderItem)items.get(i);
System.out.println("add to XML: "+item.getId());
// add each item to XML doc
addToXML(item);
380

}
//System.out.println("orderxml="+doc.toString());
//...... unmark this for debug (to see XML doc)
/*
try {
startOutputXML(System.out);
} catch (JDOMException e) {
System.out.println("toXML(): JDOM exception:"+e.toString());
} catch (Exception e) {
System.out.println("toXML(): Exception:"+e.toString());
}
*/
}

private OutputStream startOutputXML(OutputStream out)


throws IOException, JDOMException {
XMLOutputter outputter = getXMLOutputter();
outputter.output(doc, out);
return out;
}

private XMLOutputter getXMLOutputter()


throws IOException, JDOMException {
// Create an outputter with certain encoding
XMLOutputter outputter = new XMLOutputter(" ", true,
"Big5");
outputter.setTrimText(true);
outputter.setExpandEmptyElements(true);
return outputter;
}
381

}
//=======================================

ComOrderClient.java
SOAP client ComOrder SOAP service RPC
package b2b2c;
import java.io.*;
import java.util.*;
import java.net.*;
import org.apache.soap.util.xml.*;
import org.apache.soap.*;
import org.apache.soap.encoding.*;
import org.apache.soap.encoding.soapenc.*;
import org.apache.soap.rpc.*;
import org.apache.soap.transport.http.*;
/**
* SOAP Client of ComOrder
*
* @author Growbal Kuo
* @email growbal@taiwan.com
*/
public class ComOrderClient
{
private String result = null;
private URL url;
private Call call;
public ComOrderClient(String arg) throws
MalformedURLException
{
url = new URL(arg);
}
private void start(String method) {
String encodingStyleURI =
382

Constants.NS_URI_SOAP_ENC;
// Build the call.
call = new Call();
call.setTargetObjectURI("urn:ComOrder");
call.setMethodName(method);
call.setEncodingStyleURI(encodingStyleURI);
}

// SOAP RPC ,
// Vector
private void setParameters(String order) {
Vector params = new Vector();
//String name1 = new Base64().encode(name.getBytes());
params.addElement(new Parameter("order",
String.class,
order, null));
// Vector SOAP
call.setParams(params);
}

// SOAP RPC, result


private void execRPC() {
// start RPC
Response resp;
Object value;
try
{
System.out.println("CALL: "+call.toString());
// SOAP ,RPCRouter URL url
// resp SOAP Response
resp = call.invoke(url, "");
}
383

catch (SOAPException e)
{
System.err.println
("Caught SOAPException ("+
e.getFaultCode() + "): " +
e.getMessage());
return;
}
catch (Exception e) {
System.out.println(e.toString());
return;
}
// SOAP resp
if (!resp.generatedFault()) // resp
{
System.out.println("RPC response:"+
resp.toString());
// SOAP Response ,
// Parameter Parameter.getValue()
Parameter ret = resp.getReturnValue();
if (ret == null) {
System.out.println
("null result value");
return;
}
else {
value = ret.getValue();
}
if (value != null) {
result = value.toString();
System.out.println
("result:"+result+"\n");
}
else {
System.out.println
("null result value");
}
384

}
else // SOAP
{
Fault fault = resp.getFault();
System.err.println("Generated fault: ");
System.out.println (" Fault Code

="+

fault.getFaultCode());
System.out.println (" Fault String = " +
fault.getFaultString());
}
}

// SOAP service method,


// SOAP
public String getResult(String method, String order) {
try {
start(method);
setParameters(order);
execRPC();
} catch (Exception e) {
System.out.println(e.toString());
}
return result;
}
}

XML
game-supply.com XML game-supply.com server /xml/comorder.xml

<?xml version="1.0" encoding="Big5"?>


<comorder>
<item>
<id>SAITEK-X36</id>
<qty>1</qty>
</item>
385

<item>
<id>CH-F16-CS-USB</id>
<qty>222</qty>
</item>
<item>
<id>SFS-FC-USB</id>
<qty>333</qty>
</item>
</comorder>

5.9

classpath
xerces.jarApache Xerces XML parser package
soap.jarApache SOAP package
jdom.jarJdom XML parser package
servlet.jarSun Servlet package
sax2.jarSAX version 2 XML parser package
mm.mysql.jdbc-1.2cMySQL JDBC driver
package b2b2c java b2b2c /dev/b2b2c/
/dev
javac b2b2c/CatalogBean.java
package b2b2c java
package b2b2c java
CheckOrder.java
ComOrder.java
386


javac CheckOrder.java
javac ComOrder.java

5.10 SOAP service


SOAP service SOAP RPC Router
4 SOAP

deploySOAP service
4 SOAP
SOAP SOAP service
Deploy SOAP service
deliver.com CheckOrder

game-supply.com ComOrder
Web Service server
SOAP service CheckOrder.class ComOrder.class /dev/b2b2c/
Tomcat startup classpath

deliver.com SOAP service


SOAP service
http://localhost:8080/soap/admin/
deploy
ID urn:CheckOrder
387

Scope session
Method List checkOrderStatus
Provider Type Java
Provider Class CheckOrder

game-supply.com SOAP service


SOAP service
http://localhost:8080/soap/admin/
deploy
ID urn:ComOrder
Scope session
Method List xmlComOrder
Provider Type Java
Provider Class ComOrder

5.11

jakarta-tomcat Webapps/b2b2c

388

JSP
Webapps/b2b2c/jsp
login.jsp
loginauth.jsp
catalog.jsp
cart.jsp
error1.jsp
error2.jsp
checkout.jsp
checkorder.jsp
processcheckorder.jsp
checkorder2.jsp
processcheckorder2.jsp
checkorderwml.jsp
processcheckorderwml.jsp
stockmanage.jsp
comorder.jsp

Java
389

Webapps/b2b2c/WEB-INF/classes/b2b2c/
XML_Reader.class
Item.class
CartBean.class
CatalogBean.class
LoginAuthBean.class
OrderItem.class
CheckOrderBean.class
CheckOrderBean2.class
CheckOrderClient.class
ErrorBean.class
StockBean.class
ComOrderClient.class
ComOrder.class
CheckOrder.class
tomcat classes
Big5XSLServlet.class
WMLOutputHandler.class
OutputMethodHandlerImpl2.class

XML
Webapps/b2b2c/xml
catalog.xml

XSL
390

Webapps/ROOT/xsl XSL
checkorder.xsl
checkorderwml.xsl

Webapps/b2b2c/images
CH_F16CS2000.gif
Saitek_X36.gif
Suncom_SFSFC_USB.jpg

XML
order.xmlcomorder.xml /XML /XML

Tomcat Web.xml
Tomcat conf/Web.xml Servlet
<!--

for XSLT in B2B2C -->


<servlet>
<servlet-name>
checkorder2
</servlet-name>
<servlet-class>
Big5XSLServlet
</servlet-class>
<init-param>
<param-name>stylesheet</param-name>
<param-value>/xsl/checkorder.xsl</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>
checkorder2
</servlet-name>
<url-pattern>
391

/checkorder/*
</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>
checkorderwml
</servlet-name>
<servlet-class>
Big5XSLServlet
</servlet-class>
<init-param>
<param-name>stylesheet</param-name>
<param-value>/xsl/checkorderWML.xsl</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>
checkorderwml
</servlet-name>
<url-pattern>
/checkorderwml/*
</url-pattern>
</servlet-mapping>

5.12

MySQL server Tomcat server

growbal-simfan.com
deliver.com
game-supply.com

392


http://localhost:8080

http://localhost:8080/b2b2c/jsp/login.jsp

arthur

tseng

emily

huang

growbal

javaxml

catalog.jsp

393

cart.jsp

checkout.jsp

http://localhost:8080/b2b2c/jsp/checkorder.jsp

394

processcheckorder.jsp SOAP Web Service

XSL-HTML

http://localhost:8080/b2b2c/jsp/checkorder2.jsp

processcheckorder2.jsp SOAP Web Service


Server XML
processcheckorder2.jsp Servlet Big5XSLServlet XSL checkorder.xsl
XML HTML

395

XSL-WML
WAP
http://localhost:8080/b2b2c/jsp/checkorderwml.jsp

processcheckorderwml.jsp SOAP Web


Service Server XML
processcheckorderwml.jsp Servlet Big5XSLServlet XSL checkorderwml.xsl
XML HTML WAP

396

WML
<?xml version="1.0" encoding="Big5"?>
<!DOCTYPE wml PUBLIC "//WAPFORUM//DTD WML 1.1//EN" "http://www.
wapforum.org/DTD/wml_1.1.xml">
<wml>
<card title="card1" id="card1">
<p>Growbal's SimFan
</p>
<p></p>
<p> Dear arthur,
</p>
<p>
979800671416</p>
<p></p>
<p>CH-F16-CS-USB2</p>
<p>SAITEK-X361</p>
<p></p>
<p></p>
<p></p>
397

</card>
</wml>

http://localhost:8080/b2b2c/jsp/stockmanage.jsp
growbal-simfan.com game-supply.com

XML SOAP-RPC game-supply.comSOAP-RPC


game-supply.com server XML comorder.xml

5.13

XML Java Internet

XML Java

XML Java XML


Java
XML Java ......
398

Sun M Project
Sun M Project EA 1.0Early Access
M Project XML
1. ebXML
2. Java API for XML Messaging
M Project B2B B2B
HTTP M Project Java Servlet B2B
EA M Project Sun XML
Java/XML M Project java.sun.com

ebXML
ebXML ebXML
XML
ebXML OASISOrganization for the Advancement of Structured Information
Standards http://www.oasis-open.org
ebXML 1.02001 1 4 http://www.ebxml.org

Java API for XML Processing JAXP Optional Package 1.1


3 JAXP 1.0 Java API for XML Parsing 1.0 Sun
1.1 Java API for XML ProcessingJAXP Java API
XML Java
JAXP 1.1 Java API XML
XML 1.0 Second EditionXML Namespaces SAX
version 2.0SAX Extensions version 1.0DOM level 2 XSL 1.0
JAXP 1.1 JAXP 1.1 XML XSL
XML XSL Java
XML
http://java.sun.com

Xbeans
Xbean XML XML Xbean

399

Xbeans Java Beans Java Beans

Xbeans version 1 alpha http://www.xbeans.org

XQL
XQL XML XSL URL
XML HTML
XQL W3C W3C QL'98 XML
XQL GMD-IPSI XQL Engine Version 1.0.2 http://xml.darmstadt.gmd.de/xql/
XQL http://www.ibiblio.org/xql/

...
1. SOAP

2. SOAP

400

You might also like