Вы находитесь на странице: 1из 435

http://www.natahaus.

ru/

!
,

.


,
.

.


.


,

,
,
e-mail -

JAVASERVER
PAG
JSP

,
,



XML XSLT
JSP
JSP

Sun
microsystems

.
Java 2 Platform, Enterprise Edition

32.973.26-018.2.75
37
681.3.07
""
. ..
.
""
: info@williamspublishing.com, hitp://www.wilUamspubtishing.com
, .
37

Java Server Pages. . : , . - .: "", 2002. - 448 .: . - . . .


ISBN 5-8459-0290-8 (.)

, ..
, , JSP.
50 JSP. : , , XML Document Object Model.
JSP, , . HTML-, JSP-,
Mode! 1 Model 2, , ,
XML. Web-. ,
bean, JSP ,
.
, Java
JSP.
32.973.26-018.2.75
.

, ,
, -.
Prentice Hall, Inc.
Authorized translation from the English language edition published by Prentice Hall, Ptr., Copyright 2001
A31 rights reserved. No part of this book may be reproduced or transmitted in any form or by any
means, electronic or mechanical, including photocopying, recording or by any information storage
retrieval system, without permission from the Publisher.
Russian language edition published by Williams Publishing House according to the Agreement with
R&I Enterprises International, Copyright 2002

ISBN &-845290-8 (.)


ISBN01M)3O7O4-l (.)

"", 2002
Prentice Hall Inc.,2001

1.

JSP-

WEB-INF/web.xml
<taglib> <tag>





],]

10
17
19
20
21
24
24
26
27
28
32
35
35
39

2.

43
44
46
49
54
63

3.
bean


67
67
74
82
95

4.

99
100
104
107
108
110
112
113
115

5. WEB-
Model I
Model 2: MVC
Model 2

131

6. i Model
Model 2
Model 2



JSP-c

149

7.
Model 2

17S

8.118N
Unicode



,
,

197

9,


-

SSL

'-

235
235
239
242
242
246
246
251
254

10.




267
268
270
271
283
294
300
303

11. XML
XML-
XML-
XML-

309
311
316
317

132
133
134
149
157
162
167
169
174
178
197
199
201
202
212
219

223

XML-
XPath

347
356

12. JSP

363


Model 2


SSL
XML

DOM

364
385
403
409
420
427
428
429
435
436
439

, 1999 . Graphic Java, Swing, , Java-,


, . , .
XML,
XSLT Java, , , , Web-. ,
, .
, . ,
, ,
HTML- . 1984 . , - . Smalltalk, Eiffel NeXTSTEP , HTML, HTML, .
1999 . JSP , , . JSP
Java HTML Web-. , JSP 1.0 . ,
JSP 1.1 ; JSP-.
, Java . , JSP.
JSP ,
. . -, , , , ,
. -, ,
. ,
.

11


, JavaServer Pages,
, JSP-.
, bean,
JSP , .
, ..
, , JSP. JSP,
, .
HTML-, JSP-, Model 1
Model 2, , , XML.
Web-.

API JSP
, , Servlet
2.2 JSP 1.1. Servlet 2.3 JSP 1.2
2000 , . , Servlet 2.3,
; . ,
, , .


, ,
Tomcat 3.2.I. , , ,
Tomcat S.2.1, .
Tomcat HJSP, , , , Servlet 2.2 JSP 1.1 ( ).
, , , .

Resin 1.2 ( http://www.caucho.com). , , , , .

12


, Java
JSP.
HJSP, .
JSP, .
Core Servlets andJSP, Marty Hail, Sun Microsystems Press.
Java Servlet Programming, Jason Hunter, O'Reilly.
Web Development with JavaServer Pages, Fields Kolb, Manning.
UML (Unified
Modeling Language ). , . ,
UML, 6.
Web-.
HTML-, Java, JSP
, .


- , ,
. , , , , . (refactoring).
15 , ,
. "" , .
, , JSP-, JavaWoHd ( h t t p : //developer.
Java.sun.com/developer/technicalArticles/javaserverpages/jsp_templates)
. " " 4 . 4, , . ,
.


, " ". ,
, . 6, Model 2. Model 2 5,
6.
, , ,
Web-. , ,
.

13


50 JSP.
: , , XML- Document Object Model. . ,
, ,
. -, .
-, , . , , , , , .
, , .

,
, , , , http://www.ph.ptr.
com/advj .

,
. 0.1 ,
.

public class ClassName

;
, ,

getLength

; , ,

p r i v a t e i n t length
private int
bufferLength

. , .
. 0,2 .

14

0.2.

courier

, , , , ,
Java, HTML-, , URL

courier

, ,

, , , , ,

,
. , .
Tomcat Apache Struts
(Craig McClanahan) JSP. , .
(Scott Ferguson), Resin,
.
, , .
(Larry Cable), JSP, . 2 ,
.
(Rob Gordon), Sun Microsystems,
, Java-, ,
- .
.
, Struts,
,
Struts.
, 4 .
(Ccdric Dumoulin), .
(Yun Sang Jung)
(Chen Jia Ping), . 8 12.

15

Rational Rose Software Rational Rose for Java,


UML-,
.
Hop (Maty Lou Nohr), 1996 .
Graphic Java, .
(Greg Doench) Prentice Hall
(Rachel Borden) Sun Microsystems Press, . (Patti Guerrieri) Prentice Hall
, .
, (Lesa) (Ashley Anna Geary).
.
, , , .


, , . , ,
.
, .
. Web-, ,
, ,
, , .
, ,
e-mail. . :
E-mail:

infogwilliamspublishing. com

WWW:

http://www.wi 11 iamspublishing.com

...
JSP-.

.

.
WEB-INF/web. xml.
.
.
.
.
.
.
-

Tag.

- TagSupport: , .
.

ML ;
, XML , . XML- , . ,
XML- -:

<cd_collection>
<cd>
<artist>Radiohead</artist>
<title>OK Computer</title>
<priee>$14.99</price>
</cd>
</cd_collection>
XML, JSP ,
XML- , JSP
, 1. , JSP-, 1.1, .
1.1.

<htmlxtitle>Database Example</title>
<head>
<4@ taglib uri='/WEB-INF/tlds/database,tld'
</head>
<body>

prefix='database'4>

1 , ,
, . XML , . - . .

18

1.

<database:connect database= F:/databases/sunpress'>


<database:query>
SELECT * FROM Customers, Orders
</database:query>
<table border='2' cellpadding='5'>
<database: <1 columnName='columrwiame'>
<th><%= column_name %></th>
</database:columnNames>
<database:rows><tr>
<tr><database:columns columnValue='colurnn_value'>
<td><S= column_value %></td>
<7 database: columnsx/tr>
</database:rows>
</table>
</database:connect>
</body>
</html>

, 1.1 ( HTML-, JSP), HTML-. connect !, query . rows, columns coluranNames .


1.1, JSP
. , query, SQL-, ,
connect query ,
. columns columnNames , JSP. , 1.1, c o l umn_name 1_value.
, .
, .
; ,
,
.
, , ,
.

JSP-

19

{ r e q u e s t , response, s e s s i o n ..).
.

JSP XML; ,
XML-. ,
JSP- XML HTML.
, 1.1, () () , . ,
:
<prefix:someTag/>
JSP . ,
, .
JSP 1.1, , ".

JSP
, Web-
. Web-
HTML-, XML- JSP-,
, , ,
. Web- .


JSP-
. 1.1 JSP-, . . K J S P .

2 . Java Specification Request (JSR) http://java.sun.com. - . .

20 1.

ii ] A Counter Tag - Mieiuiofl Intend Explow


Die

dll

Jit*

FartJfltes

lool!

tltlp

HtpTVIccillToitBCeO/countet/losl.isp

This page has been accessed 14 times.

, f. t.
JSP

1.2,. /teat, jep


<body>
<
%
@ tglib uri='/WEB-INF/tIds/counter.tId' prefiac='util'

l>

This page has been accessed <b><util:oounter/X/b> times.


< /body x/ html >

1.2, t a g l i b , URI {TLD tag library descriptor). ,


, . t l d .
t a g l i b prefix, ,
. 1.2, p r e f i x
u t i l , counter
<util: counter/>.
, 12,,
WEB-INF/tIds. ,
.



XML-, . TLD-
1.2,6. JSP-,
1.2,.

... 21

1.2,6. /WEB-INF/ tide /counter. tld


version="1.0" encoding="ISO-8859-l" 2>
<!DOCTYPE t a g l i b PUBLIC
"-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.1//EN"
"http://Java.sun.com/j2ee/dtds/web-jsptaglibrary_l_l.dtd">
<taglib>
<tlibversion>l.0</tlibversion>
<jspversion>l.1</jspversion>
<shortname>Sun Microsystems Press examples</shortname>
<info>Example 3.2 from the book</info>

<tag>

<name>counte r</name>
<tagclass>tags.CounterTag</tagclass>
<bodycontent>empty</bodycontent>
</tag>
</taglib>

, XML-.
t a g l i b URL DTD (document type
definition ), taglib, DTD
.
t a g l i b .
1.2,6 1.0 , JSP, JSP 1.1 .
, . I .
tag,
: name t a g c l a s s . t a g c l a s s Java-,
. .
1.2,6 , , , , , .
t a g l i b , tag .
.



Tag,
j a v a x . s e r v l e t . j s p . tagext. Tag . ;
, , .

22 1.
int doStartTaq() throws JspException
int doEndTag() throws JspException
void release()

Tag ,
. doStartTag doEndTag .
; , , Tag. .
doEndTag release.
, .
1.2, , Tag.
1.2,. /WEB-INF/classes/tags/COTUiterTag. Java
package tags;
import
import
import
import

java.io.File;
Java.io.FileReader;
java-io.FileWriter;
java.io.IOException;

import
import
import

javax.servlet.jsp.JspException;
javax.servlet.jsp.tagext.TagSupport;
javax.servlet.http.HttpServletRequest;

public class CounterTag extends TagSupport


private int count = 0;
private File file = null;

public int doStartTag() throws JspException {


try (
checkFilef);
readCount ();
pageContext.getOut().print(++count);
)
catch(java.io.lOException ex) f
throw new JspExceptionfex.getMessage [ ) ) ;
return 3KIP_BODY;
)
public i n t doEndTagU throws JspException {
saveCount();
return EVAWAGE;
}

private void checkFileO throws JspException, lOException {


i f ( f i l e null) {
file = new File(getCounterFilename());
count = 0;
}

if('file.exists(>)

file.createNewFile();
saveCount ;

...

23

private String getCounterFilename() {


HttpServletRequest req = (HttpServletRequest)pageContext.
getRequest(};
String servletPath = req.getServletPath ( ) ;
String
realPath = pageContext.getServletContext[}.
getRealPath(servletPath);
return realPath + ".counter";
)
private void saveCount0 throws JspException (
try {
FileWriter writer = new FileWriter ( f i l e ) ;
writer.write (count);
writer.close();
1
catch(Exception ex) {
throw new JspException(ex.getMessage());
private void readCount() throws JspException {
try {
FileReader reader = new FileReader(file);
count = reader.read();
reader.close();
}

catch(Exception ex) i
throw new JspException[ex.getMessage());


, , JSP-.
. JSP, , . c o u n t e r . ,
/index, j s p , , / i n d e x , j s p . c o u n t e r .
, t a g s . CounterTag TagSupport. TagSupport Tag,
, . TagSupport
.
CounterTag. d o S t a r t T a g ,
o u t pageContext, TagSupport p r o t e c t e d . SKIP_BODY, , , , .
CounterTag.doEndTag, EVAL_PAGE. , , .
c o u n t f i l e d o S t a r t T a g , r e l e a s e .

24

1.


BWEB-INF/web.xml
JSP-, 1.2,, t a g l i b
! . ,
t a g l i b , Web-. , t a g l i b 1,2, :
// JSP- . . .
<%@ t a g l i b u r i = ' c o u n t e r s ' p r e f i x = ' u t i l ' %>
t a g l i b Web- URI counters
TLD-.
// web.xml . . .
<taglib>
<taglib-uri>counter3<ytaglib-uri>
<taglib-location>/WEB-lNF/tldg/counter,tld</taglib-location>
</taglib>

, TLD- , eJSP-. ,
. TLD , ,
.


,
. .
.
BjSP-, , t a g l i b .
(TDL-).
TagSupport
doStartTag doEndTag.

<taglib> <tag>

t a g l i b tag (TLD-). . 1.2,6. . 1.1 , t a g l i b .

<taglib> <tag>

25

1.1. t a g l i b { ,
)

tlibversion

jspversion

shortname

JSP, . JSP 1,1


1

uri

URI,

info

tag

"" :
1 ;
? ;
.
tag. counter , 1.2,6. ,
, , , . , tag, . 1.2.

12. tag ( ,
)

name

, , <prefix: name ...>

tagclass

, Tag

teiclass

bodycontent

info

attribute

"" :
1 ;

26

1.

? ;
* .
a t t r i b u t e , .
bodycontent ,
. JSP, .
bodycontent tagdependent, ; . empty
, .

, .
, doStartTag, doEndTag
release.
setPageContext setParent. r e l e a s e , .
. 1.2 ,
, .
J^P gpmamer

PWWTTH

Pflrj^Contert

.[spWrjler

gelujlQ
SKIP

prin!0

3
J

(JoEncfTagO
EVAL_PAGE

re lease

1
. 1.2.
counter

27

, . 1.2,
, .
doStartTag,
SKIP_BODY. SKIP_BODY , ,
, .
doEndTag EVAL_PAGE, JSP-. doEndTag
r e l e a s e , (, )
.

. , , , .
, ,
. 1.5 2.2.


Tag JSF 1.1 .
jSP-
Tag... ....
, .

,
. JSP ,
. ,
, , .

, r e l e a s e doStartTag. , , , .
public class TagHandler extends TagSupport
p r i v a t e Hashtable h a s h t a b l e ;

public irit doStartTag (} throws JspException {


hashtable = new Hashtable 0;

public void released {


hashtable = null;

28

1.


, , n u l l .
public class TagHandler extends TagSupport
private Hashtable hashtable;

public TagHandler() {
hashtable - new Hashtable();
public void release() {
hashtable - n u l l ;

, , .
_6=1__. , :
< u t i l : i t e r a t e times='4'>
.
.
< u t i l l i t e r a t e collection^<fc= aCollection %>'>
c o l l e c t i o n .
,
.
1. JSP-.
2. , , TLD.
3. setAttra . , JavaBeans.
qetAttr, , .
, .
Web- , ,
. . 1.3 Web- , ,
. , , ,
. . , , .

Please Register

Please Register

Ftrat Nme:

First Name:

|raph

Lal Name:

Last Mams:

E-mail Address:]

E-mail Address:

29

Please fill in all of the fields above

. 1.. 8

:
<input t y p e = ' t e x t ' size=15 name='firstName 1
request,getParameter("firstName")%>>
value='<%=
v a l u e HTML- inpflit , .
, , . 1.3, , .
- ;.' Refill atoiP*oj-Mbo*l*!HMtEi(*ii
. , , ( ),
Please Register

ServietRequest.getParameter
n u l l , .
First Name:
|null
Last :
(null
, ,
E-mail Address, null
,
. JSP, , 1.3,. r e q u e s t P a r a m e t e r
, .
Are. 1,4.
request.getParameter

30

1.

1.3,a. / r e g i s t e r . j
t a g l i b uri^'WEB-INF/tlds/htmL.tld'

prefix='html'%

<table>
<tr>
<td> F i r s t Name: f </td>
< t d x i n p u t type= t e x t ' size=15 narae=' firstMame'
value='<html:requestParameter property="
</td>

</tr>

<tr>
<td> Last Name: </td>
<td><input t y p e = ' t e x t ' slze=l5 name='lastName'
value='<html:requestParameter property="lastName"/>'>
</td>
</tr>
<tr>
<td> E-mail Address: </td>
< t d x i n p u t type='text' si2e=25 name=' emailAddress'
value='<html:requestParameter
propertY="emaiLAddresa"/>'>
</td>
</tr>
</table>
. TLD , requestParameter, 1.3,6.
1.3,6. /WES-IMF/ t i d e /html. t l d
<taglib>
<tag>
<name>requestPar ameter</name>
<tagclass>tags.GetRequestParameterTag</tagclass>
<bodycontent>empty</bodycontent>
<attribute>
<name>property</name>
<required>t rue</requi red>
<rtexprvalue>true</rtexprvalue>
</attribute>
</tag>
</taglib>
property ,
. , attribute,
. 1.3 ( JSP 1.1).

31

1.3. attribute

name

required

t r u e ,

rtexprvalue

t r u e , JSP-

"" :
1 ;
2 .
requestParameter 1.3, .
1.3,. /WEB-INF/clasees/tags/GetRequestParameterTag.Java
package tags;
import
import
import

javax.servlet.ServletRequest;
javax.servlet.jsp.JspException;
javax.servlet.jsp.tagext.TagSupport;

public class GetRequestParameterTag extends TagSupport {


private String property;
public void setProperty(String property) {
this.property = property;
)
public int doStartTag(} throws JspException {
ServletRequest req = pageContext.getRequest();
String value = req.getParameter(property);
try |
pageContext.getOut().print(value == null ? "" : value);
)
catch (Java.io.IOException ex) {
throw new JspException(ex.getMessage());
}
return SKIP_BODY;

set-
JavaBeans. set-
, , . set-
doStartTag.

32

1.

GetRe quest Parameter! ag set- property.


, p r i v a t e , doStartTag.
, . 1.5, , requestParameter.
G ol Re qij 5 si P mei e rTag

-lap Cz-mnm

PapsContort

JflpWrrttr

MlPageConiextQ
celPirentQ

s el Props riyO

doSlartTagO

prlfllO

doEncftagO
EVAL PAGE

retoaeefl

. /.5. GetRequestParameterTag



JavaBeans-. , set-; doStartTag. , cloStar tTag .



. , ,
, .

PageContext, pageContext, TagSupport p r o t e c t e d .

33

PageContext , ,
.
.
.
.
, ,
. , :
public class SomeTag extends TagSupport {
public i n t doStartTag[) throws JspException [
User user (User) pageConteJft.getAttx-ibuteC'user") ;
1

.
User user = (UserJpageContext.getAttribute("user",
PageContext.SESSION_SCOPE);
PageContext.getAttribute , Ob j ect.
PAGE_SCOPE, REQUEST_SCOPE, SESSION_SCOPE
APPLICATION_SCOPE, PageContext.
pageContext , :
public class SomeTag extends TagSupport (
public i n t doStartTag () throws JspException {
ServletRequest request pageConteact.getRequest() ;
Locale locale request.getLocale();

. 1.4 PageContext,
.

1.4. PageContext

Object f i n d A t t r i b u t e
(String)

, ,

Object g e t A t t r i b u t e
(String)

;
, n u l l

34

1.

. 1.4

void setAttribute
(String, Object)

void removeAttribute
(String)

JspWriter

JspWriter,

getOut()

ServletRequest
getRequest()

ServletRequest,

ServletResponse
getResponse()

ServletResponse,

ServletContext
getServletContext()

HttpSession
getSession()

void forward
(String path)

void include
(String path)

HTML- JSP-;

s e t A t t r i b u t e g e t A t t r i b u t e removeAttribute ,
, . . , .
PageContext , , out, s e s s i o n
.. PageContext .getOut , .

Web-, JSP. forward include PageContext , .
JSP 1,1, . , , JSP. ^ 1.2 .

35


,
, .
J s p Exception. .
, JSP-
.
<% t a g l i b u r i = ' u t i l . t l d ' p r e f i x = ' u t i l ' % >
<% page e r r o r P a g e = ' e r r o r . j s p ' %>
JSP, , :
import
import

javax.servlet.jsp.JspException;
javax.servlet.jsp.tagext.TagSupport;

public c l a s s SomeTagHandler e x t e n d s TagSupport


p r i v a t e boolean someCondition;
public i n t doStartTag()

throws JspException {

if (someCondition = f a l s e )
throw new J s p E i c c e p t i o n r ' i n f o r m a t i v e m e s s a g e " ) ;
}
)

e r r o r . j sp, page,
, S o m e T a g H a n d l e r . d o S t a r t T a g
.

j a v a x . s e r v l e t . j s p . t a g e x t
, . , . 1.6,
, .
Tag.
, Tag, TagSupport BodyTagSupport.
, BodyTagSupport
, TagSupport , . . , TagSupport , . BodyTagSupport .

36 1.

Interim
Tag
(fta rft

parent

4% SKIP BODV
*s EVACBODYJNCUJDE
*i SKIP PAGE
#1 EVAL PAGE

PageCcnteM
1 PAGE_SCOPE
t REQUEST SCOPE
*1 SESSION SCOPE
*i APPLICATION SCOPE

\0
*se!AHniiiitB(!
selAtlribuleO
fletAtlribllleO
gelAmibuleg
findAilrifautoQ
re moveAH ributeQ
remmeAtlributeu
gel All t lit esSc op eO
geiAJ I ;i u Nwn s In S op
O O

9
4oiwardO
included
*h -. jE a pi I onQ

yg
doStnTag()
doEnoTagO
seiBodyCortlsnlO

BafyCcmti*

. .6. , tagext

, , , .
. 1.6, PageContext , .

Tag
Tag ; , .
void setPaqeContext(PageContext)
void setParent(Tag}
i n t doStartTag() throws JspException
i n t doEndTag() throws JspException
void release ()
Tag qetParent()

37

,
.
setPageContext,
setParent. doStartTag.
doEndTag. doEndTag
doStartTag. doEndTag r e l e a s e , , .
doStartTag, doEndTag , . , , . 1.5.

1.5. , doStartTag doEndTag

doStartTag ()

SKI P_BODY;
EVAL_BODY_INCLUDE;

doEndTag ()

SKIP_PAGE: , ,
EVAL_PAGE: , ,

( n u l l ) . , JSP- inbetween innermost, outermost


inbetween.
^example:outermost>
<example:inbetween>
<example:innermost>
</example:innermost>
<example:inbetween>
</example:outermost^
, , . inbetween
outermost innermost.
Tag , set, , ,
.
Tag .

TagSupport BodyTagSupport.

38 1.

TagSupport: ,

, TagSupport.
TagSupport Tag :

;
.
TagSupport JSP-, .
, , doStartTag
SKIP_BODY, doEndTag EVAL_PAGE.
TagSupport .
// TagSupport Tag
// :
p r o t e c t e d String i d ;
p r o t e c t e d PageContext paqeContext;
static

Tag

findAncestorWithClass(Tag,

Class)

Object qetValue[String key)


void setValue(String key, Object value}
void removeValue(String key)
Enumeration qetValues ()
String qetldQ
void s e t l d Q
TagSupport :
, . p r o t e c t e d .
findAncestorWithClass .
, s t a t i c ,
. findAncestorWithClass 2.
TagSupport, ,
, -. , .


TagSupport BodyTagSupport
TagSupport BodyTagSupport . Tag TagSupport
BodyTagSupport.

39

Java , , TagSupport
BodyTagSupport, .
Tag BodyTag, .


, , BodyTag,
. b o d y c o n t e n t empty, . ,
BodyTag, .
BodyTag, , . JSP-, . 1.7. ,
, ' u s e r ' .
.
i^LognPae. **(

Edit

!<

Fgn>lt

-1

Tool!

I ed>> * i ^ w i * " si>

^D

Please Login

Welcome Steve
Vou ate a oset

Name:

Sieve

Password:

2] D

!*; Uc4lHrnt

. .7, ,
. 1.7 Web-, . , ( welcome, j s p ; 9). , 1.4,, a u t h e n t i c a t e . ' u s e r ' ,
.

40 1,

1.4,8. /welcome, jsp


<html><head><title>Welcome</title></head>
<body>
<%@ taglib uri='/WEB-INF/tlds/authenticate.tld'
prefix='security'%>
<h3>Welcome <%= request.getUserPrincipal () %></h3>
<security:authenticate role='user'>
You are a user
</security:authenticate>
</body></html>

a u t h e n t i c a t e 1.4,6.
1.4,6. /WEB -INF/ classes/ tags/ Authenticate Tag . Java
package tags;
import javax.servlet.http.KttpServletRequest;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.TagSupport;
public class AuthenticateTag extends TagSupport {
private String role null;
public void setRole(String role) 1
this.role = role;
}
public int doStartTag() throws JspException {
HttpServletRequest request = (HttpServletRequest)
pageContext.getRequest
if(request.isUserlnRole(role)) {
return EVAL_BODY_IMCLUDE;
)
return SKIP_BODY;
)
public int doEndTagO throws JspException {
return EVAL_PAGE;

();

AuthenticateTag TagSupport
, r o l e a u t h e n t i c a t e .
'user', doStartTag EVAL_BODY_INCLUDE .
SKIP_BODY, .

41


BodyTag,
.
doS t a r t Tag EVAL_BODY_INCLUDE. , , BodyTag. 2.

JSP , .
JSP.
.
JSP . JSP,
, ,
. .
, , ,
.

...
.
.
.
-

bean .
.
.
.

.
- .
- JavaScript-.
.
- .
- .


. , HTML- SELECT.

<html:links name='api'>
<option v a l u e = ' S e r v l e t s ' >servlets</option>
</html:links>
HTML-, , :
<select name='api' onChange^' t h i s . f o r m , s u b m i t ( ) ' >
<option value=' S e r v l e t s ' > s e r v l e t s < / o p t i o n >
</select>
, JSP- bean .
, , JSP- .
i t e r a t e , ,
bean.
<smp:iterate collection^'<%= vector %>'>
<jsp:useBean i d = ' i t e m ' scope='page' c l a s s = ' J a v a , l a n g . S t r i n g ' / >
Item: <%= item %><br>
</smp:iterate>
:
<smp:iterate c o l l e c t i o n ^ < % = v e c t o r %>'>
Item: <%= item l x b r >
</smp:iterate>
i t e r a t e .

44

2. ...

, . , bean . , .


, BodyTag. , , :
.

BodyTag
BodyTag Tag. Tag, BodyTag :
void doInitBody [)
int doAfterBody [)
void setBodyContent(BodyContentl

. :
/7 BodyTag
if(tag.doStartTagO == EVAL_BODY_TAG) (
tag.setBodyContent(bodyContent);
tag.doInitBodyO ;
do 1
//
}

while(tag.doAfterBodyt) == VAL_BODY_TAG);

}
doInitBody ,
doAfterBody . , . , .
<util:loop from='l' to='5'>
<util:loop>

doInitBody from to loop. doAfterBody EVAL_BODY_TAG, SKI P_BODY.


doInitBody doAfterBody ,
doInitBody .

45

. 2.1 , BodyTag,
, .

2.1. , BodyTag

doStartTag ()

EVAL_BODY_TAG:
BodyContent
SKI P_BODY:

doAf t e r T a g () EVAL_BODY_TAG:
SKIP_BODY:

doEndTag [)

EVAL_PAGE: ,
SKIF_PAGE:

BodyTagSupport

BodyTagSupport, BodyTag. BodyTagSupport TagSupport, ,
BodyTag,
, BodyTagSupport , .
// BodyTagSupport
// TagSupport BodyTag.
// :
BodyContent getBodyContent()
JspWriter qetPreviousOut()
, BodyTag TagSupport,
BodyTagSupport . g e t B o d y C o n t e n t
, g e t P r e v i o u s O u t , .
g e t P r e v i o u s O u t o u t . .
BodyTagSupport
. , , . 2.2.

46

2. ...

2.2. ,
BodyTagSupport

d o S t a r t T a g ()

EVAL_BODY_TAG:

doAf t e r T a g () SKIP_BODY:
doEndTag ()

EVAL_PAGE: ,

do-while, . , , . 2.1 JSP-,

,
.

t Sk

&

lie

favorite

look

tiers!ing over [one, two, three. Tour] ...


Item one
Hem: Iwo
Hem: throe
Item, four

. 2.1. ,

~*y L o ^ rtimd

JSP- 2.1 ,.
2.1,a. /test.jsp
<html><headxtitle>An Iterator</title></head>
<%@ taqlib uri-f/WEB-INF/tlds/iterator.tld' prefix-'it' l>
<body>
<% Java.util.Vector vector = new Java.util.Vector ();
vector.addElement("one"); vector.addElement("two");
vector.addElement("three"); vector.addElement("four");
Iterating over <%= vector *> ...<p>
<it:iterate collection^'<%= vector %>'>
<jsp:useBean id='item' scope='page' class='Java.lang.String'/>
Item: <l= item %><br>
</it:iterate>
</body>
</btml>

47

S t r i n g
c o l l e c t i o n i t e r a t e .
iterate .
< j sp: useBean>, JSP-.
2,1,6 i t e r a t e .
2.1,6. /WEB-INF/classes/ tags/IteratorTag . Java
package tags;
import java.util.Collection;
import java.util.Iterator;
import
import

javax.servlet.jsp.JspException;
javax.servlet.jsp.tagext.BodyTagSupport;

public class IteratorTag extends BodyTagSupport {


private Collection collection;
private Iterator iterator;
public void setCollection(Collection collection)
this.collection = collection;
)

public int doStartTag {) throws JspException {


return collection.size[) > D ? EVAL_BODY_TAG : SKIP_BODY;
}

public void dalnitBodyO throws JspException (


i t e r a t o r = c o l l e c t i o n . i t e r a t o r (};
pageContext.setAttribute<"item",

iterator.next());

public int doAfterBody() throws JspException {


if (iterator.hasNext()> {
pageContejct.setAttribute("item",
iterator.next());
return EVAL_BODY_TAG;
}
else (
try (
getBodyContent0.writeOut(getPreviousOut<));
}
catch[java.io.lOException e) {
throw new JspException[e.getMessage());
}
return SKIP_BODY;

2.1,6 IteratorTag , .
setCollection c o l l e c t i o n .
doStartTag,
EVAL_BODY_TAG, , -

48

2. ...

, SKIP_BODY doInitBody doAf terBody.


, doInitBody,
(), "item".

doAf terBody. , doAf terBody
.
doAfterBody EVftL_BODY_TAG, .
, SKIP_BQDY .
i t e r a t e release, i t e r a t e
,
.
, i t e r a t e , (previous out). , , doAfterBody, doEndTag.
.
. 2.2 I t e r a t o r T a g , 2.1 ,.
.
pageContext.setAttribut("itm",

iterator.next(});

< j sp: useBean>.


<jsp:useBean id='itm' scope'page' c l a s s ' J a v a . l a n g . S t r i n g ' >
, , s e t A t t r i b u t e
("item"), id <jsp:useBean>.
.
,
.
<jsp:useBean>. IteratorTag
.



BodyTag, I
doStartTag EVAL_BQDY_INCLUDE; - |
.
BodyTag, ,
, .
doStartTag EVAL_BODY_INCLUDE.
, 2,1,6.

UtrttarTij

JSP Contain if

1^

49

BorfyComtni

ttEPigtConttklQ

litColltelionQ

EVAL BOD TAG

iitBodyConun)

itAmibultQ
> I body

EVAL^BOOYJAS

4 JTIVIVSXlKbtSj

SKIP BODY

. 2.2. I teratorTag


, JSP-. , i t e r a t e ,
, .
, , ,
bean, .
JSP- , 2.2,.
2.2,. / t t . j . p
<htmlxheadxtitle>Scripting Variable Example</titlex/head>
<@ taglib uri='iterator.tld' preflx-'it' %>
<% java.util.Vector vector = new Java.util.Vectort);
vector.addElement("one");
vector.addElement("two");
vector.addElement("three"); vector.addElement{"four");

50

2. ...

I t e r a t i n g over <%=vector %> ...<>


< i t : i t e r a t e collection='<%= vector %>'>
item <%= item 3><br>
</it:iterate>
</px/body>
</html>
Wcb-, ,
. 2.1.
2.2. 2.1,, , < jsp:useBean>.
, .
, , .
1. ,
.
2. TagExtralnfo, ,
.
3. TLD, TagExtralnfo,
aiare.
i t e r a t e , 2.2,.

bean

i t e r a t e
IteratorTag, (/WEB-INF/classes/tags/IteratorTag. Java). , , , ,
bean; .
IteratorTag .


JSP- , , , ,
. , (tag extra info).
TagExtralnfo. TagExtralnfo
j a v a x . s e r v l e t . j s p , t a g e x t .

51

2.2,6 I t e r a t o r T a g l n f o , , 2.2,.
2.2,6. /WEB-INF/claa/tags/IteratorTagInfo.Java
package tags;
import
javax.servlet.jsp.tagext.TagData;
import
import

javax.servlet.jsp.tagext.TagExtrainfo;
Java*.servlet.jsp.tagext.Variablelnfo;

public class IteratorTaglnfo extends TagExtralnfo (


public Variablelnfo[] getvariablelnfo(TagData data) {
return new Variablelnfo[] {
new Variablelnfo(data.getld(), //
"Java.lang.Object", //
t r u e , //
Variablelnfo.NESTED) //
);

getvariablelnfo Variablelnfo,
. 2.2,6 g e t v a r i a b l e lnfo , Variablelnfo, item, 2.2,.
:

VariableInfo.AT_BEGIN
Variablelnfo.NESTED
VariableInfo.AT_END

AT_BEGIN AT_END
. NESTED
.


.
. TLD-
i t e r a t e 2.2,.
2.2,. /WEB-INF/tlds/iterator.tld
<taglib>
<tag>
<name>iterate</name>
<tagclass>tags.lteratorTag</tagclass>

52

2. ...

<teiclaee>tags.IteratorTagInfo</t*iclas*>
<bodycontent>JSF</bodycontent>
<attribute>
<naine>collection</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<info>Iterates over a collection</info>
</tag>
</taglib>
, 2.2,,
t e i c l a s s .
t e i c l a s s t a g l i b .

bean
bean, . , , , ^-.
JSP ,
,
<jsp:useSean>.



JSP-. , , JSP-
. ^-:
< i t : i t e r a t e collection^'<*= vector %>'>
item <%= item %><br>
</it:iterate>
item,
. .
public Variablelnfo[]'getVariablelnfo(TagData data) {
return new Variablelnfo[] {
new Variablelnfo("item", "Java.lang.Object",
true,
Variablelnfo.NESTED)
1;

53

,
. , JSP id. , , i t e r a t e
id, .
:
<it:iterate id='anltem' collection=' <%= vector %>'>
item <%= anltem %><br>
</it:iterate>
anltem,
.
. -,
id.
<taglib>
<tag>
<name>iterate</name>
<tagclass>tags.IteratorTag</tagclass>
<teiclass>tags.IteratorTaglnfo</teiclass>
<bodycontent>JSP</bodycontent>
<attribute>
<name>id</name>
<required>tme</required>
<rtexprvalue>t rue</rtexprvalue>
</attribute>
<attribute>
<name>collection</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<info>Iterates over a collection</info>
</tag>
</taglib>
-, ,
id. i t e r a t e :
public class IteratorTaglnfo extends TagExtralnfo {
public Variablelnfo[] getVariablelnfo(TagData data)
{
return new Variablelnfo[] {
new Variablelnfo(data.getldO, //
"Java,lang.Object", //
true, //
Variablelnfo.NESTED) //

54

2. ...

,
id. ,
TagSupport BodyTagSupport, , TagSupport id
s e t Id.


- 1 Cw*be I Ew4fe - W e * E
-tout

I Obi ddi yw Rauoriiii iced t>
, ,
SQL-,
CAPITALIZE THIS STRING
,
BodyTag, . ,
, , 2.3,
JSP-, . 2.3,

J
c a p i t a l i z e , *- Lor-J rt-w.f>
, . .2..
2.3,.
2.3,. /test.
<htmlxheadxtitle>Capitalize Tag Example</titlex/head>
<%@ taglib uri='example' prefix^'example' %>
<example:capitalize>
capitalize this string
</example:capitalize>
</body>
</html>
capitalize 2.3,6.
2.3,6. /WEB-IKF/classes/tags/CapitalizeTag. Java
package tags;

'

import javax.servlet.jsp.JspException;
import iavax.servlet.jsp.tagext.BodyTagSupport;
public class CapitalizeTag extends BodyTagSupport {
public int doAfterBody() throws JspException !
try (
String content - bodyContent.getstring();


String

55

upper = c o n t e n t . t o U p p e r C a s e ( ) ;

bodyContent.clearBody();
bodyContent.print(upper);
bodyContent.writeOut(getPreviousOut());

)
c a t c h ( J a v a . i o . I O E x c e p t i o n e) {
throw new J s p E x c e p t i o n ( e . g e t M e s s a g e ( ) ) ;
1
r e t u r n SKIP BODY;

doAfterBody,
bodyContent, BodyTagSupport,
. , .
doAfterBody .
i t e r a t e , 2.1,6,
c a p i t a l i z e .
,
. , c a p i t a l i z e ,
, , . 2.3,

( " c a p i t a l i z e t h i s s t r i n g " ) .
<example:capitalize>
<%= " c a p i t a l i z e t h i s s t r i n g " %>
</example:capitalize>
, JSP
bodycontent.
<tag>
<name>capitalize</name>
<tagclass>tags.CapitalizeTag</tagclass>
<bodycontent>JSP</bodycontent>
</tag>

, ,
, SQL-. " bodycontent, tagdependent.
<tag>
<name>capitalize</name>
<tagclass>tags.Capital!zeTag</tagclass>
<bodycontent>tagdependent</bodycontent>
</tag>

56

2. ...


,
( c a p i t a l i z e
i t e r a t e ) , ,
. .
BodyContent,
. , . BodyContent . 2.4.
Writer
/

I.

BodyTagSupport

doSlartTagQ
*doEndTagO
*5 91 Bod yContent 0
*d ofmi Bod f 0
^duAfl 6 r8 ody 0
*ielease0

^BodyContenifl
ftodyConleni

*clearBodyO
getfieadsrj)
gelStringO
*writBOwO
*get Enc 1 osrngWnl efO

jelPieviousOulfl

. 2.4. BodyContent

BodyContent JspWriter, out. JSP-


out, , . BodyContent.
BodyContent , .
BodyContent , , .
(previous out),

(enclosing writer). BodyContent.


getEnclosingWriter BodyTagSupport. getPreviousOut.

57

, BodyContent. He
, , BodyTagSupport . JSP-, ( 2.4,), , .
2.4,a. /teat.jap
<htmlxheadxtitle>Body Content</title></head>
<%@ t a g l i b uri='body' prefix='body' %>
<body:printBody>
BODY Kbr>
<body:printBody>
BODY 2<br>
</body:printBody>
</body:printBody>
</body>

</html>

printBody , . 2.5.
-lalxtl

i- Bo* Content - * Internet


| pk

Edit

git*

Fefflritei

.jpolj

Help

. 2.5. ,

, printBody .
printBody 2.4,6.
2.4,6. /WEB-INP/clasees/tags/PxintBodyTag. Java
package

tags;

import
import

javax.servlet.jsp.JspException;
javax.servlet.jsp.tagext.BodyTagSupport;

public class PrintBodyTag extends BodyTagSupport {


public int doftfterBody(} throws JspException (

58

2. ...

try (
getBodyContent().writeOut(getPreviousOut()};
)
catch (Java,io.IOException e) (
throw new JspException(e.getMessage());
)
return SKIP_BODY;

, , , , . JSP-, 2.4,, .
1
<body:printBody> < % pageContext.pushBody()* % >
2
BODY K b r >
<body:printBody> <%-- pageContext.pushBody(}* --%>
3
BODY 2<br>
</body:printBody> <% pageContext.popBody()** %>
2
</body:prntBody> <% pageContext.popBody()** %>
1
* d o S t a r t T a g ( )
**
doAfterTagO , doEndTagO
, , p r i n t B o d y , J s p W r i t e r , . 1. . 2.6 p r i n t B o d y .
d o S t a r t T a g printBody, o u t BodyContent. J s p W r i t e r , .
( 2)
(. 2,6). ,
PageContext. pushBody. pushBociy
d o S t a r t T a g p r i n t B o d y .
p r i n t B o d y , PageContext.pushBody. BodyContent
, BodyContent , J s p W r i t e r . 3. , p r i n t B o d y
BodyContent p r i n t B o d y . ,
p r i n t B o d y J s p W r i t e r , .

59

. 2.6.

doAf terBody p r i n t B o d y ,
doEndTag P a g e C o n t e x t . popBody. popBody BodyContent, 2 (. . 2.6).
PageContext .popBody doAf t e r B o d y doEndTag , doAf t e r B o d y
p r i n t B o d y 3, doEndTag 2. ,
.
, doAf t e r B o d y P&geContext. popBody.
, PrintBodyTag. doAf terBody . ,
doAfterBody BodyContent . |1 p r i n t B o d y BodyContent .
p r i n t B o d y ,
printBody, JspWriter, PrintBodyTag. doAfterBody out,
.
, PrintBodyTag
doEndTag , out. , )' doEndTag BodyContent, , , o u t

60

2. ...

BodyContent . ,
, , JSP 1.1 ,
, BodyContent , . .

BodyContent
doEndTag
, doEndTag, BodyContent, JSP 1.1, .
doEndTag
n u l l .
doAf terBody,
, BodyContent
11 .

JavaScript-
,
HTML-
JavaScript-. JavaScript- , .
. 2.7 JSP-,
HTML- SELECT.
SELECT .
.
, . 2.7, ,
.
. -1 !
flkt

ylew

Fjrt>rlr

Ioolt

View Documentation for

a Doc*

"

f""'

-v

11 It JMOI As. MeotdtWtmet E tftaa -iDlxl


j ib frill Klew Ffcuornn 1 *

OocumBrrtalionforJNDl

. 2.7. l i n k s

61

JSP- 2.5,.
2.5,a. /teat.jsp
<htmlxtitle>Java Api Document a tion</t it le>
<body>
<%@ taglib uri='html' prefix='html' %>
<form action='showApi.jsp'>
<font size='4'> View Documentation for</font>
<html:links name= api'>
<option
Servlets'>servlets</option>
<option value= JSP'>jsp<7option>
<option value= Swing'>swing</option>
<option value- JDBC >JDBC</option>
<option value= JNDI' >JNDK/option>

<option value='JavaBeans'>JavaBeans</option>
</html:links>
</fonn>
</body>
</html>
l i n k s , HTML- s e l e c t ;
option. , ,
2.5,6.
2,5,6. /showApi.jsp
<html><title>The <% request.getParameter["api") %> Api</title>
<body>
Documentation for <%= request.getParameter("api") %>
</body>
</html>

showApi . j sp , ,
. , -,
, , API
. l i n k s 2.5,.
2.5,. /WEB-INF/classes/tags/LinksTag. Java
package
import
import
import

tags;
javax.servlet.jsp.JspException;
javax.servlet.jsp.tagext.BodyContent;
javax.servlet.jsp.tagext.BodyTagSupport;

public class LinksTag extends odyTagSupport (


private String name;
private StringBuffer buffer;

62

2. ...

public void setName (String name) (


this.name = name;
>
public i n t doAfterBody(J throws JspException {
try |
String body = bodyContent.getString();
bodyContent.clearBody();
buffer = new StringBuffer(
"<select name='" + name + "' " +
"onChange=' t h i s . f o r m . s u b m i t ( ) / > " +
body + " < / s e l e c t > " ) ;
bodyContent.print(buffer.toString() ) ;
bodyContent.writeOut(getPreviousOut());
}
c a t c h ( J a v a . i o . l O E x c e p t i o n ex) {
t h r o w new J s p E x c e p t i o n ( e x . g e t M e s s a g e ( ) ) ;
)
r e t u r n SKIP_BODY;

HTML- s e l e c t , l i n k s
name ( s i z e m u l t i p l e l i n k s ).
LinksTag ,
JavaBeans.
BodyContent. g e t S t r i n g , doAf terBody
, . BodyContent
, , HTML- s e l e c t .
BodyContent,
. :
<select

name='api'

onChange='this.form.submit()'>

<option v a l u e - ' S e r v l e t s ' > s e r v l e t s < / o p t i o n >


<option value='JSP'>jsp</option>
<option value='Swing'>swing</option>
<option value='JDBC >JDBC</option>
<option value=' JNDI' >jNDK/option>
<option value-'JavaBeans'>JavaBeans</option>
</select>
s e l e c t cmChange;
JavaScript- ( t h i s . form, submit ()),
.
,
HeJSP JavaScript. JSP JavaScript
,
. JSP JavaScript
, Web-.

63


, . ,
f i n d A n c e s t o r WithClass (Tag, C l a s s ) TagSupport.


f i n d A n c e s t o r W i t h C l a s s s t a t i c , , ,
.
, f i n d A n c e s t o r W i t h C l a s s , , t h i s .
// TagSupport.
public i n t d o S t a r t T a g ( ) throws J s p E x c e p t i o n {
try (
II
Class k l a s s = com.companyname.TagName".class;
Tag a n c e s t o r = f i n d A n c e s t o r W i t h C l a s s ( t h i s , k l a s s ) ;
>
catch(ClassNotFoundException ex) {
throw new J s p E x c e p t i o n ( e x . g e t M e s s a g e ( ] ) ;

TagSupport.
f i n d A n c e s t o r W i t h C l a s s Tag, TagSupport,
TagSupport.
f i n d A n c e s t o r W i t h C l a s s C l a s s .
, , . findAncestorWithClass-.
, , TagSupport, . ,
. TagSupport.
// ,
// TagSupport

private TagSupport getAncestor(String className)


throws JspException (
Class klass = null; // class
try {
klass = Class.forName(className};
}
catch(ClassNotFoundException ex) f
throw new JspException(ex.getMessage());

64 2. ...

return (TagSupport)findAncestorWithClass(thia, klass);


-,
.
, :
<smp:ancestor>
<smp:offspring/>
</smp:ancestor>
doStartTag "name" "value".
package tags;
public class AncestorTag extends TagSupport {
public int doStartTag() throws JspException I
setValue("name", //
"value"); //
return EVAL BODY INCLUDE;

AncestorTag.doStartTag EVAL_BODY_INCLUDE;
. , :
public class OffspringTag extends TagSupport (
public int doStartTag() throws JspException {
AncestorTag ancestor = null;
try {
ancestor =

(AncestorTag)findAncestorWithClass(this,
tags.AncestorTag.class);
pageContext.getOut0.println(
ancestor.getValue["name")) ;

}
catch(Exception ex) {
throw new JspException(ex.getMessage(}};
}
return EVAL_BODY_INCLUDE;

OffSpringTag.doStartTag findAncestorWithClass
tags.AncestorTag. TagSupport.
getValue ("name") ("value"), out.

65

JSP 1.1 . , JSP.


. , JSP.
. . , 8 .

HTML-

...
'

bean.
- ,
.
- ,
.
- JavaScript.
- JSP-.
- .
- JSP-
.
.
- fa?ade HTML-.
- , .
- .
.

TML- Web- , (, Swing AWT) .


JSP , j s p : u s e B e a n bean.
{ ) ( bean) Memento.
bean.
, ,
HTML- form.

bean
bean
. JSP beans ,
.


, , URL a c t i o n . {
a c t i o n , Web.)
7.1=12=){2&. . . &UMHN=3na4emteN. , , -

name, John, "name=John", phone -

68

3. HTML-

555-1212, :
"name=John&phone=555-1212".
JSP-
request. , , ,
:
<%= request.getParameter("name") %>
, bean.
1
<jsp:useBean id='form' class='beans.Form
scope='request'>
f
<jsp:setProperty name='form propeirty='* '/>
</jsp:useBean>

p rop ert y
'*'. Java- , . ,
name setName,

j sp: useBean bean. ;
, .

, bean Memento
Memento ,
. Memento HTML , bean.

,

,
. ,
.
, ,
.
JSP- , . 3.1, ,
. , ,
action, Submit Query
. . 3.1 Web-
, ,
.

bean

and Had-. . || |
Qk

pftt

^lew

favoritej

ioolj

Utlp

- [Ralph

69

I. TBJ Ait. id Had Buawn InL.. . lOl xj


ile

Bill

VFB

FawrltK

loot

blip

Name: [Ralph

t~viss f~ master catd

^vtsa ^ mastej card

^ discovery ^ amencari

^ dtscovefy

^ amerJcan

1
Submit Query

Submit Queiy

name: Ralph
commanls: Enter comments
cradle, disc

name:
ca mm ants: Enlur comments
credit
*-; Lottrf w

Tt Locot n

. 3. f. bean

, bean. JSP- , . 3.1,


3.1,.
3.1,a. /form.jsp
<html><title>Textfields,
<body>

Text Areas,

and Radio Buttona</title>

<jsp:useBean id='form' class='beans.Form' scope='request'>


<jsp:satProperty name='form'
property='*'/>
</jsp:useBean>
<form>
Name:<input t y p e = ' t e x t ' name='name'
value='<%=form.getName()%>' /><p>
<input type='radio' name='credit' value='visa'
<%= form. cteditSelectionAttr ("visa") % v i s a
<input type='radio' name='credit' value='mc'
<%= form.creditSelectionAttr ("me") %master card<br>
<input type='radio' name=' credit' value=r disc'
<%= form.creditSelectionAttc("disc") %>>discovery
<input type^'radio' name='credit' valuer'amex'
<%= form.creditSelectionAttr("amex") %>>american express
</p><pxtextarea name='comments' cols='25'
rows='5'><%= form.getComments() %></textarea>

70

3. HTML-

</p><p><input type='submit'/></p>
</form>
<%@ include file='showForm.jsp' %>
</body></html>

)' beans . Form. j sp: setProperty . , .


, 3.1,, JSP- showForm. j sp.
, 3.1,6,
bean.
3.1,6. /showForm.jsp
<b>name:
</b> <%= form.getName()
<b> comments : </b> <% form, get Comment 5 (]
<b>credit:
</b> <%= f o r m . g e t C r e d i t ( )

showForm. jsp
include, .. . , showForm. jsp, form. ,
bean
form showForm. jsp.
bean, JSP- , 3.1,.
.1.. WEB-INF/classes/beans/Form.Java
package beans;
public class Form {
String name, comments "Enter comments", credit;
public void setName(String s) { name s; )
public String getNameO { return name ! = null ? name :
public void setComments(String s) ( this.comments = s;
public String getComments() ) return comments; }
public void setCredit(String s) ( credit = s;
public String getCredit0 {
return credit != null ? credit : " " ;

public String creditSelectionAttr(String creditName)

bean

71

iffcredit !- null) {
return credit.equals(creditName) ? "checked"
}

return " " ;

JavaBeans, Form , ,
(name), (comments) ( c r e d i t ) .
.
n u l l , " n u l l " , .
n u l l bean, JSP- . Java- JSP- .


HTML- s e l e c t o p t i o n .
s e l e c t , o p t i o n , :
<select name='years' s i z e = ' 5 ' multiple>
<option value='2000'>2000</option>
<option value='2001'>200K/option>
<option valuer'2002">2002</option>
. . . , . ,
</select>
2000, 2001 2002,
, ,
: "... years=2000Syears=2Q01&years=2002 ...". years , JSP-:
<% S t r i n g [ ] value= r e q u e s t . g e t P a r a m e t e r V a l u e s ( " y e a r s " ) %>
, , .
, , .
, . .
. 3.2 JSP- , .
, . 3.1. a c t i o n ,
,
Web- ,
Submit Query, .

72

3. HTML-
-IDixl

- ICl x\
fib

Edit

FjrfH!

loWl

looh

Find:

Find:

^ Stanley Cup Chimps


P SuparBowl Champs
World Series Champs
W NCAA Champs

F* Stanley Cup Champs


P Super Bowl Chimps
World Series Clumps
P NCAACtitmpt

For the following years:

For the following years:

-1
Submit unary |

Submit Query

t)>(>

Find; oianicj-cup super-bawl


d a t : 1 9 9 9 17 15

Si
. .2. bean

JSP-, . 3.2, 3.2,.
3.2,a. /form.jsp
<html><title>Checkboxes and Options</title>
<body>
<jap:u3eBean id='form' class='beans.Form' scopes'request'>
<jsp:setProperty name=' form' property='*'/>
</jsp:useBean>
<form>
<font size='5'>Find:</fontxbr>
<input type=f checkbox' name^'categories' valuer' stanley-cup'
<%= form.categorySelectionAttr("stanley-cup") %
Stanley Cup Champs<br>
<input type='checkbox' name='categories' value=' super-bowl'
<%= form,categorySelectionAttr{"super-bowl") %>>
Super Bowl Champs<br>
<input type='checkbox' name='categories' value='world-series'
<%= form.categorySelectionAttr("world-series") %
World Series Champs<br>
<input type='checkbox' name^'categories' value='ncaa'
<%= form.categorySelectionAttr("ncaa") %>>
NCAA Champs<br>
<pxfont size=' 5' >For the following years : </fontxbr>

bean
<select name='years' s i z e = f 5' m u l t i p l e >
<%
f o r f i n t year=1999; year
> 1989; year) { %>
<option value='< < b= year %>'
<%= f o r m . y e a r S e l e c t i o n A t t r ( I n t e g e r . t o S t r i n g ( y e a r ) )
<%=year%x/option>
<% } %>
</select>

73

</pXpXinput type=f submit'/x/p>


</form>
<i@ include file='showForm.jsp' %>
</bodyx/html>
, 3.1, JSP-
bean beans . Form .

.
,
JSP-, ,
. 3.2,6.
3.2,6. /showForm. j
if[form.getCategories() != null) ( %>
<b>find:</t
StringU strings = form.getCategories () ,for(int i=0; i < strings.length; ++i) ( %>
<%= strings[i] %>
)

if (form.getYearsO !- null) ( %>


<brxb>dates : </b>
<%
StringH strings - form.getYears (1 ;
for(int i=0; i < strings.length; ++i) ( %>
<%= strings[i] %>
S

bean, JSP-,
3.2, 3.2,6, 3.2,.
3.2,. /WEB-INF/classes/beans/Form. Java
package beans;
public class Form (
Stringf] years, categories;

74

3. HTML-
public String[] getCategories() ( return categories; 1
public void setCategories(String[] categories) {
this.categories - categories;
}

public String categorySelectionAttr[String category)


if (categories != null) {
for(int i=0; i < categories.length; ++i) \
if(categories[i].equals(category))
return "checked";

return " " ;


}

public String[) getYears() f return years; )


public void setYears(String[] years) [ this.years = years;

public String yearSeleetionAttr(String year) {


if(years != null) {
for(int i=0; i < years.length; ++i) {
if (years[i].equals(year) )

return "selected";

)
return " " ;

bean, 3.1,
, . , , , , , .
checked, selected, categorySelectionAttr yearSelectionAttr
"checkeci" "selected".


, ,
, .
JavaScript-, JSP-.
, , , . , , - JavaScript-.
, , ? . ,
, .

75


Ja vaScript-

JSP-, .
. 3.3 JSP-, ,
.
JavaScript-, ,
, '@* ". com" ". edu".
, . S.3 , ,
, .
K k r t SiA> V*Wion nth JiwaSdipt -Mtfaiuft Irtann... ___
11 f i b

diP

Jtlw

F^vti riT*i

Ipob

i^t

pit

P*Go

' A>*ft JXJ hup /tocdfrott.

Firsl Name:

'.tMVddaticn*nJmsScret -Mtusn Irtane .. . |p| K[


Edit

llcw

Fflmmra

IDOII

tjtt

Bp7l _^

jgeorei

Lsst Ma me

(nurt cortiin ^ end er*J in com c* i

E-mail Address: [
Submit Query

]>=

-.LoMlrwanfl

'

. 3.3. JavaScript

JSP-, . 3.3, ,1 3.3.


3.3./form.jsp
<htral><head>
<title>Client Side Validation with JavaScript</title>
</head>
<body>
<jsp;useBean id='form' scope='request' class='beans.Form'>
<jsp:setProperty name='form' property-'*'/>
</jsp:useBean>
<form name='simpleForm' onSubmit='return validate[)'>
<tablextr>
<td>First Kame:</td>
<tdxinput type='text' size=15 name='f irstName'
valuer' <%= form.getFirstName () %>' /></tdx/trxtr>
<td>Last Name:</td>
<tdxinput type='text' size=15 name=' lastbiame'
value='<%= form.getLastKame () %>' /></tdx/trxtr>

76

3. HTML-

<td>E-mail Address:</td>
<tdxinput type='text' size=25 name='emailAddress'
value='<%= form.getEmailAddress{) %>' /></td></tr>
</table>
<pxinput type=' submit' /></p>
</form>
<script language='JavaScript' >
function validate() (
var firstName = simpleForm.firstHame.value,
lastName = simpleForm.lastName.value,
emailAddress = simpleForm.emailAddress.value,
errorMsg = "",
errorDetected false;
if(firstName "" || lastName "" || emailAddress ""){
errorMsg += "Please fill in all fields";
errorDetected = true;
}
if(!isEmailAddressValid(emailAddress)) {
if (errorMsg.length > 0)
errorMsg += "\n";
errorMsg += "Email Address must contain @ and " +
"end in .com or .edu";
errorDetected = true;
)
if(errorDetected)
alert(errorMsg);
return !errorDetected;
)
function isEmailAddressValid(s) (
v a r a t S i g n = new R e g E x p ( " . * ( 8 ) . * " ) ,
d o t E d u = new R e g E x p ( " . e d u $ " ) ,
dotCom = new R e g E x p ( " - c o m $ " ) ;
return atSign.test(s)
}
</script>
</bodyx/html>

SS

(dotcom.test(s)

|I

dotEdu.test(s));

onSubmit ' r e t u r n
v a l i d a t e () ', .. JavaScript- v a l i d a t e .
v a l i d a t e true,
, .
,
bean.
, bean .

, , http://www.
phptr. /advj sp.

77

, 3.3, JSP JavaScript, JSP- HTML-


, JavaScripL- JSP.


JSP-
JSP . JSP-,
.
, 3,4 JSP-, ,
, 3,3. . 3.4 Submit Query, .
0 I S H V SWsVAiatiwi vi JSP - Micunoft lite >1
i [lie

dll

Firtl Name:

yitw

fffrtjrlm

Itotr

tV

| j ii>

Edit

in*

Favorittt

loois

.lalx|

; ; A * * H | ] |tp49iN.i.o>aoItlINH.l

Please fill in all fields.


Email addles; must contain @ and end in .cum sr.edu

Igeorge

L>!t Hum

ii

E-mail Address:

First Name: \ gen


La si Name |

Submit Query |

-mail Address: [
SubmitQueiy |

d
Local inlind

, .4. JSP-

, 3.3, . -, JavaScript-, -, a c t i o n v a l i d a t e , jsp.


<form name=fsimpleForm'

action^'validate.jspf/>

</form>
v a l i d a t e , jsp, 3.4.
3.4. /validate.jsp
String first = request.getParameter("firstName") ,
String
last request.getParameter{"lastName");

78

3. HTML-
String email = request.getParameter("emailAddress");
String errorMsg = "";
boolean errorDetected = false;
if(first.equals["") II last.equals("") M email.equals("")) {
errorMsg += "Please fill in all fields.";
errorDetected = true;
}
if(email.indexOf("g") = = - 1 ||
(!email.endsWith(".com") fiS lemail.endsWith(",edu"))} (
if(errorMsg.length() > D)
errorMsg += "<br>";
errorMsg += "Email address must contain 8 and " +
"end in .com or .edu";
errorDetected = true;

}
if(errorDetected) { %>
<%= errorMsg %>
<jsp:include page='form.jsp' flush='true'/>
<%
} else { %>
<jsp:forward page='registrationComplete.jsp'/>

JSP- request ,
JavaScript-, 3.3. , registrationComplete . j ,
Web- , , .


JSP-
. JSP-, ,
action,
ValidatiortServlet.
<form name='simpleForm'

action='ValidationServlet'/>

</form>
, , 3.5.
3.5./WEB-INF/clasaes/ValidationServlet.java
import Java.io.lOException;
import j avax.servlet.RequestDispatcher;
import javax.servlet.ServletException;

79

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServlet;
public class ValidationServlet extends HttpServlet (
public void service(HttpServletRequest req,
HttpServletResponse res)
throws IOException, ServletException {
String first = req.getParameter("firstName"),
last req.getParameter("lastName"),
email = req.getParameter("emailAddress"),
errorMsg = "", nextStop = "/registrationComplete.jsp";
boolean errorDetected = false;
if(first.equals("") II last.equals("") II
email.equals("")) {
errorMsg += "Please fill in all fields.";
errorDetected = true;

if(email.indexOf("@") =- -1 |[
(!email.endsWith(".cam") fi !email.endsWith(".edu"))) {
ifferrorMsg.length() > 0)
errorMsg += "<br>";
errorMsg += "Email address must contain @ and " +
"end in .com or ,edu";
errorDetected = true;
>
if(errorDetected) (
res.getWriter().print(errorMsg);
nextStop = "/form.jsp";
)
RequestDispatcher rd;
rd - getServletContext().getRequestDispatcher(nextStop);
if[nextStop.equals("/form.jsp"))
rd.include[req, res);
else
rd.forward(req, res) ;

C-T, 3.5, , JSP, 3.4. Java JSP-, , bean.


JSP
.

80

3. HTML-



,
, .
: ,
, - JavaScript-.

JSP-

,
, JSP. , HTML-, JSP- , . , jSP-
, , JSP- -.
, ,
JSP- .
, 3.5, ,
.
.
public class ValidationServlet extends HttpServlet {
public void service(HttpServletRequest req,
HttpServletResponse res)
throws IOException, ServletException {
String f i r s t = req.getParameter("firstName"),
last = req.getParameter("lastName"),
email req.getParameter("emailAddress"),
errorMsg "", nextStop 'VregistrationComplete.jsp";
boolean errorDetected = false;
if(errorDetected) {
req.satAttributa("validate-error",
nextStop "/form.jsp";
)

errorMsg);

81

,
JSP- :
<htmlxheadxtitle>Server Side Validation</title>
<%@ t a g l i b u r i - ' v a l i d a t e ' p r e f i x ^ ' v a l i d a t e ' %>
</head>
<body>
<4 String errorMsg = [String)request.getAttribute(
"validate-error");
if[errorMsg != null) { %>
<*= errorMsg %>
<% J >
<p>
<form name-'simpleForm'

action='ValidationServlet'/>

</form>
</p>
</bodyx/html>
JSP-,
, .
:
<htmlxheadxtitle>Server Side Validation</title>
<%@ taglib uri-'validate' prefix='validate' %>
</head>
<body>
validate: showValidateError/>
<form name=rsimpleForm'

action^'ValidationServlet'/>

</form>
</p>
</bodyx/html>
,
3.6.
3.6. /WEB-INF/olasses/tags/ShowValidateErrorTag.Java
package tags;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.TagSupport;
public class ShowValidateErrorTag extends TagSupport f
public int doEndTagO throws JspException (
String msg = (String)pageContext.getRequest().
getAttribute("validate-error")
if(msg != null) (
try (

82

3. HTML-
pageContext.getOut().print(msg);
}
catch(Java.io.lOException ex) {
throw new JspException(.getMessage());
return EVAL_PAGE;
\



bean,
. ,
, JSP- :
<jsp:useBean id='form' class='beans.Form*
scope='request *>
<jsprsetProperty name='form1 property^'*'/>
</jsp:useBean>
property j sp : s e t P r o p e r t y '*', JSP- Java- bean . , category JSP- setCategory.
, JSP-
category. .
Java- - beans,
:
( ), Java-.
JSP-,
.
bean. ( , 3.2,):
...
private String!] categories;

public String categorySelectionAttr(String category)


if [categories != null) (
for{int i=0; i < categories.length; ++i) {
if(categories[i].equals(category) J
return "checked";
return "";

83

categorySelectionAttr, , ,
category, "checked",
. HTML input. , ,
. ,
grocery bean , :
private String!] groceries;
public String grocerySelectionAttr(String grocery)
if(categories != null) {
for(int i=0; i < groceries.length; ++i) {
if(groceries[i].equals(grocery))
return "checked";

)
return " " ;

. ,
, facade.

fagade
HTML-
facade
. HTML- facade
, . 3.5.
JSP-

Form ( facade)

beans.html
( )

<inpLttype='te)tti
Textfield Element

form.getNam'eO %>' >

get Valued

<%if(form.validate()) {

validated

RadioElement
validate))

. 3.5. facade

84

3. HTML-

Fac-ade bean ,
beans .html, . . 3.5 ;
91 .
, fa$ade , . , . 3.5,
. , categorySelectionAttr
:
public class Form \
CheckboxElement categories = new CheckboxElement 0;
public String categorySelectionAttr() {
return categories.selectionAttr(category) ;

Form.categorySelectionAttr ,
HTML- input.
CheckboxElement, Form, ;
public class CheckboxElement (
private Stringtl items;
public String selectionAttr(String item) {
if [items !- null) (
f o r ( i n t i-0{ i < items.length; ++i) (
if(items[i].equals(item))
return "checked";
return " " ;
}
}

, , , .
, CheckboxElement,
, , . .


. ;
. ,
.

85

. 3.6 JSP-, ,
. a c t i o n , Submit Query .
| -
:

Fit!

grill

Vim

Fjwrutl

Tool;
*!

Nam&: |Rick

Language .
P Hint JSVJ P Peri Osp

Credit Card

Ccrnmftnts
ulist's this?

^ r-ll.4F.FP' - -* -1

am* i

Exairalion Date
D1/DO *

jj

Selet) FftJitr
orange ^|

iiSL

iH/OD
05/00.]

SubmJlOuny

J
j f l ( Local rtie

. .6.

JSP- Web-, . 3.6, ;
3.7,.
3.7,. / f o r m , j s p ()

<jsp:useBean id='form' class='beans.Form' scope='request'>


<jsp:setProperty name='form' property='*'/>
</jsp:useBean>
<form>
<% %>
Name: <input t y p e = ' t e x t ' name='name'
value='<%- form.getName() %>'/>
<% %>
Programming Language Experience:<br>
<input type='checkbox' name='languages' value='html'
<%= form.languageSelectionAttr("html") *> /> Html
<% %>
Credit Card:<br>
<input t y p e - ' r a d i o ' name='credit' v a l u e = ' v i s a '
<%- f o r m . c r e d i t S e l e c t i o n A t t r ( " v i s a " ) %>>
visa</input type='radio'><br>

86

3. HTML-

< % % >
Comments:<br>
<textarea name='comments' cols='20' rows='5'>
<%= form.getComments() ></textarea><p>
<% --%>
Expiration Date:<br>
<select name=' expiration' size=5>
<option <%= form.expirationSelectionAttr("01/00") %>
value=' 01/00'>01/00</option>
</select>
< % % >
Select a Fruit:<br>
<select name='fruit'>
<option <%= form.fruitSelectionAttr("apple") >
value='apple'>apple</option>
</select>
< % Submit i >
<pxinput type=' submit' /></p>
</form>
</bodyx/html>
;
JSP- beans . Form
.
bean .
bean, 3.7,, 3.7,6.
3.7,6. /WEB-INF/classes/beans/Formoava
package beans;
import
import
import
import
import

beans.html.CheckboxElement;
beans.html.OptionsElement;
beans.html.RadioElement;
beans.html.TextElement;
beans.html.TextAreaElement;

public class Form {


TextElement name = new TextElement();
RadioElement credit = new RadioElement();
TextAreaElement comments = new TextAreaElement();
CheckboxElement languages = new CheckboxElement();
OptionsElement expiration = new OptionsElement();
OptionsElement fruit = new OptionsElement(};
public String getName ( return name.getValue(); }
public void setKame(String s) ( name.setvalue(s); }
public String getComments() [ return comments.getValue();}

87
p u b l i c v o i d setComrrtents [ S t r i n g s)

( comments . s e t V a l u e (s) ;

public S t r i n g getCreditO { r e t u r n c r e d i t . g e t V a l u e ( ) ;
p u b l i c v o i d s e t C r e d i t ( S t r i n g s) ( c r e d i t - a e t V a l u e ( s ) ;

)
)

p u b l i c S t r i n g [ ] getLanguages() { r e t u r n l a n g u a g e s . g e t V a l u e ( ) ;
p u b l i c v o i d s e t L a n g u a g e s ( S t r i n g [ ] s) ( l a n g u a g e s . s e t V a l u e ( s ) ;

)
}

public S t r i n g [ ] g e t F r u i t ( ) [ r e t u r n f r u i t . g e t V a l u e ( ) ; }
public void s e t F r u i t ( S t r i n g ! ] s) { f r u i t . s e t V a l u e ( s ) ; t
public S t r i n g ! ] getExpiration() ( r e t u r n expiration.getValue ( ) ; )
public void s e t E x p i r a t i o n ( S t r i n g [ ] s) ( e x p i r a t i o n . s e t V a l u e ( s ) ; 1
public S t r i n g c r e d i t S e l e c t i o n A t t r ( S t r i n g s) {
return c r e d i t . s e l e c t i o n A t t r ( s ) ;
)
p u b l i c S t r i n g l a n g u a g e S e l e c t i o n A t t r [ S t r i n g s) {
return languages.selectionAttr(s);
]
public String expirationSelectionAttr(String s) (
return e x p i r a t i o n . s e l e c t i o n A t t r ( s ) ;
)
public String fruitSelectionAttr(String s) (
return f r u i t . s e l e c t i o n A t t r ( s ) ;

bean beans .html, TextElement, RadioElement . /WEB-INF/classes/beans/Form. Java, 3.2, , , , beans . html.
bean, 3.7,6, , , facade HTML-.
JSP-, . 3.6,
beans.html.
, . 3.7.
beans.html : , (,
, ), , (,
).
StringElement StringArrayElement.
, , , StringElement S t r i n g ArrayElement ValidateElement, 3.7,.

38

3. HTML-

ValicJaledElemenL
(from html)

galValidationErrarQ
StringEfement
Siring
getValuej)

(hem 1*nfl}

. 3.7. beans, html

3.7,. /WEB-INF/classes/beans/html/ValidatedElement. Java


package beans-html;
public interface ValidatedElement
boolean validate ;
String getValidationError() ;

ValidatedElement v a l i d a t e , ,
. , ..
v a l i d a t e false, getValidationError
, , .
StringElement 3.7,.

89

3.7,. /WEB-rNF/olaeaes/beans/html/StringElemant. java


package beans.html;
public class StringElement implements ValidatedElement I
final protected String emptyString = "";
private String value;
public void setvalue(String value) {
this.value - value;
)
public String getValueU {
return value !- null ? value : emptyString;
)
public boolean validated {
return true;
)
public String getValidationError() (
return emptyString;

I
StringElement , getValue. , . ,
null, HTML-,
, StringElement,
. ,
validate getValidationError. .
TextElement TextAreaElement StringElement,
.
.
public class TextElement extends StringElement {1
public class TextAreaElement extends StringElement 1}
TextElement TextAreaElement
, . , , .
StringArrayElement,
CheckboxElement OptionsElement, 3.7,.
3.7,. /WEB-IKF/classes/beans/html/StringArrayElement.Java
package beans.html;
public abstract class StringArrayElement
implements SelectableElement, ValidatedElement {
final String emptyString " " ;
private String[] value;

90

3. HTML-

public void setValue[String[] value)


this.value = value;

public 3tring[] getValueO f


return value != null ? value : new String[ ]{}
I
public boolean validated (
return true;
}

public String getValidationError[)


return " " ;

public boolean contains(String s) {


String!] strings - getValueO;
for(int i=0y i < strings,length; ++i)
if(strings[i].equals(s))
return true;

return false;

StringArrayEleraent StringElement, ,
StringArrayEleraent . StringElement,
StringArrayElement no .
contains ,
StringArrayElement. , ,
.

,
, .
. SelectableEleraent,
3.7,.
3.7,. /WEB-INF/classes/beans/html/SelectableElement. }ava
package beans.html;
public interface SelectableElement {
String selectionAttr(String s};

SelectableElement RadioElement, CheckboxElement Opt ions Element. , , selectionAttr "checked"

91

"selected". , .
.
// emptyString
// StringElement protected.
public class RadioElement extends StringElement
implements SelectableElament {
public String selectionAttr(String value) {
return getValue().equals{value) ? "checked" : emptyString;

public class CheckboxElement extends StringerrayElement {


public String selectionAttr(String s) (
return contains(s) ? "checked" : amptyString;

public class OptionsElement extends StringArrayElement {


public String selectionAttr(String s) (
return contains(s) ? "selected" : emptyString;
}

J
, beans . html, . , ValidatedElement. ,
, .


JSP-, . 3.8,
. , , , , . . 3.8 , .

. a c t i o n
JSP-, .
// form ,
// 3.7,.
<form a c t i o n = ' v a l i d a t e . j s p 1 >
v a l i d a t e , j sp, 3.8,.

92

3. HTML-

'

NVM: I "

Pr&grammlng Ljnguaoa E a p e i ^ n t t

The form was not filled out correctly because

Him r j m T Pari jip


Ntma caw.fll contj.n
Commims

radii Cditf must li

Credd Cird:

r vii

1" maste Call

!
fttyW *

UntJ J^ r p d T J i p
CDmmenls
Cndil Card:

discovery

SitM i Fnft

O-VtD
/C-D *

matter card

dtaccvary

EKpirsiiu^Data.

5 F * C a Prun

oppl

il

owo_
ow
SutifrJUXmy

. .8.
... /validate.jsp
<jsp:useBean id-' form' class='beans.Form' scope='request'>
<jsp:setProperty name='form' property^''/>
</jsp:useBean>
<% String errorMsg = "";
boolean errorDetected false;
if(Jform.validate!)) (
errorMsg += form.getValidationError();
errorDetected = true;
}

if(errorDetected) { %>
<font c o l o r s ' r e d ' size='5'>
The form was not f i l l e d out correctly because:<p>
</fontxfont size='3'>
<%= errorMsg %></fontx/p>
<jsp:include page='form.jsp' flush='true'/>
<% ) e l s e { %>
<jsp:include page='registrationComplete.jsp' fluah='true'/>

v a l i d a t e , j s p bean form.
. , . , , bean, . , JSP-.

93
v a l i d a t e . j sp setProperty, . , JSP, Java- bean .
bean, , 3.8,6.
3.8,6. /WEB-INF/classes/beans/Form. Java
//
// 3.7,6
public class Form implements ValidatedElement (
private CreditElement c r e d i t = new CreditElement()
private NameElement
name = new NameElement();
private String e r r o r ;
public boolean validate () 1
error = "";
if(Iname.validate(}) {
error += name.getValidationError [ ) ;
}

if(!credit.validate()) {
if(error.length!) > 0)
error += "<br>";
error += credit.getValidationError(};
)
return error == "";
}
public String getValidationError() {
return error;

bean, 3.8,6, , 3.7,6. ,


TextElement CheckboxElement NameElement
CreditElement. , v a l i d a t e , . , .
NameElement CreditElement
TextElement CheckboxElement. , ValidatedElement. CreditElement 3.8,.

94

3. HTML-

3.8,. /WEB-INF/claasea/beans/CreditElement. Java


package beans.html;
public class CreditElement extends RadioElement {
private String error;
public boolean validate () (
boolean valid = true;
String value = getValue();
error = "";
if(value null || value.length{) == 0) (
valid = false;
error = "Credit card must be selected";
)
return valid;
}
public String getValidationError() (
return error;

validate CreditElement true,


, false .
NameElement 3,8,.
3.8,. /WEB-INF/claases/beans/NameElement.Java
package beans.html;
public class NameElement extends TextElement (
private String error;
public boolean validated {
boolean valid = true;
String value = getValueO;
error = "";
if[value.length == 0) {
valid - false;
error - "Name field must be filled in";
1
else (
forfint i=0; i < value.length (); ++i) {
.char value. charAt (i) ;
if (c == v ' Illc > "0' st < ' 9 ' ) M
valid = false;
if[c ' M
error = "Name cannot contain spaces";

95

else
error = "Name cannot contain digits";

return valid;
)

public String getValidationError(J [


return error;

,
NameElement. v a l i d a t e t r u e .
, .
bean ,
v a l i d a t i o n g e t V a l i d a t i o n E r r o r .



JSP-. , ,
, .
.
, , .


, , HTML- Web-. , , s e l e c t , . HTML
, , JSP. , s e l e c t 2,
,
HTML- form. ,
focus,
. 3.9,.

96

3. HTML-

3.9,. form
r

<%@ t a g l i b u r i = ' f o r m . t l d prefix='html' %>


<%-- name
--%>
<html:form name='myForm' focus='name' method='post'>
<%--
3.7, %>
</htrrd: f orm>
, , 3.9,, , . 3.8. ,
name.
, 3.7,.
form 3.9,6.
3.9,6. /WEB-INF/classes/tags/FormTag.Java
package tags;
import javax.servlet.jsp.*;
import javax.servlet.jsp.tagext.*;
public class FormTag extends BodyTagSupport (
public String method, name, focus;
public void setName(String name} { this.name * name; }
public void setMethodfString method} ( this.method = method; )
public void setFocus(String focus) { this.focus * focus; }
public int doEndTag() throws JspException [
try {
String body = bodyContent.getString();
bodyContent.clearBody();
StringBuffer buffer = new StringBuffer(
"<form name='" + name + pl1 method^'" + method + " 1 > "
+ body + "\n</form>\n" +
"<script language='JavaScript'>\n" +
"document." + name + "." + focus + ".focus[)" +
"\n</script>");
bodyContent.print(buffer.toString
());
bodyContent.writeOut(pageContext.getOut());
(
catch(Java.io.IOException ex) (
throw new JspException(ex.getMessage [)};

return EVAL__PAGE;

97
. .
HTML.
, 3.9,6, HTML-
form method name. , , , , a c t i o n , . ;
, method name.
JavaScripl-c. , JavaScript-, , . , .

HTML-. : Memento,
bean, facade,
)'. ,
, .
,
HTML- form. .
JSP- HTML-,
.

Apache Struts:
http://Jakarta.apache.org/struts/index.html

oeaJSP-ecpLlopoIN16:
http://sourceforge.net/projects/jsptags/
Form:
http://cupid.saninternet.com/~joeo/Form.html

...

.
.
, .
.
.
.

.

, : , .
. , , ; ,
'.
,
Composite Strategy"'. Composite
; ,
. ,
, .
.
Strategy,

. ,
, .
JSP , .
B J S P
Web-, , , . (Web-KOMitoHCHTaMH , HTML- JSP. Web- , .)
Web-, .
, ,
, ,
. , .

1. Geary, Graphic Java Volume 1:AWT, Prentice Halt, 1998. - . .


2. Gamma, Helms,Johnson, Vtissides. Design Patterns, Addhon-Wesky, 1994. - . .

100

4.

(section) , HTML JSP .

(region) , .

(template) JSP-,
.
. ,
(HTML- JSP-) , .
. JSP-
, . bean.
, , J2EE Composite View
, bean . (Alur), (Crupi) (Malks)
CoreJ2EE Patterns, Prentice Hall Sun Microsystems Press.


, , .
- : , ,
.
Web- . , ,
. 4.1, , ,
.
Web-
t a b l e . JSP- 4.1.
4 . 1 .
<htmlxhead>
<title>A JSP Page Without Templates</title>
</head>
<body

background^'graphics/blueAndWhiteBackground.gif'>

<table>
<tr valign='top'>
<td>
<jsp:include page='sidebar.jsp' flush='true'/>
<7td>
<td>


<table>
<tr>
<td>
<jsp:include page='header.jsp' flush='true'/>
</td>
</tr>
<tr>
<td>
<jsp:include page='introduction.jsp' flush='true'/>
</td>
</tr>
<tr>
<td>
<jsp: include page=' footer.. jsp' flush^' true' />
</td>
</tr>
</table>
</td>
</tr>
</table>
</body>
</html>

Hcn^l IrHM E *

3 <**
/

S Chapter 4. Tarpates
JAVA

IntroducHon
Window Tuolkr& 1ypical> provide a tayDUI mechanism lhai poenions widgelg en a contain^
(orfKsir:plf. AWT and Swing nave Ijyoijl manajtrs, wlnrns VisuilWori<5 Smilllslk has

Because layoul undeigoes changes mar Ihe course of dmlopmenl ft impctiintto


encspsulate tiiai fund ions In liyout can bs mgdiOsd with minimal iimpaci in Ihe ratt at
[he ipplicalion In fact, layoul managers are an \ of one of the tenets of abjectonenisd design encapsulate Hi) concepl Ihst wiati which is also a tundamemal theme
for many design pstltrns.
JSP doss Tint provids direct support fat ancipsutiting layout, to web pages with iderrtLC.il
(ormals usually replicate layoul cotfe; Sneamplg A,web Pa;ie Latnai aiiwra a web page
conuinmg socticr.s for a header, fooler, sidebar, a^d main concent

wthoulmoinvrtelIlestr>wjierteiiv>b1 large websTfes


identical formats, eirch a mechanism is valuable bacauef it localize changes to
That mechfnitm is JSP templates

. 4.1. Web-

101

102

4.

, 4.1, j sp: include.


, , .
, Web- . Web- Web- , .
Web-, , 4.1, Web- . , eJSP-.

,

.
JSP-, ( 4.1),
: , , , . 4.2,.
4.2, . JSP-,
taglib uri= f regions' prefix^'region' %>
<region:render template=' /template.j sp'>
<region:put s e c t i o n ^ ' t i t l e '
content= Templates' direct^'true'/>
<region:put section='header' content= /header.jsp' />
<region:put section='sidebar'content^ /sidebar.jsp' />
<region:put section^'content'content= /introduction.jsp' />
<region:put section^'footer' content='/footer.jsp' />
</region:render>

, , . , 4.1.
,
template region: render. region : render
(region) .
.
region:put - ,
region: render. ; , ,
4.2,, , header,
/header . j sp.
region: render , template. 4.2,6.

103

4.2,6. , ,
4.2,.
<$@ taglib uri-'regions' prefix^'region' %>
<htmlxhead>
<title><region:render s e c t i o n ^ ' t i t l e ' / > < / t i t l e >
</head>
5

<body background ^' graphics /blueAndWhiteBackground.gif'>


<table>
<tr valign='top'>
f

<region:render section= sidebar'/>


</td>
<td>
<table>
<tr>
<td>
<region:render section='header'/>
</td>
</tr>
<tr>
<td>
<region:render section^'content'/>
</td>
</tr>
<tr>
<td>
<region:render section^'footer'/>
</td>
</tr>
</table>
</td>
</tr>
</table>
</body>
</html>
, , 4.2,6,
region: render.
, . region: render , ,
. ( , region: render , .)
region : render d i r e c t .
t r u e , region: tender, ,
out. , 4.2, t i t l e ("Templates") .

104

4.

Web-, Web- , , 4.2,6, JSP-, (


4.2,). .

. , JSP-, 4.2,,
/header, jsp, 4.2,.
4.2,. /header, jsp
<table>
ctdximg src=' graphics/java.gif /></td>
ctdximg =' graphics/templates.gif /></td>
</tr>
</table>

<hr>

/header. j sp , . , /header. j sp HTML- html, head, body ..


. /header . j sp .
r e gion: render r e g i o n : p u t , . , , , . .

Web-
, )' Web-. , Web-, . , ^-, .


, , ,
. , . 4.2 , . ,
, , .
. 4.2, ,
.

Specifying All Content:


SIDEBAR

Omitting Content:
HEADER

SIDEBAR

HEADER

CONTENT

FOOTER

FOOTER

. 4.2.
}5-, . 4.2, 4.3,.

4.3,.
<I3 taglib uri='regions' prefix='region' %>
<table>
<tr>
<td valign='top'>
<font size='5'>Specifying All Content:</font>
f
<table cellspacing= 20'>
<tr>
<td>
< % % >
<region:render template='hscf.jsp'>
<region:put section='header'
content='/header.jsp'/>
<region:put section^'sidebar'
content='/sidebar.jsp'/>
<region:put section='content'
content='/content.j sp' />
<region:put section='footer'
content='/footer,jsp' />
</region:render>
</td>
</table>
</td>
<td valign='top'>
<font size='5'>0mitting Content:</font>
<table cellspacing='20f>
<tr>
<td>
< % % >

105

106

4.
<region:render template'hscf,jsp'>
<region:put section-'header'
content'/header,jsp'/>
<region:put

section^'sidebar'
content'/sidebar.j sp' />

<region:put section='footer'
content='/footer.j sp'/>
</region:render>
</td>

</tr>
</table>
</td>
</tr>
</table>

JSP- JSP-,
, . , /sidebar, j sp :
<font size'5'>SIDEBAR</font>
JSP-, ,
/sidebar, jsp , . ,
/header. j sp :
<font size='5f>HEADER</font>
, , JSP-, 4.3,, . .
4.3, /hscf. j sp 4.3,6.
4.3,6. /hscf. js P : , 4.3,
<htmlxhead>
<%@ taglib uri='regions' prefix'region' %>
</head>
<table border-'1' width='500'>
<tr> < % , % >
<td valign'top' width='25%'>
<region:render section='sidebar'/>
</td>
<td valign'top' align='center' width='*'>
<table height'300'>
<tr> < % % >
<td align='center' height^'20%'>
<region:render section='header'/>
</td>
</tr> < % % >
<td align='center' height='*'>
<region:render section='content'/>

107

</td>
</tr> <i %>
<td align='center' height='15%'>
<region:render section='footer'/>
</td>
</tr>
</table>
</td>
</tr>
</table>
</bodyx/html>

, 4.2,6, ,
4.3,6, t a b l e .
, , 4.3,6, . ,
.

,
Web-
. , , . 4.3, JSP- , ,
curator.
; ^ HUUI H - V e<*n

e Jtanrinjfnndt E d

-JQJJU

The Antique House

14* 'iHw Fjfriirt Ic

8*d

curator

P*tc. 4.3. ,

108 4.
, . 4.3, :
<table>
<tci><region:render section='editPanel' role='curator'/></td>
</table>
*

region:render , role. role


, ( ) .
e d i t P a n e l ,
curator. , . , , .
, r o l e region: put.
:
<region:render template='hscf.jsp' >
<region:put section='header' content='/header.jsp'
role-'curator'/>
</region:render>
header , region: render, , curator.


.
, , JSP-, . 4.4.
1 : //bcjhw / - ! few
lh

Bill

il

SIDEBAR

HEADER
CONTENT
FOOTER

S] Done

. 4.4.

109

JSP-, . 4.4, , . , 4.4, .


4.4.
<%@ t a g l i b u r i = ' r e g i o n s ' prefix='region' %>
<table>
<td>
<%-- s %>
<region:render teraplate='hscf,j sp'>
<region:put section='header'
content"'/header.jsp'/>
<region:put section='sidebar'
content^'/sidebar.jsp'/>
f
<region:put section= content' c o n t e n t ^ ' / c o n t e n t . j s p ' / >
<region:put section='footer'
content-'/footer.jsp'/>
</region:render>
</td>
</tr>
</table>
. , 4.5 JSP-, . 4.4,
.
4.5,. JSP-,
<%@ t a g l i b u r i = ' r e g i o n s ' prefix^'region' %>
<%@ include f i l e = ' / r e g i o n D e f i n i t i o n s . j s p ' %>
<region:render region^'SIDEBAR_REGION'/>
, 4.5,,
SIDEBAR_REGION, /regionDef i n i t i o n s . j s p ( 4.5,6).
4.5,6. /regionDefinitions. j s p :
<%? taglib uri='regions' prefix='region' %>
<region: define id=' SIDEBAR_REGlOlsr scope=' application'
template='hscf.jsp' >
<region:put section='header'
content='/header.jsp'/>
<region:put section^'sidebar'
content='/sidebar.jsp'/>
<region:put section^'content' content='/content.jsp'/>
<region:put section='footer'
content='/footer.jsp'/>
</region:define>

110

4.

SIDEBAR_REGION, , 4.5,6
region:define.
id scope. region : define template, , .
region: render, region: define region:put, ,
region: define.
, , , ?
, .
. ,
, ,
.



Composite, .
. 4.5.

&

"

iSIDEBAR

HEADER
TOP

LEFT

RIGHT

BOTTOM
FOOTER

. 4.5.

JSP-, . 4.5, JSP-, 4.5,. JSP SIDEBAR_


REGION, 4.5,.

111

4.5,. /regionDefinitions. jsp


<
%
@ taglib uri='regions' prefix^'region' %>
cregion: define id='SIDEBAR_REGION' scope='application'
template='hscf.jsp' >
<region:put section^'header'
content='/header.jsp'/>
<region:put section^'sidebar'
content='/sidebar.jsp'/>
<region:put section='content' content='BORDER_REGION'/>
<region:put s e c t i o n = ' f o o t e r '
content='/footer.jsp'/>
</region:define>
<region:define id='BORDER_REGION' scope=' a p p l i c a t i o n '
template^'tlbr.jsp' >
<region:put s e c t i o n = ' t o p '
content=F/top.jsp'/>
<region:put s e c t i o n = ' l e f t '
content='/left.jsp'/>
<region:put s e c t i o n = ' r i g h t '
content='/right.jsp'/>
<region:put s e c t i o n = ' b o t t o m ' c o n t e n t = ' / b o t t o m , j s p ' / >
</region:define>
SIDEBAR_REGION c o n t e n t B0RDER_REGION. , BORDER_REGION SIDEBAR_REGION.
, BORDER_REGION ,
SIDEBAR_REGION. , SIDEBAR_REGION lie
BORDER_REGION SI DEBAR_REGION.
, ,
4.5,; BORDER_REGION.

4.5,. , BORDER^REGION
<html><head>
<%@ t a g l i b u r i = ' r e g i o n s ' prefix^'region' %>
</head>
<table border='2' width='500'>
<tr> <% Top %>
<td colspan='2' a l i g n = ' c e n t e r ' height^'50'>
<region:render section^'top'/>
</td>
</tr>
<tr> < % Left Right % >
<td aligns'center' width='50%' height-'150'>
<region:render section='left'/>
</td>
<td align='center' width='50%' height='150'>
<region:render section^'right'/>
</td>
</tr>
<tr> < % Bottom --%>
<td colspan='2' align='center' height='50'>
<region:render section^'bottom'/>

112

4.
</td>

</tr>
</table>

</bodyx/html>
, 4.5,, top, l e f t , r i g h t
bottom, BORDER_REGION. BORDER_REGION
AWT BorderLayout, .


. , JSP-, . 4.6,
, SIDEBAR_REGION,
.
JSP-, . 4.6, 4.6,.
JSP-, 4.5,,
4.6, JSP-, . EXTENDED_SIDEBAR_REGION.
i:1iiip/AK<hHtMn/'4iarBMn-iinnidiltp-NlniigltMvniF<to>f
PI ll lit* Fjwlttt Iwd t*t>
; ** | Wlp //bulhg1rOH!"lv>ni/nja..wh

SiDEBAR

TO

UOljEl
^J

OVERRIDDEN HEADER

CONTENT
::

OVERRIDDEN FOOTER
J
. 4.6.

4.6, .
t a g l i b u r i = ' r e g i o n s ' prefix='region' %>
<%Q include file-'/regionDefinitions-override.jsp' %>
<region:render region='EXTENDED_SIDEBAR_REGIOK'/>

113

JSP-, SIDEBAR_REGION EXTENDED_SIDEBAR


REGION, 4.6,6.
4.6,6. /regionDefinitions-override.
<$@ t a g l i b u r i = ' r e g i o n s '

prefix^'region'

l>

<region:define id='SIDEBAR_REGION' scope-' a p p l i c a t i o n '


tempiate='hscf.jsp'>
<region:put section^'header'
content"'/header.j sp'/>
<region:put section^-' sidebar' content"5' /sidebar, jsp' />
<region:put section^'content'
content='/content.jsp'/>
<region:put section1*'footer'
content='/footer,jsp'/>
</region:define>
<region:define

id='EXTENDED_SIDEBAR_REGION'

scope=' application'

region-'SIDEBAR_REGION'>
<region:put section-'header' content=' /overridden-header.jsp'/>
<region:put s e c t i o n - ' f o o t e r ' content=' /overridden-footer.jsp'/>
</region:define>
, , SIDEBAR_REGION, 4.6,6. ; , , EXTENDED_
SIDEBAR_REGION SIDEBAR_REGION.

. , EXTENDED_
SIDEBAR_REGION SIDEBAR_REGION, EXTENDED_
SIDEBAR_REGION SIDEBAR_REGION. ,
region:put EXTENDED_SIDEBAR_REGION ,



, , Web-, , , . 4.7.

, .
JSP- , . 4.7, 4.7,.
4.7,a. /index, jep
<*@ t a g l i b u r i = ' r e g i o n s ' prefix='regions' %>
<
%
@ include file='/regionDefinitions-override.jsp' %>
region:render region='EXTENDED_SlDEBAR_REG!ON'/>

114

4.

j hUp7A>caliaifc8G8Q/regiora/ - MBIDUH Internet Expfcnr


Ella

dir

yiw

F^^rltes

Took

._. 1 D| _xj

|jv^

jfut |4Jj kirp //lucalTosLaOSO/iegou/

OVERRIDDEN HEADER

TOP

OVERRIDDEN TOP
LEFT

RIGHT
LEFT

Direct

nnrent

HEADER
CONTENT

FOOTER

BOTTOM

OVERRIDDEN BOTTOM

FOOTER
#] Done

TsLoodf*l

. 4.7.
JSP- 4.7,6.
4.7,6. /regionDefinitions-override.isp
taglib uri='regions1 prefix-'region1 %>
<region:define id=1SIDEBAR^REGION' scope-'request'
template-'hscf.jsp'>
<region:put section-'header' content='/header.jsp'/>
<region:put section-'sidebar' content='EXTENDED_BORDER_REGION'/>
<region:put section-1content' content='/content.jsp1/>
<region:put section-'footer' content=1/footer.jsp'/>
</region:define>
<region:define id='BORDER_REGION' scope=Trequest'
template^'tlbr.j sp'>
<region:put section^ 1 top 1
content='/top.jsp'/>
<region:put section =1 bottom 1 content='/bottom.jsp'/>
<region:put section^1left'
content =1 /left.jsp'/>
1
<region:put section^'right
content =l /right.jsp 1 />
</region:define>
<region:define id='EXTENDED_SIDEBAR_REGION' scope-1request'
region='SIDEBAR_REGION'>
<region:put section='header' content-'/overridden-header.jsp'/>
<region:put section-'sidebar'content='BORDER_REGIONT/>
<region:put section-1content'content='SIDEBAR_REGIOM'/>
</region:define>
<region:define id-'EXTEHDED_BORDER_REGION' scope-'request'
region-'BORDER_REGION'>
<region:put section^ 1 top 1
content='/overridden-top.jsp'/>

115

<region:put s e c t i o n ^ ' b o t t o m ' c o n t e n t = ' / o v e r r i d d e n - b o t t o m . j s p ' / >


<region:put s e c t i o n = ' r i g h t * >
<font s i z e = ' 4 ' > D i r e c t Content</font>
</region:put>
</region:define>
, 4.7,6,
, , .
.
EXTENDED_SIDEBAR_REGION ,
. 4.7. SIDEBAR_REGION header, s i d e b a r c o n t e n t . s i d e b a r c o n t e n t
EXTENDED_SIDEBAR_REGION BORDER_REGION
SIDEBAR_REGION.
SIDEBAR_REGION s i d e b a r EXTENDED_BORDER__REGION. BORDER_REGION top, bottom r i g h t . ,
r i g h t EXTENDED_BORDER_REGION r e g i o n : p u t .
.

, , bean .
.

bean
bean, , , . 4.1.
beans . r e g i o n s .

4 . 1 . bean
( beans. regions)

Content

JSP

PageContext

Section

Region

RegionStack

(region), (scope)

116

4.

beans, . 4.1, . 4.8.


.

Content

*Contern[)

toSlrinaO

#comeni

String

05 > tr pet jr *

\
Section

Region

\
L

sections
^I&n[j9rQ
^loStringO

Has hi able
(Turn krtlfj

guSectiomO

. 4.8. bean

Content ,
Section Region. Content
(), , Composite.
Section Region
Content render. Region - .
Content 4.8,.
4.8,. /EB-INF/cl.../b. U
package beans.regions;
import javax.servlst.jsp.JspException;
import javax.servlet.jsp.PageContext;
public abstract class Content implements Java.io.Serializable
protected final String content, direct;
// JSP-
abstract void render(PageContext pc) throws JspException;
public Content(String content) {
this(content, "false");

1
public Content(String content, String direct) {
this.content content;
this.direct = direct;

117

public String getContent () {


return content;
}

public String getDirectO (


return direct;
)
public boolean isDirectO {
return Boolean.valueOf(direct).booleanValue[);
)
public String toStringO (
return "Content: " + content,-

Content : content d i r e c t .
content ,
render, d i r e c t , . d i r e c t t r u e , ,
direct false,
.
Section 4.8,6.
4.6,6. /WEB-iNF/clasaes/beans/templates/Section. Java
package beans.regions;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.PageContext;
//
//
//
//
//
//
//
//
//
//

Section Content,

Content.render. Content.render ,
.

direct, Section.
,
; Region.render
Section.Render().

public class Section extends Content {


protected final String name;
public Section(String name, String content, String direct) (
super(content, direct);
this.name = name;

I
public String getNameO {
return name;
)
public void render(PageContext pageContext)
throws JspException (
if {content ! = null) (

118

4.
//
Region region = (Region)pageContext.
findAttribute(content);
if(region ! = null) (
//
RegionStack.push{pageContext, region);
region.render(pageContext) ;
RegionStack.pop(pageContext);
}
else {
if (isDirectO ) {
try {
pageContext.getOut().print(content.toString())
}
catchfjava.io.lOException ex} (
throw new JspExceptionfex.getMessage());
else {
try {
pageContext.include(content.tostring());
}
catch(Exception ex) {
throw new JspException(ex.getMessage()I

)
public String toStringO {
return "Section: " + name + ", content= " +
content.toString();

Section Content render.


d i r e c t true,
out. d i r e c t false,
Section JSP-.
, Section
( 4.8,).
Section .
Region 4.8,.
4.8,S. /WEB-INF/classes/beans/templates/Region. Java
package beans.regions;
import
import
import
import

Java.util.Enumeration;
Java.util.Hashtable;
javax.servlet.jsp.PageContext;
javax.servlet.jsp.JspException;

119

// ,
// .
public class Region extends Content {
private Hashtable sections = new Hashtable ();
public Region(String content) {
this(content, null); // content -
}
public Region(String content, Hashtable hashtable) {
super(content);
if(hashtable != null)
sections = (Hashtable)hashtable.lone ();
}
public void put(Section section) {
sections.put(section.getName(), section);

public Section get (String name) (


return (Section)sections.get(name);
}
public Hashtable getSections() {
return sections;
}
public void render[PageContext pageContext)
throws JspException {
try {
pageContext.include(content);

J
I

catch(Exception ex) ( // lOException ServletException


throw new JspException(ex.getMessage());
)

public String toStringO {


String s = "Region: " + content.toString() + "<br/>";
int indent = 4;
Enumeration e - sections.elements();
while(e.hasMoreElements()) {
Section section = (Section)e.nextElement();
for(int i=0; i < indent; ++i) {
s += "&nbsp;";
>
s += section.toStringO + "<br/>";

I
return s;

>

S e c t i o n , Region C o n t e n t r e n d e r . Region - . Region . g e t


Region. g e t S e c t i o n s . , - .

120

4.

(scope) (region) .
RegionStack,
4.8, .
4.8,. /HEB-INF/classaa/beans/templates/RegionStack. Java
package beans.regions;
import
import

javax.servlet.jsp.PageContext;
java.util.Stack;

public class RegionStack {


private RegionStack() { } //
public static Stack getStack(PageContext pc) (
Stack s (Stack)pc.getAttribute("region-stack",
PageContext.AFPLICATION__SCOPE);
if (s "- null) {
s = new Stack[);
pc.setAttribute("region-stack", s,
PageContext.AFPLICATION_SCOPE);
)
return s;
)
public static Region peek(PageContext pc) {
return (Region)getStack(pc).peek();
}
public static void push(PageContext pc, Region region){
getStack(pc).push(region);
}
public static Region pop(PageContext pc) {
return (Region)getStack(pc).pop();

,
. RegionStack ,
.


, , , 4.2.

121

4.2. ,
( , ,
tags. regions)

RegionTag

RegionDefinitionTag RenderTag

RegionDefinitionTag

(region) (scope)

RenderTag

PutTag

(region)

. 4.9.

BodyTagSuppnrt

Region
( 1

(fregion

>0

get Sections!)
tenderf)

9findftegionByKeyO
i*creale RegionF tomTeivtfilataO
^ c r e ale Regi nFro mRe gion 0
pvtO

SodyTagSupportQ
doAflenSodyO
doEndTagO

gO

geLBodyConlentO
geLPreviousOutO
leleasaQ
setBodyContentO

RegionDefinrtionTag
setScopeQ
doStartTagg
*dEfTO
getScop
released

set Se

PuiTag
selSeclionQ
selDiraclO
setContentQ
geiSectionO
getRoteQ
gatContentfl
getDirsclO
doMerBocfyO

. 4.9. ,

122

4.

region; render region:


define, RenderTag
RegionDef initionTag.
RegionTag, RenderTag RegionDefinitionTag. RegionTag, , TagSupport.
PutTag region:put.
BodyTagSupport, .. .
RegionTag 4.9,.
4,9,a. /WEB-IKF/claases/tags/regions/RegionTag.
package tags.regions;
import javax,servlet.jsp.JspException;
import javax,servlet.jsp.PageContext;
import javax.servlet.jsp.tagext.TagSupport;
import beans.regions.Section;
import beans.regions.Region;
public class RegionTag extends TagSupport {
protected Region region = null;
protected String template = null;
private String regionKey = null;
public void setTemplate(String template) {
this.template = template;
}
public void setRegion)String regionKey} {
this,regionKey - regionKey;
}
protected boolean findRegionByKey() throws JspException {
if [regionKey l= null) {
region = (Region)pageContext.findAttribute(regionKey);
if (region = null) (
throw new JspException("can't find page definition " +
"attribute with this key: " +
regionKey);
>
}
return region != null;
}
protected void createRegionFromTemplate() throws JspException (
if[template = null)
throw new JspException("can't find template");
region = new Region(template);
}
protected void createRegionFromRegion() throws JspException {
findRegionByKey();
if(region = null)
return;

123

region = new Region(region.getContent(),


//
region.getsections[)); //
)
public void put(Section section) {
region.put(section);
)
public void release() (
super.release();
region = null;
regionKey = null;
template = null;

, template region. RegionTag set , , ,


. RegionTag.
RegionDefinitionTag 4,9,6.
4.9,6. /WEB-INF/ classes/ tags/regions /RegionDefinitionTag. Java
package tags.regions;
import javax.servlet.j sp.JspExcept ion;
import j avax.servlet.j sp.PageContext;
import javax.servlet.jsp.tagext.TagSupport;
import beans.regions.Content;
import beans.regions.Region;
public class RegionDefinitionTag extends RegionTag {
private String scope = null;
public void setscope(String scope) (
this.scope = scope;
)
public int doStartTagO throws JspException {
if(region != null && template t= null)
throw new JspException("regions can be created from " +
"a template or another region," +
"but not both");
createRegionFromRegion();
if(region == null)
createRegionFromTemplatet);

return EVAL_BODY_INCLUDE;

public int doEndTag() throws JspException (


pageContext. setAttribute (id, region, getScope {));
return EVAL PAGE,-

124

4.

protected int getScope() {


int constant = PageContext.FAGE_SCOPE;
scope - (scope null) ? "page" : scope;
if("page".equalsIgnoreCase(scope))
constant = PageContext.PAGE_SCOPE;
else if("request".equalsIgnoreCase(scope))
constant = PageContext.REQUESTJ3COPE;
else if{"session",equalsIgnoreCase(scope))
constant = PageContext.SESSION_SCQPE;
else if("application".equalsIgnoreCase(scope)
constant PageContext.APPLICATION_SCOPE;
return constant;
}
public void released {
super.release() ;
scope "page";

RegionDefinitionTag RegionTag
, . ,
region template, RegionDefinitionTag. doStartTag . , , .
RenderTag 4.9,.
4.9,. /WEB-INF/classes/tags/ragion3/RenderTag.Java
package tags.regions;
import
import
import
import

javax.servlet.http.HttpServletRequest;
javax.servlet.jsp.JspException;
javax.servlet.jsp.PageContext;
javax.servlet.jsp.tagext.TagSupport;

import
import
import
import

beans.regions.Content;
beans.regions.Section;
beans.regions.Region;
beans.regions.Regionstack;

public class RenderTag extends RegionTag (


private String sectionName=null, role=null;
public void setSection(String s)
public void setRole(String s)

( this.sectionName - s; )
( this.role = s;
)

protected boolean renderingRegion() {


return sectionName == null;
}
protected boolean renderingSectionO {

125

return sectionName != null;


public i n t doStartTag() throws JspException {
HttpServletRequest request = (HttpServletRequest)
pageContext.getRequest();
i f ( r o l e ! n u l l & [request. istJserlnRole (role) )
return SKIP_BODY;
if(renderingRegion() ) (
if(!findRegionByKey()} [
createRegionFromTempiate[);
)
Regionstack.push(pageContext, r e g i o n ) ;
}
return EVAL_BODY_INCLUDE;
}
public i n t doEndTag() throws JspException (
Region region = RegionStack.peek(pageContext);
i f ( r e g i o n == null)
throw new JspException("Can't find r e g i o n " ) ;
if(renderingSection(}) f
Section section = region, get(sectionName);
i f ( s e c t i o n == null)
return EVAL_PAGE;

//

section.render(pageContext);
)
e l s e if(renderingRegion()) (
try <
region.render(pageContext);
RegionStack.pop(pageContext);
I
catch (Exception ex) { // IOException ServletException
throw new JspException(ex.getMessage());
}

return EVAL_PAGE;
I
public void released {
super.release[);
sectionName = role = null;

RenderTag , .
section, , .
doStartTag ,
doEndTag . .
PutTag 4.9,.

126

4.

4.9,. /WEB-INF/classes/tags/regions/PutTag. Java


package tags.regions;
import
import
import
import
import

javax.servlet.http.HttpServletReguest;
javax.servlet.jsp.JspException;
javax.servlet.jsp.PageContext;
javax.servlet.jsp.tagext.BodyTagSupport;
javax.servlet.jsp.tagext.TagSupport;

import beans.regions.Content;
import beans.regions.Section;
public class PutTag extends BodyTagSupport [
private String section, role, content, direct = null;
public
public
public
public

void
void
void
void

setSection(String
setRole
(String
setDirect (String
setContent(String

public
public
public
public

String
String
String
String

getSection ()
getRole()
getContent0
getDirect()

{
{
(
f

section){this.section
role)
{this.role
direct) {this.direct
cntnt) {this.content
return
return
return
return

section;
role;
content;
direct;

=
=
=
=

section;}
role;
\
direct; }
cntnt; }

}
}
)
)

public int doAfterBody() throws JspException {


HttpServletRequest request =
(HttpServletRequest)pageContext.getRequest();
if(role != null SS Irequest.isUserlnRolefrole))
return EVAL__PAGE;
RegionTag regionTag (RegionTag)getAncestor(
"tags.regions.RegionTag");
if(regionTag null)
throw new JspException("No RegionTag ancestor");
regionTag.put(new Section(section, getActualContent(),
isDirectO ) ) ;
return SKIP_BODY;
)
public String isDirectO {
if(hasBody[)) return "true";
else
return direct == null ? "false" : "true";
}
public void release() {
super.release();
section = content = direct = role = null;
)
private String getActualContent() throws JspException {
String bodyAndContentMismatchError =
"Please specify template content in this tag's body " +
"or with the content attribute, but not both.",
bodyAndDirectMismatchError =

127
"If content is specified in the tag body,
"direct a t t r i b u t e must be t r u e . " ;

the " +

boolean hasBody = hasBody;


boolean contentSpecifled = (content != n u l l ) ;
if([hasBody f i S contentspecified}
||
UhasBody S& IcontentSpecified))
throw new JspException(bodyAndContentMismatchError);
if(hasBody is direct != null ss
direct.equalsIgnoreCase("false"))
throw new JspException(bodyAndDirectMismatchError);
return hasBody ? bodyContent.getString()
)
private boolean hasBody() {
if (bodyContent == null)
return (false);

: content;

return ! bodyContent.getString().equals["");
}
private TagSupport getAncestor(String className)
throws JspException (
Class klass = n u l l ; // class
try <
klass Class.forName(className);
}
catch(ClassNotFoundException ex) (
throw new JspException(ex.getMessage());
>
return (TagSupport)findAncestorWithClass(this, klass);

PutTag ,
region .'define region; render. PutTag BodyTagSupport;
. , region: put
:
<region:render template='/WEB-INF/jsp/templates/hscf.jsp'>
<region:put section= f t i t l e ' >
The Fruitstand
</region:put>
</region:render>
r e g i o n : p u t , , . , PutTag d i r e c t , , true.

128

4.

,
,
. ,
Web- JSP. , , ,
.


WEB-

...
Model 1.
Model 2: MVC.
Model 2.
- .
-

HTML- . Web-,
HTML, JSP Hjava,
, , . Web-.
JSP
. Web- JSP . Web- .
HTML- JSP-,
bean.

, JSP- bean
"--" (MVC Model-View-Controller).

Java- JSP- , , .
bean Java- JSP- , , , . , Model 1, 0.91 JS. ( 0.91 0.92 JSP , h t t p : //www. k i r k d o r f f e r , com/j spspecs.)
, JSP beans
MVC , .
. 0.91
JSP Model 2.
Model 1,
Model 2. Model 2
, .

132

5. Web-

Model 1
Model 1, . 5.1, JSP-,
bean -.

JSP-

/
-&

bean

. 5 . 1 . Model 1: JSP-, bean -

, JSP-, - bean. JSP- , . , -


. , bean, , - HaJSP-.
- bean
, Web- JSP-.
,
. , JSP- ,
, Java- .
Web-
Model 1 ,

, Java, JSP, HTML XML.
.
Model 2,

Model 1
Model 1 JSP- -, Web-.

-
JSP-. .

Model 2: MVC

133

Model 2: MVC
Model 1, Model 2 - JSP-,
, - . , Mode! 2 (. 5.2)
.

7
[ )

/
-

/
[Bean ()]

JSP-
|( )!

...

.-

Web-

. 5.2. Model 2: MVC


Model 2, , - . bean, JSP-. , , , HTML.
,
Java-, (Java, , .) Java- -,
Web- JSP-.
Model 2 MVC, -
( ), { ), aJSP- . MVC " " Smalltalk.
- ,
, .
Model 2 MVC,
, .
, Web- .

134 5. Web-


MVC , Smalltalk.
-
. , , ^
, , , .. .
.
MVC ,
: , .
, , MVC .

Model 2
Web-, . Model 2. , . 5.3, JSP, , bean
, . ,
(/WEB-INF/web. xral), ,
(/WEB-INF/t Ids / u t i l i t i e s , t l d ) .
, .

bean
, ,
bean. ,
. User 5.1,.
5.1 ,. /WEB-INF/classes/beans/User . Java

package beans;
//
public class User implements java,io.Serializable (
private final String userName, password, hint;
public User(String userName, String password. String hint}
this.userName < userName;
this.password = password;

Model 2

135

this.hint = hint;
}
public String getUserName[) { return userName; }
public String getPassword() { return password; }
public String getHinto
{ return hint; }
public boolean equals(String uname, String pwd)
return getUserName().equals(uname) &
getPassword{).equals(pwd);

IJSP

Java

| XML

. 5.3. ,

User , ,
.
. , .
, User equals, t r u e
, , , ,
.
;
User. . -

136

5. Web-

, .
f i n a l , .
, , 5.1,6.
5.1 ,. /WEB-lKF/classes/beans/LoginDB.java
package beans;
import java.util.Iterator;
import java.util.Vector;
public class LoginDB implements Java.io.Serializable {
private Vector users new Vector!);
public void addUser(String uname, String pwd, String hint} {
users.add(new User(uname, pwd, hint));
)
public User getUser(String uname, String pwd} {
Iterator it = users.iterator();
User bean;
synchronized(users} {
while(it.hasNext()) {
bean = (User)it.next();
if(bean.equals{uname, pwd))
return bean;
return null;
}
public String getHint(String uname) (
Iterator it = users.iterator ();
User bean;
synchronized(users) f
while (it.hasNextd } {
bean = (User)it.next();
if(bean.getUserName().equals(uname))
return bean.getHint ();
return null;

LoginDB
. ,
,
.

Model 2

137


. Java, u t i l .Vector , LoginDB.addUser . , , .


Web- , ,
.
.
/JSP.
/JSP.
-.
.
, .
.
/WEB-INF web.xml.
, ,
http://java.s-un.com/products/servlet. 5.1,.

5.1,.
version="1.0" encoding="ISO-8859-l"?>
<!DOCTYPE web-app
PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.2//EN"
"http://java.sun.com/j2ee/dtds/web-app_2.2.cttd">
<web-app>
<servlet>
<servlet-name>login</servlet-name>
<servlet-class>LoginServlet</servlet-class>
</servlet>
<servlet>
<servlet-name>new-account</servlet-name>
<servlet-class>MewAccou.ntServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>new-account</servlet-name>
<url-pattern>/new-account</url-pattern>

138 5. Web-
</servlet-mapping>
<servlet-mapping>
<servlet-name>login</servlet-name>
<url-pattern>/login</url-pattern>
</servlet-mapping>
<taglib>
<taglib-uri>utilities</taglib-uri>
<taglib-location>/WEB-INF/tlds/utilities.tld</taglib-location>
</taglib>
</web-app>
, 5.1,,

. URL . , ,
,
, ,
<orm action='<%= response.encodeURL("login") %>'>
<form action='<%= response.encodeURL("new-account")

%>'>

UR1 .
:
<%@ t a g l i b u r i - ' u t i l i t i e s ' p r e f i x - ' u t i l ' %>
, ,
.



(Ivarjacobsen) Object-Oriented Software Engineering . , ,
Web-.
,
Web-, HTTP- .

xJSP- .

Model 2 139

, .

, .
, ,
. 5.4.
II-J' 11
P E iw F i n I*ot. HUp
!<:| !| 1/:

_ |D| K||

| B - if"! I*

^J <?0o

Eta

F ^,!*t.

leai Udp

i J ^ ^ T _ _ l ^ ^P |901 1 |1'
?

Please Login

Welcome |oe

Name:
(M
Password:

{gloialrtini

. 5.4.

. 5.5 , .

^r

* SIJSH fiyi
U s t ( J H .

welcome j5p

ir- usir)

forwtni

"D
. 5.5. ,

, , , . 5.4, . , . ,
, .
User
, .

140 5. Web-
JSP- 5.1,.
5.1,. /login, j
<html><headxtitle>Login Page</titlex/head>
<body>
<l@ include file='login-form.jsp' %>
</body>
</html>
JSP-
( 5.1, 5.1,), JSP-,
login. j sp.
, , 5.1,.
5.1,. /login-form.j
<%@ taglib u r i = ' u t i l i t i e s ' p r e f i x = ' u t i l ' %>
<font

size=' 5'

color='blue'>Please

Login</fontxhr>

<form action^'<%= response.encodeURL("login") %>' method='post'>


<table>
<tr>
<td>Name:</td>
<tdxinput type='text' name='userName'
value='<util:requestParameter
property='userName'/>'>
</td>
</trxtr>
<td>Password:</td>
<tdxinput type='password' name='password' size='S'></td>
</tr>
</table>
<br>
<input type='submit' value='login'>
</form>
login-form, jsp ,
, html, head body; JSP-.
;
login. , cookie
, HttpServletResponse.encodeURL.

. . 1.
, 5.1,.

Model 2

141

5.1 ,. /WEB-lNF/claeees/LoginServlat. java


import
import
import
import
import

javax.servlet.ServletConfig;
javax.servlet.ServletException;
javax.servlet.http.HttpServlet;
javax.servlet.http.HttpServietRequest;
javax.servlet.http.HttpServletResponse;

import beans.LoginDB;
import beans.User;
public clas3 LoginServlet extends HttpServlet {
private LoginDB loginDB;
public void init(ServletConfig config)
throws ServletException (
super.init(confIg);
config.getServletContext().setAttribute("loginDB",
loginDB new LoginDBO);
}
public void service(HttpServletRequest req,
HttpServletResponse res)
throws java.io.iQException, ServletException I
User user = loginDB.getUser(req.getParameter("userName"),
req.getParameter("password"});
iffuser ! null) { //
req.getSessiont).setAttribute("user",
user);
getServietContext().getRequestDispatcher(
res.encodeURL("/welcome.j")).forward(req,res);
}
else { //
//
getServletContext().getRequestDispatcher(
res.encodeURL("/logiiiFeiled.jsp")).forward(req,res);

: . init, .
service.
, , , . , User
. ,
, .
5.1,.

,

142 5. Web-
,
LoginDB.
5.1,.
5.1 ,. / w e l c o m e . j s p

<html><head><title>Welcome</title></head>
<body>
<jsp:useBean id='user' scope='session' class='beans.User />
Welcome <%= user.getUserName() %>
</body>
</html>
User, . . 5.2.

Model 2 Java-

Model 2 Java- .
Java- , -;;
5.1 ,. BJSP-, 5.1, 5.1 Java .
, Web- JSP-.
, 5.1,
, , .
Web- , .


, . , , .
1. , uJSP- .
2. ,
.
S. , ,
.

Model 2

143

4. , JS - .
5, , Web-, . JSP-, .
. 5.6. Web- (Login Page), , {Login Failed, New Account Account Created) .

Logtn

:'!!

1.1

:.!r

BHDI

LuqiJi Imlird bAir.iitr.nh 11-1 t nfilDrri

Login Failed

Please Login

Name:

Please enter a valid use- and password,


of create new account

(joe

Please Login

Password: [""*

Name:

||

Password: ~

'aba*

&

An account has been crated for joe

Open a New Account

Please Login
User Name:
Name:
Password: I

Password:
Confirm Password;!

. 5.6. (
, )

144 5. Web-
. 5.7 ,
.

I I
'
-1

1 \

MTWt*fl
^

1 j

LJ

niiJ]
for inl

i
> 1

l m l
fc

i
!

,urt

1
i

him - g r

tddU

HNvn*")

^D

l.hlnt)

fbrwirtd

i
. 5.7.
, , , , , , .
, , Web- Login Failed.
, JSP-, .
a c t i o n ,
. , , .
JSP- Account Created.
JSP-, , 5.1..
5.1,. /loginPailed. jep
<html><headxtitle>Login Failed</title></head>
<font color='red' size='5'>Login Failed</font>
<font color='red' 3ize='4'xp>
Please enter a valid username and password, or create
a new account
</fontx/p>

Model 2

145

include f i l e = V l o g i n - f o r m . j s p 1 %>
<hr>Click <a href='<%= response.encodeURL("newAccount.jsp") %>' >
here</a> to open a new account.
</body>
</html>
Web- .
, , .
JSP- New Account,
, 5.1,.
5.1,. /nwAcoount. jep
<htmlxheadxtitle>New A c c o u n t < / t i t l e x / h e a d >
<body>
<font s i z e * ' 5 ' color='blue'>Open a New Rccount</font>
<hr>
<form action='<%= response.encodeURL("new-acoaunt") %>'
method*3' post' >
<table><tr>
<td> User Name: </td>
<tdxinput type='text' name= 1 userName t x/td>
</tr><tr>
<td> Password: </td>
<tdxinput type=' password1 name=' password1 size=' 8 ></td>
</trxtr>
<td> Confirm Password: </td>
<tdxinput type='password' name='confirm-password'
size='8'x/td>
</trxtr>
<td> Password Hint: </td>
< t d x i n p u t type=' t e x t ' name=' password-hint' >
</td>
</tr>
</table>
<br>
<input type='submit' v a l u e - ' c r e a t e account'>
</form>
</body>
</html>
New Account ,
. a c t i o n new-account
, , .
, , 5.1 ,.

146 5. Web-

5.1 ,. /WEB-IHF/classes/NewAccountServlet. Java


import
import
import
import

javax.servlet.ServletException;
javax.servlet.http.HttpServlet;
javax.servlet.http.HttpServletRequest;
javax.servlet.http.HttpServletResponse;

import beans.LoginDB;
public class NewAccountServlet extends HttpServlet (
public void doPost(HttpServletRequest req,
HttpServletResponse res)
throws java.io.lOException, EervletException {
LoginDB loginDB = (LoginDS)getServletContext().
getAttribute("loginDB") ;
loginDB.addUser(req.getParameter("userName"),
req.getParameter("password"),
req.getParameter("password-hint"J);
getServletContext().getRequestDispatcher(
res.encodeURL("/accountCreated.jsp")).forward(req,

res);

, . ,
LoginDB, addUser, Account Created.
, , , .
)5- Account Created 5.1,.
5.1 ,. /accountcreated.jsp
<htmlxheadxtitle>Account Created</title></head>
<body>
<font size='4' color-'blue'>
An account has been created for
<%= request.getParameter("userName") %>
</font>
<p><%@ include file='login-form.jsp' %></p>
</body>
</html>

Account Created ,
, .

Model 2

147

Web- JSP .
, Model 1
Model 2. Model 2 Modei 1 , , .
, , Model 2.

MODEL 2
...
Model 2.
-

Action.
.
.
.

.
.
.
JSP-.

odel 2 "--", Web-


,
Web-. ,
.
, Model 2. , Apache Struts
( Struts h t t p : //www. apache ,org).
, 5, .

Model 2
, , , .
(action servlet). HTTP-, .do, . . 6.1, bean, (action).
- - {action router). JSP-. JSP-
- ( ) .

150 6. Model 2

1.
'


()

2.

~~

~~1

-
()

1 L

" .
{
^
"V
)

5.
(toward send Redirect)

7.

4.
IX

JSP-
()

.
Web-

. 6.1. M o d e l 2

(. . 6.1) , . 6.1.

6.1. ,
( )

Action

ActionFactory

ActionServlet

ActionRouter

^-

. 6.2 .
JSP- .
.
Web- , .
,
, , .
, ,
. ,
, ..
. .

Model 2

Hashtabls

getAciionfl

Atfiari

Class

;
n Action sciion = get(classname)

151

,

, .
&
i
.

[action *** mill]


actjon - newinsl
put(cla&sname. action)

ActionRoutar router = perfbrm(iht3. req. res)

req, res]
n &'
[

ly We - KOHODW ,
URL
|
^
< . Action, perform.

. 6.2. ActionServlet
, p e r f o r m
. p e r f o r m , ( -). Act i o n . p e r f o r m , URI
b o o l e a n , ,
)' URI: forward s e n d R e d i r e c t .
, r o u t e , Web-. Web- JSP-, HTML- . , Web , . .
, . 6.1, 5.

Action
Act ion 6.1.
6,1,a. /WEB-INF/classes/actions/Action. java
package actions;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
// ,
//

152 6. Model 2

public interface Action (


public ActionRouter perform[HttpServlet servlet,
HttpServletRequest req,
HttpServletResponse res)
throws Java.io.IOException,
javax.servlet.ServletException;
>

Action perform, , ,
HTTP- .


ActionFactory 6.1,6.
6.1,6. /WEB-XNF/classes/actions/ActionFactory. Java
package actions;
import Java.util.Hashtable;
public class ActionFactory (
private Hashtable actions = new Hashtable{);
II .
public Action getAction[String classname,
ClassLoader loader)
throws ClassNotFoundException,
IllegalAccessException,
InstantiationException {
Action action (Action)actions.get(classname);
if(action == null) {
Class klass = loader.loadClass(classname);
action (Action)klass.newInstance();
actions.put(classname, action);
return action;

- getAction,
. ,
. -,
. , , -.

Model 2

153


Act ionRouter 6.1,.
6.1,. /WSB-INF/clasaes/actions/ActionRouter. Java
package actions;
import
import
import
import

javax.servlet.GenericServlet;
javax.servlet.http.HttpServlet;
javax.servlet.http.HttpServletRequest;
javax.servlet-http.HttpServletResponse;

// .
public class ActionRouter {
private final String url;
private final boolean isForward;
public ActionRouter(String url) {
this(url, truej; / / forward
)
public ActionRouter(String url, boolean isForward) (
this.url = url;
this.isForward = isForward;
}
// .
public void route(GenericServlet servlet,
HttpServletRequest req,
HttpServletResponse res)
throws javax.servlet.ServletException,
Java.io.lOException {
if(isForward) {
servlet.getServletContext()-getRequestDispatcher(
res.encodeORL(url)).forward(req, res);
}
else {
res.sendRedirect(res.encodeRedirectURL(url));

,
forward, sendRedirect. .


URL, ".do",
.

154

6. Model 2

// /WEB-INF/web.xml
<web-app>
<servlet>
<servlet-name>action</servlet-name>
<servlet-class>ActionServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>ac:tion</servlet-name>
<url-pattern>*,do</url-pattern>
</servlet-mapping>
</web-app>
". do" , . ".do" . , , LoginAction
actions, U R L :
<form action='<%= response.encodeURM"actions-LoginAction.do") %>'
method='post'>
, , 6,1,,
U R L .
6.1,. /WEB-iNF/classes/ActionServlet. java
import
import
import
import

javax.servlet.ServletException;
javax.servlet.http.HttpServlet;
javax.servlet.http.HttpServletRequest;
javax.servlet.http.HttpServletResponse;

import actions.Action;
import actions.ActionFactory;
import actions.ActionRouter;
public class ActionServlet extends HttpServlet {
private ActionFactory factory = new ActionFactory ();
public void service(HttpServletReque3t req,
HttpServletResponse res)
throws Java.io.IOException,
javax.servlet.ServletException {
try <
Action action = factory.getAction(getClassname(req),
getClass().getClassLoader());
ActionRouter router - action.perform[this,req,res);
router.route(this, req, res);
}
catch(Exception e) {
throw new ServletException(e);

Model 2

155

private String getlassname(HttpServletRequest req) (


String path = req.getServletPath ();
int slash = path.lastlndexOf("/"),
period = path.lastlndexOf(".");
if[period > 0 &s period > slash)
path = path.substring(slash+1, period);
return path;

A c t i o n S e r v l e t . s e r v i c e .
p e r f o r m .
perform , .
A c t i o n S e r v l e t .getClassname URL
.
. URL , , / a c t i o n s . LoginAction. do, a c t i o n s . LoginAction.

,

,
. Mode] 2.
. . 6.3
. . 5.3.

(jSloginFailed
login-form
newAccount
welcome

Iogin2 '
. Web-inf-'
H 13 classes - actions
l i beans- - . .
tags-

ActionRoutel
LoginAction
NewAccountActio

u
4J GetRequestParameterTag

^ J S P -V] Java

j ^ j XML

| * ]

. .. ,

156

6. Model 2

/WEB-INF/classes, , , / W E B - I N F / c l a s s e s / a c t i o n s / ,
. -, l o g i n , j s p
newAccount. j sp URI . JSP- , URI, :
<%-- l o g i n . j s p --%>
<form action='<%= response.encodeURL("login")

%>'

<%-- newAccount.jsp --%>


<form action='<%= response.encodeURL("new-account")
method^'post'>

method=fpost'>
%>'

URI
<% l o g i n . j s p %>
<form action^'<%= response.encodeURL("actions.LoginAction.do")
method='post'>

%>'

<% newAccount.jsp %>


<form
action='<%= response.encodeURL("actions.NewAccountAction.do") %>'
method^'post' >
-, , , .
6.2, 6.2,6.
6.2,a. /WEB-INF/classes/actions/LoginAction.Java
package actions;
import
import
import
import

javax.servlet.*;
javax.servlet.http.+;
beans.LoginDB;
beans.User;

public class LoginAction implements Action (


public ActionRouter perform[HttpServlet servlet,
HttpServletRequest req, HttpServletRespon.se res)
throws Java.io.IOException, ServletException {
LoginDB loginDB = getLoginDB(servlet.getServletContext()J;
User user loginDB.getUser(req.getParameter("userName"},
req.getParameter("password")};
if (user \= null) f //
//
req.getSession[).setAttribute("user",
user);
return new ActionRouter("/welcome.jsp");

else
return new ActionRouter("/loginFailed.jsp");
)
private LoginDB getLoginDB(ServletContext context) (
LoginDB loginDB = (LoginDB)context.getAttribute("loginDB");

157

ifdoginDB == null)
context.setAttribute("loginDB", loginDB = new LoginDB(J);
return loginDB;

6.2,6. /WEB-INF/classes/actions/NewAecountAction . Java


package actions;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServietResponse;
import beans.LoginDB;
import beans.User;
public class WewAccountAction implements Action [
public ActionRouter perform(HttpServlet servlet,
HttpServletRequest req,
HttpServletResponse res)
throws Java.io.lOException,
javax.servlet.ServletException{
LoginDB loginDB - (LoginDB)servlet.getServletContext {).
getAttribute("loginDB");
String uname = req.getParameter("userName");
loginDB.addUser(uname, req.getParameter("password"),
req.getParameter("password-hint"});
req.setAttribute("userName", uname);
return new ActionRouter("/accountCreated.jsp");

, , ,
, .


, . , , JSP- , form, login-form.jsp:
<form action='<%= response.encodeURL("actions.LoginAction.do") %>'
method='post' >

158 6. Model 2
, , LoginAction . j ava, JSP-:
i f ( u s e r != null)

{ II
//
eq.getSession().setAttribute("user",
user);
r e t u r n new ActionRouter("/welcome.jsp");

else
r e t u r n new A e t i o n R o u t e r ( " / l o g i n F a i l e d . j s p " ) ;
JSP- ,
JSP- ,
, , JSP-.
, JSP- . , JSP- :
<form action='<%= response.encodeURL("login-action") %>'
method='post'>
:
i f [ u s e r ! = null)

{ //
//
req.getSession[).setAttribute("user",
user);
return new ActionRouter("welcome-page");

}
else
return new ActionRouter("login-failed-page");
JSP- (
8). ,
6.3,, /WEB-INF/classes.
6.3,a. /WEB-INF/classes/actions . p r o p e r t i e s
# , ActionServlet
login-action=actions.LoginAction
new-account-action=actions.NewAccountAction
# JSP,
login-failed-page^/loginFailed.jsp
welcome-page=/welcome.j sp
account-created-page=/accountCreated.jsp
i n i t ,
, . ,
. 6.3,6.

G.3,6. /WEB-INF/classes/ActionServlet.Java
import java.util.MissingResourceException;
import Java.util.ResourceBundle;
import
import
import
import
import

javax.servlet.ServletConfig;
javax,servlet.ServletException;
javax.servlet.http.HttpServlet;
javax.servlet.http.HttpServletRequest;
javax.servlet.http.HttpServletResponse;

import actions.Action;
import actions.ActionFactory;
import actions.ActionRouter;
public class ActionServlet extends HttpServlet (
private ActionFactory factory = new ActionFactory();
public void init(ServletConfig config) throws ServletExceptioni
super.init(config} ;
ResourceBundle bundle = null;
try I
bundle = ResourceBundle.getBundle("actions");

catch(MissingResourceException e) {
throw new ServletException(e) ;
)
getServletContext().setAttribute("action-mappings", bundle);
)
public void service(HttpServletRequest req,
HttpServletResponse res)
throws Java.io.lOException, ServletException {
try {
String actionClass = getActionClass(req);
Action action = factory.getAction(actionClass,
getClass().getClassLoader());
ActionRouter router action.perform(this,req,res);
router.route(this, req, res);
}
catch(Exception e) {
throw new ServletException(e);
)
)
private String getClassname(HttpServletRequest req) {
String path = req.getServletPath[);
int slash = path.lastlndexOf("/"),
period = path.lastlndexOf(".");
if(period > 0 S& period > slash)
path = path.substring(slash+1, period);
return path;
1

159

160

6. Model 2

private String getActionClass(HttpServletRequest req) {


ResourceBundle bundle = (ResourceBundle)getServletContext[).
getAttribute("action-mappings");
return (String)bundle.getObject(getActionKey [req});
>
private String getActionKey(HttpServletRequest req) (
String path - req.getServletPathO;
int slash path.lastlndexOf("/"),
period path. lastlndexQf ("."),if(period > 0 6& period > slash)
path = path.substring(slash+1, period);
return path;

service
getActionClass,
.
ActionRouter, 6.3,, , JSP-.
6.3,. /WEB-INF/classes/actions/Ac tionRouter . Java
package actions;
import
import
import
import

java.util.ResourceBundle;
javax.servlet.GenericServlet;
javax.servlet.http.HttpServletRequest;
javax.servlet.http.HttpServletResponse;

//
public class ActionRouter {
private final String key;
private final boolean isForward;
public ActionRouter(String key) {
this(key, true); // forward
}
public ActionRouter(String key, boolean isForward)
this.key = key;
this.isForward - isForward;
// .
public synchronized void route(GenericServlet servlet,
HttpServletRequest req,
HttpServletResponse res)
throws Java.io.lOException,
javax.servlet.ServletException (
ResourceBundle bundle = (ResourceBundle)servlet.

161

getServletContext().
getAttribute("action-mappings");
String url - (String)bundle.getObject(key);
if(isForward) (
servlet.getServletContext().getRequestDispatcher(
res.encodeURL(url)).forward(req, res);
}

else {
res.sendRedirect(res.encodeRedirectURL(url));
I

, JSP- . ,
6.3, .. NewAccountAction
HjSP- login-form, j sp.
6.3,r, /WEB-iNF/classes/actions/NewAccountAction. Java
public class NewAccountAction implements Action {
public ActionRouter perform(HttpServlet servlet,
HttpServletRequest req, HttpServletResponse res)
throws Java.io.IQException, ServletException (
LoginDB loginDB = (LoginDB)servlet.getServletContext [).
getAttribute("loginDB");
String uname = req.getParameter("userName");
loginDB.addUse(uname, req.getParameter("password"),
req.getParameter("password-hint"));
req.setAttribute("userName", uname);
return new ActionRouter("aooount-created-page");

6,3,. /login-form.jsp
<*@ taglib uri-'utilities' prefix-'util' %>
<font size='5' color='blue'>Please Login</fontxhr>
<form action='<%= response.encodeURL("login-action.do") %>'
method='post'>
</form>

162

6. Model 2

,
. , , ,
6.3,6, . , .
, ,
<web-app>
<servlet>
<servlet-name>action</servlet-name>
<servlet-class>ActionServlet</servlet-class>
<init-param>
<param-naiue>actioii-mappings</param-name>
<param-valvie>actions</param-value>
< / init-param>
</servlet>
</web-app>

:
public class ActionServlet extends HttpServlet {
public void init (ServletConfig config) throws ServletException(
super.init(config) ;
ResourceBundle bundle = null;
try {
bundle = ResourceBundle.getBundle [
config.getlnitParameter("action-mappings"));
)
catch(MissingResourceException e) (
throw new ServletException(e);


,
.
, .
XML-.
, , .


,
, , ,
, -

163

. , , .
1. , - () , , bean
JSP- ().
.
2. JSP-, - { ) bean, ( ). Web-.
3. JSP, 1 2.
Web-
.
JSP Web-.
, , ( ), JSP- ( Web-) ( ). , .
Web-, 5
.
.
1. ; , .
2. , ;
.
3. ,
, .
4. .
5. JSP-,
, . ,
.
. 6.4 JSP-; , .

164

6. Model 2

*''PiiiwadHnl MiandtImarvt*
ik

dLI

]iMr

FavorltKl

.!

Jool

{dlt

ii*

Fipodln

,|Q| X

Iwj

A,

Login Failed
irl iist?rnam& and password, w
^aii? a new account

Hint forjoi is fly tfcg'i

Please Login

Please Login
Name:
PasswonJ |
Name

jjoe

Password f^

[agin I

tngln j
Click * \o see your password him.

PMC 6.4.

, ,
.

1: ,

ShowHintAction 6.4,.
6.4,3. /HEB-INF/classes/actiona/ShowHintAotion. Java
package actions;
import
import
import
import

javax.servlet.ServletContext;
javax.servlet.http,HttpServlet;
javax.servlet.http.HttpServletRequest;
javax.servlet.http.HttpServletResponse;

import beans.LoginDB;
public class ShowHintAction implements Action {
public ActionRouter perform(HttpServlet servlet,
HttpServletRequest req, HttpServletResponse res)
throws IOException, ServletException {
LoginDB loginDB = getLoginDB(servlet.getServletContext
String = (String)req.getSession().
getAttribute("userName");
req.setAttribute("hint", loginDB.getHint(uname)};
req.setAttribute("userName", uname);
return new ActionRouter("show-hint-page");

165

private LoginDB getLoginDB(ServletContext context) (


LoginDB loginDB = (LoginDB)context.getAttribute("loginDB");
iffloginDB null)
context.setAttribute("loginDB", loginDB = new L o g i n D B O ) ;
return loginDB;

, 6.4,, . 4 , .. . ,
perform, show-hint-page. JSP- .

2: JSP-,

JSP-, , 6.4,6,
6.4,6. /sbowHintAction. jS p
chtmlxtitle>Password Hint</title>
<body>
Hint for < b x % = request.getAttribute ("userName")
<i><%= request.getAttribute("hint") %></i>

%></b> is

<pxfont size='5' color='blue'>Please Login</fontx/p><hr>


<form action-'<%= response.encodeURL("login-action.do") %>'
method^'post' >
<table>
<tr>
<td>Name:</td>
<tdxinput type-'text' name='userName'
value='<%= request.getAttribute("userName") %>'>
</td>
</tr><tr>
<td>Password:</td>
<tdxinput type='password' name=' password' sizs=' 8' ></td>
</tr>
</table>
<br>
<input type='submit' value=' login'>
</form>
</body>
</html>

166

6. Model 2

JSP-, 6.4,6, . 5 , .
, , loginaction. , , .

3:
6.4,.
6.4,. /WEB-INF/classes/actions.properties
# , ActionServlet
login-action^actions.LoginAction
new-account-tion=actions.NewAccountAction
show-hintaction=actions,ShowHintAetion
# JSP,
login-failed-page=/loginFailed.jsp
we1ome-page=/welcome.jsp
account-created-page=/accountCreated.jsp
3how-hint-page=/3howHint.jsp

4: ,

,
, 6.4,. ,
, , , .
6.4,. /loginFaiXed. jap
<htmlxheadxtitle>Login
<body>

Failed</title></head>

<font c o l o r = ' r e d ' size-'5'>Login Failed</font>


<font c o l o r = ' r e d ' s i z e = ' 4 ' x p >
Please enter a valid username and password, or create
a new account
</fontx/p>
<%@ include f i l e - ' / l o g i n - f o r m . j s p '
<jsp:useBean

%>

id='loginDB' class='beans.LoginDB'
scope='application' />

<%if(loginDB.getHint(request.getParameter("userName")) != null){%>
Click <a href='<%=response.encodeURL("show-hint-action.do")%>'>

167

here</a> to see your password h i n t .


<% } else { %>
Click <a href=' <%=re5ponse.encodeURL("newAccount.jsp")%>'>
here</a> to open a new account.
<\

%>

</body>
</html>
, .
, . , , ,
.


Model 2 , Java-
.
; Web- HTML- JSP-,
,
Wcb-, JSF- Java- , Web ; .
, Model 2,
Java- "" JSP-. , , , 6.4,, :
<htmlxheadxtitle>Login

Failed</titleX/head>
1

<j sp:useBean id='loginDB class='beans.LoginDB'


scope='application'/>
<%if ( l o g i t i D B . g e t H i n t ( r e q u e s t . g e t P a r a m e t e x - ( " u s e r N a m e " ) ) ! = n u l l ) {%>

Click <a href='<%=response.encodeURL["show-hint-action.do")%>'>


here</a> to gee your password h i n t .

<% } e l s e { %>

Click <a href='<%=response.encodeURL("newftccount.jsp")%>' >


here</a> to open a new account.

Java- JSP- , . , .
<htral><headxtitle>Login

Failed</titlex/head>

<%@ t a g l i b u r i = ' a p p l i c a t i o n - t a g s ' prefix='app'


"

app:hintAvailable>

i>

168

6. Model 2

Click < href='<%=response.encodeURL("show-hint-action.do"J%>'>


here</a> to see your password h i n t .
/apprhintAvailable>
<app:hintNotAvailable>
Click <a href='<%=response.encodeURL("login.jsp")%>' >
here</a> to retry login.
</app:hintHofcAvailable>
, HTML- hint Available, hintNotAvailable.
, , , , . 6.5,
hintAvailable, 6.5,6 hintNotAvailable.
6.5,a. /WEB-lNF/claeses/tags/HintAvailableTag. Java
package tags;
import
import
import
import

j avax.servlet.ServletRequest;
j avax.servlet.j sp.JspException;
javax.servlet.jsp.tagext.TagSupport;
beans.LoginDB;

public class HintAvailableTag extends TagSupport {


public int doStartTag0 throws JspException {
ServletRequest req - pageContext.getRequest();
LoginDB loginDB = [LoginDB)pageContext.
findAttribute("loginDB");
if(loginDB.getHint(req.getParameter("userName")) ! = null)
return EVAL_BCDY_INCLUDE;
else
return SKIP_BODY;
}

6.5,6. /WEB-INF/classes/tags/HintKotAvailableTag. Java


package tags;
import javax.servlet.jsp,JspException;
public class HintNotAvailableTag extends HintAvailableTag I
public int doStartTag0 throws JspException {
int available = super.doStartTag();
return available == EVAL_BODY_INCLUDE ?
SKIP_BODY : EVAL_BODY_INCLUDE;

JSP-

169

, , ,
. d o S t a r t T a g
SKIP_BODY, EVAL_BODY_INCLUDE. ,
HTML-.
1 2.
Java-, JSP-
Java. ,
JSP.

JSP-
,
Java- JSP-. ,
, Ko^aJSP-flOKyMeiiTbi , MVC. ,
JSP-, Java-. JSP-. , JSP , Web.
JSP- JSP-, HTML-, Java. , JSP- , Web-. , 6.6,, . .
6.6, a. /showRequestParameters -jap: JSP-
J a v a . u t i l . E n u m e r a t i o n e = request.getParameterNames [ ) ;
boolean hasParams = f a l s e ;
while(e.hasMoreElements()) (
S t r i n g name = ( S t r i n g ) e . n e x t E l e m e n t ( ) ;
S t r i n g [ ] v a l u e s = r e q u e s t , g e t Parameter-Values (name) ;
hasParams - true;
o r ( i n t i=0; i < v a l u e s . l e n g t h ; ++i)
S t r i n g next = v a l u e s [ i ] ;

i f ( i == 0) { %>
<b><%= name %>:</b> <%= n e x t %>
}

e l s e f %>
, <%= n e x t !>

170

6. Model 2

if(ihasParams) { %>
<i>No parameters with t h i s request</i>
JSP-, , 6.6,,
. 6.5.
t UJFCmami-HimidilMpMEitfaia
f*

E*1

I,

fgnNM-.

Setod Your Age Bracket


SelwYourFeMoiileFnKiB

Ik

nrtECkn

LGI

I<I

tt>

11.30 121-30 f 31-40 '" Jl-Stt

i7A(jpl ! Grapa

. 6.5. JSP-
HTML-,
6.6,6.
6.6,6. t e s t . h t m l
<htmlxtitle>JSP Scripts</title>
<body>
<form action=' showParaxns. jsp' >
<font size='4' color='blue'>Select Your Age Bracket:</font>
<input
<input
<input
<input
<input
<font
<input
<input
<input
<input

type'radio'
type='radio'
type='radio'
type='radio'
type='radio'

name='age'
name='age'
name='age'
name='age'
name='age'

value=
value=
value=
value=
value=

ll-20'>ll-20</input>
21-30'>21-30</input>
31-40'>31-40</input>
41-50'>41-50</input>

4' color='blue'>Select Your Favorite Fcuits:</font>


type-'checkbox'
type='checkbox'
type='checkbox'
type='checkbox'

name='fruit'
name='fruit'
name='fruit'
name='fruit'

value=' Kiwi'>Kiwi</input>
value='Apple'>Apple</input>
value='Pear'>Pear</input>
value='Grape'>Grape</input>

<p><input type='submit'/></p>
</form>
</body>
</html>
HTML- action showParams. j sp.
showParams. j sp 6.6,.

JSP-

171

6.6,. /showParams.jsp
<htmlxtitle>JSP Scripts</title>
<body>
<font size='4' color='blue'>Request Parameters:</font>
<%@ include file='showRequestParameters.jsp' %>
</body>
</html>
, JSP-
JSP- JSP-, , Web-. JSP^eiiapunMir,
; , . JSP- , i n c l u d e . , JSP-
^-.

, JSP
Web-,
"" HTML- Java-. .
6ascJSP Model 2, ,
, .
* - , , "--"
. . ;
.
- :
Gamma, Helm, Johnson, Vlissidcs. Design Patterns, Addison-Wesley, 1992.
Wirfs-Brock, Wilkerson, Wiener. Designing Object-oriented Software, Prentice Hall, 1990.
Meyer, Bertand. Object-Oriented Software Construction, Prentice Hall, J997.
Budd, Timothy. An Introduction to Object-oriented Programming, Addison-Wesley, 1991.
"~-":
Alpert, Brown, Woolf. The Design Patterns Smalltalk Companion, Addison-Wesley, 1998.
Gamma, Helm, Johnson, Vlissides. Design Patterns, Addison-Wesley, 1992.
:
Fowler, Scott. UML Distilled Second Edition, Addison-Wesley, 2000.
Schneider, Winters. Applying Use Cases, a Practical Guide, Addison-Wesley, 2000.

...
Model 2.
.
, , Model 2.

.

. , Swing , ,
.
, Servlet 2.3,
. ( ,
HttpSessionBindingListener.) Servlet 2.3 , . .
Servlet 2.3 ,
. , , , , Servlet 2.3.

. , . , ,
Model 2, , , , .
Model
2. ,
, .
Reload.
, ,
. ,
, Model 2.

174

7.


Model 2
Model 2 Web-,
-
Web- . Model 2 ,
. ,
, , , .
Mode) 2
, perform .
Java, .. ,
.
,
, ActionListener.
ActiortEvent. . 7.1 ,
( form).

new Attie nEvsnlf

AC1ionrtrt>CT10M.BEFORe_PERFOB*t, fflQUlst, risoonse)

peffomi(seiv<at, request, response}


Uflff **.^101_1#."
> jwit uel otv (JSfqrArign
tertttjun
.PERFORM)

i. t n lfl r i r ;
inecAcDonfactiait, rt'ques!, response)

. 7.1. ,

Model 2

175

, ActionEvent.ACTION_BEFORE_PERFORM f ireEvent , beforeAction .


ActionEvent .ACTION_AFTER_PERFORM. fireEvent
^ , afterAction .
ActionListener 7.1. , Action
ActionListener Action
ActionListener AWT.
7.1 ,. /WEB- INF/ classes /actions /events /ActionLi a tener. Java
package actions.events;
import

javax,servlet.ServletException;

public interface ActionListener extends Java,util.EventListener (


public void beforeAction[ActionEvent event)
throws ServletException;
public void afterAction[ActionEvent event)
throws ServletException;

ActionListener J a v a . u t i l .EventListener,
.
EventListener .
ActionListener : beforeAction a f t e r Action. . 7.1, perform .
ActionListener , , , .
ActionListener .
ActionEvent 7.1,6.
7.1,6. /WEB-INF/classes/actions/events/ActionEventoava
package actions.events;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import actions.Action;
public class ActionEvent extends Java.util.EventObject (
public s t a t i c final int BEFORE_ACTION=0, AFTER_ACTION=1;
private int eventType;
private HttpServletRequest request;
private HttpServletResponse response;

176

7.

public ActionEvent(Action action, int eventType,


HttpServietRequest request,
HttpServietResponse response) (
super(action); //
11
this.eventType eventType;
this.request = request;
this.response = response;
}
public int
getEventType[) f return eventType; }
public HttpServietRequest getRequest()
{ return request;
}
public HttpServletResponse getResponse() { return response; }
public void setEventType(int eventType) {
this.eventType = eventType;

Action, , , . Action (java.util. EventObject), .


getSource, .
Action, 6, 7.1.,
, . Action
, . Action . f ireEvent.
7.1,. /WEB-INF/claps*a/action/Action. Java
package actions;
import
import
import
import
import

javax.servlet.http.HttpServiet;
javax.servlet.http.HttpServletRequest;
javax.servlet.http.HttpServletResponse;
actions.events.ActionEvent;
actions.events.ActionListener;

// ,
public interface Action {
ActionRouter perfom(HttpServlet servlet,
HttpServletRequest req,
HttpServletResponse res)
throws j avax,servlet.ServletException;
void addActionListener[ActionListener listener);
void fireEvent(ActionEvent event)
throws javax.servlet,ServletException;

Model 2

177

Action.addActionListener Action.
FireEvent ActionBase,
7.1,.
7.1,. /WEB-INF/clasaea/actions/ActionBaae. Java
package actions;
import
import
import
import
import

Java.util.Enumeration;
java.util.Vector;
javax.servlet.ServletException;
actions.events.ActionEvent;
actions.events.ActionListener;

public abstract class ActionBase implements Action (


protected boolean isSensitive = false,
hasSensitiveForms false;
private Vector listeners = new Vector!);
public ActionBase() {
addActionListener(new SensitiveActionListener());
)
public void addActionListener(ActionListener listener) {
listeners.addElement(listener);
public void removeActionListener(ActionListener listener) {
listeners.remove(listener);
}
public void fireEvent(ActionEvent event)
throws ServletException (
Enumeration it - listeners.elements 0;
while(it.hasMoreElementsf) ) {
ActionListener listener =
(ActionListener)it.nextElement 0;
switch!event.getEventType 0) {
case ActionEvent. BEFORE__ACTION:
listener.beforeAction(event);
break;
case ActionEvent.AFTER_ACTION:
listener.afterAction(event);
break;

, ,
, 7.1,. 6.3,6.

178

7.

7.1,. /WEB-lNF/classes/ActionServlet. Java


// 6.3,6.
import actions.events.ActionEvent;
public class ActionServlet extends HttpServlet {
public void service(HttpServletRequest req,
HttpServletResponse res}
throws ServletException {
Action action = getAction(req);
ActionEvent event = new ActionEvent(action,
ActionEvent.BEFORE_ACTION, req, res);
action.fireEvent(event);
ActionRouter router = performAction(action, req, res);
action.setEventType(ActionEvent.AFTER_ACTION);
action.fireEvent(event);
// ,
//
routeAction(router, req, res);

, Model 2, , .


, , ; . Model 2. .



, , Reload, .

179
. 7.2 Web-,
. Web- , Timotliy ( t i m o t h y ) .
1-|||
' Eil.

a<

Kn.

Fpwmut

loot!

jjMp

, * . j g l 11,-.1,|1!*>.-|1* ,t _

Login Failed

C'lm'evaai/qusn-c^o.iri-r

Open a New Account

Please enter a vabd username and


password, or create a new account
User Name:

Please Login

tirnolh^

Password:
Confirm Password:
Password Hinl:

Name:

jtimottiy
create account

Password: |

Click here to open a new account


fcttoni

my dog's name

J
...

An account has been crated foe timothy

Please Login
Name:

(timothy

Password: [~

. 7.2. ,

Timotliy , ,
Login Failed. Timothy ,
, , Open a New Account. Wcb-, ,
create account.
Timothy ,
Web- Please Login, .
Timothy , . ,

180

7.

Reload, Web-? Back, , ,


create account? , .,
,
.
; ,
JSP. {. 7.3).
J ''" //tuiiiilhusi .naiKVnvnnlsfmiw ui;i:i>unl in i

iln - Mi,.ur.:i>tt Inlcmni xpln

j j AidrM j|l]iittp^localhast908D/events/new-accounl-ac(ion.do

Error: 500
Location: /events/new-account-action-do
Internal Servlet Error:
javaxservlet ServletException: Sorry, but this is a sensitive page that c e n t be resubmitted.
at actions S ensitiveActionListener.be Core Acti on(actions/3ensitiveActionListener.jav:Z4)
ataotions.ActionBase.fireEventCactions/AotionBasejava:48)
atedionsActionBasebeforeActionCections/ActionBasejava3Z)

j f c Local iinrow

, 7.3.

,
,
Model 2
,
, Reload. . 7.2 n e w - a c c o u n t - a c t i o n (.
URL Address). , ,
.
. , , n e w - a c c o u n t - a c t i o n , 7.2,,
.

181

7.2,. /WEB-INF/classas/actions/NewAoccmntAction. Java


package actions;
import
import
import
import

javax.servlet.ServletException;
javax.servlet.http.HttpServlet;
javax.servlet.http.HttpServletRequest;
javax.servlet.http.HttpServietResponse;

import beans.LoginDB;
import beans.User;
public class NewAccountAction extends ActionBase (
public NewAccountAction() {
isSensitive = t r u e ; //
public ActionRouter perform(HttpServlet servlet,
HttpServletRequest req,
HttpServletResponse res)
throws ServletException {
LoginDB loginDB = (LoginDB)servlet.getServletContext().
getAttribute("loginDB");
String uname req.getParameter("userName");
loginDB.addUser(uname, req.getParameter("password"),
req.getParameter("password-hint"]
req.setAttribute("userName", uname);
return new ActionRouter("account-created-page");

, . , -

, . , ,
, ,
new-account-action.
JSP-, . query-accountaction, 7.2,6; JSP-, . 7.2, . .

7.2,6. /WEB-INF/classes/aetiona/QueryAccountAction. java


package actions;
import
import

javax.servlet.ServletException;
javax.servlet.http.*;

// JSP-,
// .
public class QueryAccountflction extends ActionBase

182

7.

public ActionRouter perform(HttpServlet servlet,


HttpServletRequest req,
HttpServletResponse res)
throws ServletException (
// query-account-page -
// JSP-,
// . 7.2.
return new ActionRouter("query-account-page");

i
.
, Action ActionBase.
7.3, 7.3,6,
7.3,. Action
// 7.1,.
package actions;
public interface Action extends ActionListener

public boolean hasSensitiveForms();


public boolean i s S e n s i t i v e ( ) ;

7.3,6. ActionBase
// 7.1,.
package actions;
public abstract class ActionBase implements Action {
protected boolean isSensitive = false,
hasSensitiveForms = false;
public ActionBase(J {
addActionListener(new SensitiveActionListener());
public boolean isSensitive() {
return isSensitive;
}
public boolean hasSensitiveForms() {
return hasSensitiveForms;

183

,
, , .


, ,
.
, (token). .

. , .
, , .
.
, . Reload , .
Token 7.4,.
7.4,a. /WEB-INF/classes/beans/Token . Java
package beans;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import j avax.servlet.http.HttpSession;
import Java-security.MessageDigest;
public class Token (
private String token;
public Token[HttpServletRequest req) throws ServletException (
HttpSession session = req.getSession(true);
long systime = System.currentTimeMillis (),byte[) time - new Long[systime).toString().getBytes();
byte[] id = s e s s i o n . g e t l d f ) . g e t B y t e s ( ) ;
try {
MessageDigest md5 = MessageDigest.getlnstance ("MD5");
md5.update(id);
md5.update(time);
token = toHextmdb.digest());
)
catch(Exception ex) {
throw new ServletException(ex);
public String toString()

184

7.

return token;
)
private String toHex(byte[] digest) {
StringBuffer buf = new StringBuffer() ;
f o r ( i n t i=0; i < d i g e s t . l e n g t h ; i++)
buf.append(Integer.toHexStringf(int)digest [i]

& OxOOff)

return b u f . t o S t r i n g ( ) ;

Token ,
. Token " ": -.
,
, SensitiveActionListener.
.
, ActionBase
.
// 7.3,6.
public abstract class ActionBase implements Action
public ActionBase() {
addActionListener{new

SensitiveActionLiatener());

. 7.4 ,
bef oreAct ion , .
.
, .
,
, .

(. 7.5).

Action

Action

Lllinn

RtomSI

lActwnQ

nm Actionvnt(djn AclionEnt.ACT10N_BEFORe_PERFORM.
i

mponct)

! (tvsni)

, nipmm;

xnt gMR<quisi|)
[
relum

getSseiionO
*
( HJUi
1
i *

^^,rttum

. 7.4.

185

186

7.

Action

LatBMt

new ActionEvantlaction

HltnSinainn

SinsitrvaActipn

ActionEwnt ACT10M_AFreR_PERF0RMd

Takin

Reguesi

. response]

s^,
(Action) gelSourc e()

n( ge(RequBSL()

glSionO .
#
0&1
&

,J.:'!.:::Mi-L

niLOvcPcriraO]

-Token lakan = navr TolkmO

-.,. 51 nblHn^i'- l o k n loStringO)

-1

, 7.5,


SensitiveActionListener 7.4,6.
7.4,6. /WEB-INF/cla3sea/actions/SensitiveActionListener. Java
package actions;
import
import
import
import
import
import
import

javax.servlet.SevletException;
javax.servlet.http.HttpServletRequest;
javax.servlet.http.HttpSession;
actions.Action;
actions.events.ActionEvent;
actions.events.ActionListener;
beans.Token;

public class SensitiveActionListener implements ActionListener {


public void befoceAction(ActionEvent event)
throws ServletException {
Action action = (Action)event. getSource();
if [action.isSensitive() ) (
HttpServletRequest req = event.getRequest();
String requestToken = (String)req.getParameter("token"),
sessionToken = (String)req.getSession().
getflttribute("token");
if [sessionToken == null | | requestToken == null | |
!sessionToken.equals(requestToken)) {
throw new ServletException(
"Sorry, but this is a sensitive page " +
"that can't be resubmitted.");

public void afterAction(ActionEvent event)


throws ServletException {
Action action = (Action)event.getSource(};
HttpServletRequest req = event.getRequest();
HttpSession session = req.getSession();
if(action.hasSensitiveForms()) (
Token token = new Token(req);
session.setAttribute("token", token.tostring());
req.setAttribute("token", token.toString());
}
if(action.isSensitive()) {
session.removeAttribute("token");

187

188

7.


, , , .
.
new-accaurvt-action .
// 7.2,.
public class NewAccountAction extends ActionBase I
public NewftccountActicn() (
isSensitive = true; //

, query-account-action .
// 7.2,6.
public class QueryAccountAction extends ActionBase {
public QueryAccountAction[) {
// JSP-
//
hasSensitiveForms true;

newAccount. j sp, 7.4, , action new-account-action. JSP-


.
,
.
7.4,. /newAccount.jsp
<htmlxheadxtitle>New Account</title>
<
%
@ taglib uri='/WEB-lNF/tlds/utilities.tld' prefix-'util 1 %>
</head>
<body>
<font size='5' colors'blue'>Open a New Account</font>
<hr>
<form action^' <%=response.encodeURL("new-account-action.do")%> '
method='post'>
<tablextr>
<td> User Name: </td>
<tdxinput type='text' name='userName'x/tci>
</trxtr>
<td> Password: </td>
1
1
<td><input type='password name= 'password size='S ' x / t d >
</trxtr>

189

<td> Confirm Password: </td>


<td><input type='password' name='onfirm-password'
size='8'x/td>
</tr><tr>
<td> Password Hint: </td>
<td><input type='text' name='password-hint'>
</td>
</tr>
</table>
<br>
<input type='submit' value='create account'>
<util: tofcen/>

</form>
</body>
</html>

new-account-action.
, , . new-account-action
Reload.
, u t i l : token. 7.5,
7.5./WEB-INF/classes/tags/TokenTag.Java
package

tags;

import
import
import

javax.servlet.ServletRequest;
javax.servlet.jsp.JspException;
javax.servlet.jsp.tagext.TagSupport;

public class TokenTag extends TagSupport (


private String property;
public int doStartTagd throws JspException {
ServletRequest req = pageContext.getRequest();
String value = (String)req.getAttribute("token");
if(value = null}
throw new JspExceptionC'Ko token in request scope");
try {
pageContext.getOut().print("<input type='hidden1 " +
"narae='token' " + "value -'" + value + n ( > " ) ;
}
catcMjava. io. IOException ex) {
throw new JspException(ex.getMessage());
}
return SKIP_BODY;

190

7.

token HTML- .
, ,
, .



Back Web-,
, . Back
, ,
, .

, . [
.



Model 2,
. , , .
, .
, , . 7.1.
7 . 1 . ,

create-tokens

token

check-tokens

, . 7.1, ; , 7.6, JSP-, .

191

7.6,. create-tokens

<htttLl><headxtitle>New Account</title>
<
%
@ taglib uri='/WEB-INF/tlds/utilities.tld 1 p r e f i x = ' u t i l ' l>
<
%
@ taglib uri='/WEB-lNF/tlds/tokens.tld' prefix='tokens' %>
<tokens:create-tokens/>
</head>
<body>
<font s i 2 e = ' 5 ' color='blue">Open a New Account</font>
<f orm action^'createAccount.j sp' method^'post'>
<table>
<tr>
<td>User Name:</td>
<tdxinput type=' t e x t ' name=' userName' ></td>
</tr>
<tr>
<td>Password:</td>
<td><input type='password1 name=' password1 size='8 ' x / t d >
</tr>
<tr>
<td>Confirm Password:</td>
<td><input type =1 password' name='confirm-password'
size=I8'x/td>
</tr>
<tr>
<td>Password Hint:</td>
<tdxinput type=' t e x t ' name=' password-hint' x / t d >
</tr>
</table>
<br>
<input type='submit' value^'create account'>
<tokens:token/>
</form>
</body>
</html>

JSP-, , c r e a t e - t o k e n s , token ,
.
( ,
). token
7.5.
check-tokens . , . JSP-, 7.6,6.
, .

192

7.
,

7.6,6. check-tokens reraove- seas ion -token


tagLib uri='/WEB-INF/tlds/utilitiestld' prefix='util' %>
<% taglib uri='/WEB-INF/tlds/tokens.tld' prefix='tokens %>
<tokens:check-tokens/>
<jsp:useBean id='bean' class='beans.CreateAccountBean'/>
<l bean.createAccount(request, application); *>
<font size='4' color='blue'>
An account has been created for
<%= request.getParameter("userName") %>
</font>
<p><%@ include file='login-forra.jsp' %></p>
create-to kens 7.6,.
7.6,. /WEB-INF/classs/tags/CreateTokensTag. Java
package tags;
import
import
import
import
import
import

javax.servlet.ServletRequest;
javax.servlet.http.HttpServletRequest;
jsvax.servlet.jsp.JspException;
javax.servlet.jsp.PageContext;
javax.servlet.jsp.tagext.TagSupport;
beans.Token;

public class CreateTokensTag extends TagSupport {


private String property;
public int doEndTag() throws JspException {
ServletRequest request = pageContext.getRequest();
try (
Token token = new Token((HttpServletRequest)request);
pageContext.setAttribute("token", token.toString [),
PageContext.SESSION_3COPE)
pageContext.setAttribute("token", token.toString(),
PageContext. REQtfEST_SCOPE)
}
catch(Exception ex) {
throw new JspException(ex.getMessage ());
)
retUtn EVAL_PAGE;

193


.
check-tokens 7.6,.
7.6,. /WES-IKF/classes/tags/CheckTokensTag.Java

package tags;
import
import
import

javax.servlet.ServletRequest;
javax.servlet.jsp,JspException;
javax.servlet.jsp.tagext.TagSupport;

public class CheckTokensTag extends TagSupport {


private String property;
public i n t doEnctTag 0 throws JspException {
ServletRequest req pageContext.getRequest t ) ;
String sessionToken (String)req.getParameter("token");
String requestToken (String)pageContext.getSession().
getAttribute("token");
if(requestToken == null || cequestToken > null ||
!sessionToken.equals(requestToken))
throw new JspException("Sorry, but t h i s sensitive page" +
" c a n ' t be resubmitted.");
return EVAL_PAGE;

. , .

.
Model 2.
.

Model 2.
Java Front Controller. ,
, . Model 2,

194 7.
, Front Controller.
,
, .
,
, , .
, , ,
.
:
.

I18N
...
Unicode.
.

.
.
- ListResourceBundle.
- PropertyResourceBundle.
- .
,
, .
-

.
.

.
- message.
- format.

World Wide Web Web- , . Web-


, . , , .
(internationalization)
(localization) Web-. il8n, ,
{internationalization
localization) , .
, ,
, , .
4,0 Netscape Communicator, Internet Explorer .
, . , , , , . ,

. : Unicode .

Unicode
Java
Unicode. Unicode 1
. , 1 Unicode hup://iaam>. uniiode.org/. -

. .

198

8. I18N

, , . , . 8.1 JSP-, " " .


i-'llncaie Escape Sequences - MiciojofUntanat EMpioref
j Fife

gdlt

View

Fnvorltts

Tool!

- I D 1 x[

' AsJcken j | hltpWIoealhost:MMVil Bn-ctiaisetsytesl. jsp J^J <?Go I

^Sus usos son internacionalizados?

,f>r Local rtianei

. 8.1. Unicode

JSP-, . 8.1, 8.1.


8.1. Untcode
<htmlxhead><title>Unicode Escape Sequences</title>
<%S page contentType='text/html; eharset=IS0-8859-1' %>
<% response.setHeader("Content-Language", " e s " ) ; %>
</head>
<body>
<font s i z e - ' 4'>
<%= "\uOOBFSus usos son internacionalizados?" %>
</font>
</body>
</html>

JSP-
\uOOBF. \uXXXX, .
, Latin-1, http://www.unicode.org/charts/PDF/UOOOO.pdf.
Unicode,
HTML, , ,
&iquest, ( HTML http://www.utoronto.ca/
webdocs/HTMLdocs/NewHTML/iso_table.html.) HTML
HTML-, JSP-, HTML, , Unicode.

199

JSP-, 8.1, Content-Language, es. , .


, . ,
Content-Language , Netscape Internet Explorer .

, , 8.1, \uOOBF . . RFC 2278


(RFC 2278
http://www,cis.ohiostate.edu/htbin/rfc/rfc2278.html). , 8.1, ISO-8859-1, , .

JSP -, ,
,
, , , , . ,
, ,
. , 8.2 Web-,
" " .

pit

"^

Edit

view

Tooh

Hslp

HIpVflocalhostSCTOAiarrchatsets/test.isp

* Locdinnanet

. 8.2.

200

. I18N

JSP-, , 8.2, 8.2.


.2.
<html><headxtitle>Character Sets</tltle>
<%9 page contentType='text/html; charset=EUC-KR' %>
<% response.setHeader("Content-Language", "ko"); %>
</head>
<body>
<%* "\uc548\ubl55\ud558\ucl38\uc694" %>
</body>
</html>
JSP-, . 8.2, EUC-KR, "\uc548\ubl55\ud558\ucl38\uc694"
.
, EUC-KR . , .
.
Netscape Communicator: h t t p : //home . n e t s c a p e . c o m / e n g / i n t l

Internet Explorer: h t t p : //www.microsoft. com/ie/intlhome.htm

h t t p : //www.
w3.org/International/0-charset-lang.html.
Servlet 2.2, ServletResponse . setLocale.
.

JSP-
UCS (Universal Character Set ), 1993 . ISO (International Standards Organization) IEC (International Electrotechnical Commission).
UCS ,
. UCS 31-
, .. , ,
. , UCS, ,
16- ,
UCS Unicode.
UCS Unicode
. UTF-8
(UCS Transformation Format 8 UCS 8),
UCS -, - . ASCII-
l'TF-8 ! , -

201

, UCS. UTF-8
.
, UTF-8
. ,
, . 8.4 8.9.


, , , .
Java j a v a . u t i l .
Locale; , , .
Locale :

Locale(String language,
Locale(String language,

S t r i n g country)
String country,

String v a r i a n t )

ISO-. , .
http://www.ics.uci.edu/pub/ietf/http/related/iso639.txt h t t p : / / u s e r page .cheraie.fuberlin.de/diverse/doc/ISO_3166.html.
(variant). , , , WIN Windows, a MAC Macintosh. .
Locale , . 8.1.

8.1. , Locale

Locale.CANADA
Locale.CHINA
Locale.CHINESE
Locale.ENGLISH
Locale.FRANCE
Locale.GERMANY
Locale.ITALY
Locale.JAPAN
Locale.KOREA
Locale.SIMPLIFIED_CHINESE
Locale.TAIWAN
Locale.TRADITIONAL_CHINESE
Locale.UK
Locale.US

CA
CN

en
zh

en
fr
de
it

zh

FR

DE
IT
JP
KP

ja
ko

TW
UK
US

en
en

202

8.118N

, . 8.1,
Locale. , United States English.
Locale locale_l = new Locale("US", "en");
Locale locale_2 = Locale.US;

,
Locale .
Locale, ,
, :
// Locale
Locale locale - new LocaleC'BG", "") ;
Servlet 2.2 ServletResponse
setLocale getLocale. setLocale ContentLanguage , . 8.3
.
<_- , .,
Content-Language .
8.3.
<htmlxheadxtitle>Character Sets</title>
<% response.setLocale(java.util.Locale.KOREAN); %>
</head>
<body>
<%= "\uc548\ubl55\ud558\ucl38\uc694" %>
</body>
</html>

, . 8.2.


, Unicode
, ,
, , . Locale, , . ,
Web-.
.
JSP- .
, JSP-. ,
.
, .

203

, , , JSP-. JSP-
, , , . .
, j ava. u t i l . ResourceBundle, -, -. , . Java-,
,
. ResourceBundle
.

s t a t i c ResourceBundle g e t B u n d l e ( S t r i n g base)

s t a t i c ResourceBundle g e t B u n d l e [ S t r i n g b a s e ,

Object g e t O b j e c t ( S t r i n g key)

String getString(String

String[]

Locale)

key)

getStringArray(String

key)

, s t a t i c ,
ResourceBuncile. , , Locale. , , , .
, package.Bundle_la_C0_va, package.Bundle ,
base, la ,
, a v a - ( ). , . :
ResourceBundle bundle = ResourceBundle.getBundle("Resources",
new L o c a l e ( " f r " , " C H " ) ) ;

Swiss French ( ()).
Australian English { ()), :
Resources_f_
Resources_fr
Resources_en_AU
Resources_en
Resources
.
, MissingResourceException.
,
ResourceBundle , . ,

204

8. MSN


Object, S t r i n g String.
Object object = bundle.getObject("key_l");
String string = bundle.getString("key_2");
String[] array = bundle.getStringArray("key_3");

.
, , , , MissingResourceException.
, ResourceBundle .getBundle,
ListResourceBundle, PropertyResourceBundle. .

ListResourceBundle
ListResourceBundle
ResourceBundle. 8.4, 8.4,6
ListResourceBundle.
. 4,a. /WEB-INF/classes/Resources . Java.
import java.util.ListResourceBundle;
// "" ,
// .
public class Resources extends ListResourceBundle {
static final Object[][] contents = {
{ "message.welcome", "Welcome" ),
{ "picture.flag", "graphics/usa_flag.gif" ),
>;
public Object[][] getContents() {
return contents;

8.4,6. /WEB-INF/classes/Reaources_fr. Java


import java.util.ListResourceBundle;
// .
public class Resources_fr extends ListResourceBundle {
static final Object [][] contents = {
{ "message.welcome", "Bienvenue" ),
1 "picture.flag", "graphics/french_flag.gif" }
};
public Object[][] getContents0 {

205

return contents;

, 8.4,, ,
. getBundle . "" ,
.
8.4,6 Locale,
; _,
GIF.
getContents , L i s t ResourceBundle. -.
. 8.3 JSP-, .
, , JSP-,
,
, . , 8.4, 8.4,6.
! pit

BH

FfcwrHe

Joob

pki Edit Jltw

P-
Families Iwb

Atfduwj
Select a Language:
\

11

1 English ^|

Welcome

Show Massage

j
Tx Local hUanet

e'lUmgRMejiolSmfc. With JSP. *


j Ella Edit Jir Tfmni' i t

^ Buxln V* JSP Mcnnll lnim E... j j n i j t j


dlt yigw FflrtifltB . look

j 4 d m i | hltpi/ftKshBstBMO/il&vtMiAM .,.^| ^Go j

II

Select a Language:
| French ^J

Bienvenue

Show Message

> Lr cdrtrewt

. S.3. ListResourceBundle

206

. I18N

JSP-, . 8,3 , 8.4,.


8,4,. /test.jsp
<html><title>Using Resource Bundles With JSP</title>
<head><%@ page i m p o r t = ' J a v a . u t i l . L o c a l e ' %></head>
<body>
<font s i z e = M ' > 3 e l e c t a Language:</font>
<form action='showMessage.jsp'>
<select name='language'>
<option value='en'x%= Locale.ENGLISH.getDisplayNameO %>
<option value='f r'><%= Locale.FRENCH.getDisplayName() %>
</select>
< p x i n p u t type='submit' value='Show Message'/></p>
</form>
<7p>
</body>
</html>
JSP-, . 8.4,, Locale . getDisplaybiame. , . en_US,
getDisplayName "English", f r "anglais".
a c t i o n , 8.4,, showMessage . j sp, 8.4,.

8.4,. /showMessage. jap


<html><title>Using Resource Bundles With JSF</title>
<head>
<%9 page import='Java.util.Locale' %>
<%@ page impoi:t='Java.util.ResourceBundle' %>
</head>
<body>
<% String language = request.getParameter("language");
Locale locale = new Java.util.Locale(language, " " ) ;
ResourceBundle bundle
ResourceBundle.getBundle("Resources", locale);%>
<img src='<%= bundle.getString("picture.flag") %>'>
<font size='4'>
<b= bundle.getString("message,welcome") %>
</font>
</body>
</html>

207

JSP-, 8.4,,
Locale. getBundle, .
URL .
, 8.4,,
"" , , .
(Spanish),
.
, S p a n i s h .
R e s o u r c e s , a Re s o u r c e s__en,
, "" M i s s i n g R e s o u r c e E x c e p t i o n .

, 8.4, 8.4,6, 1 ; ,
, JSP-, 8.4,, . ,
,
MissingResourceException.
, .
JSP-, 8.5,,
, 8.4,.
8.5,a. /showMessage.jsp
< h t m l x t i t l e > U s i n g Resource Bundles With J S P < / t i t l e >
<head>
<%@ page i m p o r t ^ ' J a v a . u t i l . L o c a l e ' %>
<%@ page i m p o r t = ' J a v a . u t i l . R e s o u t c e B u n d l e ' %>
</head>
<body>
<% S t r i n g language = r e q u e s t . g e t P a r a m e t e r ( " l a n g u a g e " ) ;
Locale l o c a l e = new J a v a . u t i l . L o c a l e ( l a n g u a g e , " " ) ;
ResourceBundle bundle
ResourceBundle.getBundle ("Resources",

l o c a l e ) ,-%>

<img src='<%= bundle.getString(Resources.FIAG_PICTURE) %>'>


<font s i z e = ' 4 ' >
<%= bundle.getString{Resources.WELCOME) %>
</font>
</body>
</html>

208

8.118N

ResourceBundle .GetS t r i n g .
Resources, "" .
Resources 8.5,6,
8.5,6. /WEB- INF/classes /Resource , Java

import java.util.ListResourceBundle;
// ,
// "" .
public class Resources extends ListResourceBundle (
public s t a t i c final String WELCOME = "message.welcome";
public s t a t i c final String FLAG_PICTURE = " p i c t u r e . f l a g " ;
s t a t i c final Object!)[] contents {
( WELCOME, "Welcome" ),

{ FLAG_PICTURE, "graphics/usa_lag.gif" ),
);
public Object[][] getContents () {
return contents;

, 8.4,6, 8.5,. , Resources JSP-, .


8.5,. /WEB- INP/ classes /Re sour ces_f r. Java

import Java.util.ListResourceBundle;
// .
public class Resources_fr extends ListResourceBundle {
static final Object!][] contents {
{ Resources.WELCOME, "Bienvenue" J,
{ Resources. FLAG__PICTURE, "graphics/f rench_flag. gif' }

I;

public Object!)[] getContents() (


return contents;
}

PropertyResourceBundle
Java-
- . , , 8.6, 8.6,6 , Java-,
8.4, 8.4,6.

209

8.6,a. /WEB-INF/classes/Resources.properties
message.welcome^Welcome
picture.flag=usa_flag.gif

8.6,6. /WEB-INF/claases/Resources_f r .properties

message.welcome-Bienvenue
picture.flag=french_flag.gif
, , ResourceBundle . getBundle , -
= (, ( , ). , PropertyResourceBundle, , ge tBundle.
, Java-, . -, , Java-
. -,
, .
, .


. ,
, , . , , , .
8.7 JSP-, ,
, 8.4,; ,
URL
.
8.7,.
<htmlxtitle>Using Resource Bundles With JSP</title>
<head>
page import='java.util.Locale' %>
page import=' java.util.ResourceBundle' %>

</head>
<body>

210

8.118N

<% String language = request.getParameter("language");


Locale locale = new java.util.Locale{language, " " ) ;
ResourceBundle mes3ages_bundle =
ResourceBundle.getBundle("messages",locale);
ResourceBundle piatures_bundle =
ResourceBundle.getBundle("pictures", locale);%>
<img src='<%= pictures_bundle.getString("pictures.flag") %>'>
<font size='4'>
<%= messages_bundle.getString("message.welcome") %>
</font>
</body>
</html>
, , , JSP-,
. Java-, *
. .


JSP-, 8.7,6, , 8.7,, , .
8.7,6.
<html><title>Using Resource Bundles With JSP</title>
<head><%@ page import=fjava.util.Locale' %></head>
<body>
<jsp:useBean ici='bundleCache' scope-'request'
class=' beans.ilSn.BundleCache'/>
<% String language request .getParameter ( "language") ,Locale locale - new java.util.Locale(language, " " ) ; >
<img src='<%= bundleCaone.getString("pictures", locale,
"pictures.flag") %>'>
<font size='4'>
<%= bundleCache.getStringC'messages", locale,
"message.welcome") %>
</font>
</body>
</html>

211

,
.
, , 8.7,.
8.7,. /WEB-INF/clasaea/beans/ilBn/BundleCache. Java
package beans.ilBn;
import
import
import
import

java.util.Hashtable;
java.util.Locale;
java.util.MissingResourceException;
Java.util.ResourceBundle;

public class BundleCache (


private Hashtable bundles new Hashtable ();
public Object getObject(String base, Locale locale, String key)
throws MissingResourceException {
return getBundle(base, locale).getObject(key);
)
public String getString[String base, Locale locale, String key)
throws MissingResourceException {
return getBundle(base, locale).getString(key);
}
public String[] getStringArray(String base. Locale locale.
String key) throws MissingResourceException {
return getBundle(base, locale).getStringArray(key);
}
public ResourceBundle getBundle(String base, Locale locale)
throws MissingResourceException {
String key - base + "_" + locale.toString();
ResourceBundle bundle = (ResourceBundle)bundles.get(key);
if(bundle null) (
bundle > ResourceBundle.getBundle(base, locale);
bundles.put(bundle, key) ;
}
return bundle;
}
public void addBundle(ResourceBundle bundle, String base) (
Locale locale = bundle.getLocale ();
bundles.put(bundle, base + "_" + locale.toString ());
\
)
-
, , .

. -, , . -, , -.

212

8. MSN

,

, ,
, , .
j ava . t e x t ,
, , . J a v a , t e x t ,
, .


.
, mm/dd/yy, mm , dd , . : dd/mm/yy.
Java, t e x t . Date Format , .
, DateFormat.

s t a t i c DateFormat g e t l n s t a n c e ()

s t a t i c DateFormat g e t D a t e l n s t a n c e [ )

s t a t i c DateFormat getDateTimelnstance()

s t a t i c DateFormat getTimelnstancet)

: , ,
.
; , .
,
. DateFormat , .
DateFormat .
. 8.2.

8.2.

SHORT


( )

10/19/00 6:07

MEDIUM

Oct 19, 2000 6 : 0 5 : 5 5

LONG

O c t o b e r 19, 2000 6 : 0 7 : 0 1 MDT

FULL

T h u r s d a y , O c t o b e r 19,
6 : 0 4 : 3 3 MDT

2000

213

, 8,4 JSP-, ,
, , .
] Fotmafog D i e t and Ttnta -Microsoft !
file

Edit

Slew

Firm

rites

Tools

Help

: A d 4 s n | g ] http://locislhDsta080/i1 en-dafe

English (United States): Friday. October 20.2000 3:45:26 PM MDT


French (France): vendredi 20 octobre 200015 h 45 MDT
Japanese (Japan): 2000^10 20 158$45#26$MDT
jj Done

*; Local rhtrri

. 8.4.
JSF-, , 8,4, 8.8,
8.8.
<html><headxtitle>Format:ting Dates and Times</title>
<%@ page contentType=' text/html,- charset=UTF-8'%>
<%@ page import='Java.text.DateFormat' %>
<%@ page import='java.util,*' %>
</head>
<body>
<% DateFormat frenchFormat - DateFormat.getDateTimelnstance(
DateFormat.FULL,
DateFormat.FULL,
Locale.FRANCE);
DateFormat englishFormat = DateFormat.getDateTimelnstance(
DateFormat.FULL,
DateFormat.FULL,
Locale.US);
DateFormat japaneseFormat = DateFormat.getDateTimelnstance
DateFormat.FULL,
DateFormat.FULL,
Locale.JAPAN); %>
<font size='4'>
<%= Locale.US.getDisplayNameO %>:
<%= englishFormat.format(new Date(J) %><p>
<%= Locale.FRANCE.getDisplayName %>:
<%= frenchFormat. format [new Date () ) %></pxp>
<l= Locale.JAPAN.getDisplayName() *>:
<%-= japaneseFormat.formatfnew Date()] %></p>
</font>
</body>
</html>

214

8.118N

JSP-, 8.8, DateFormat,


, (FULL). format
, format , .
JSP-, . 8.4,
UTF-8.

,
, , - . Java, text
NumberFormat, .
DateFormat, Number Format , .

static
static
static
static

KumberFormat
NumberFormat
NumberFormat
NumberFormat

getlnstance()
getCurrencylnstance()
getNumberlnstance()
getPercentlnstance()

getNumberlnstance
. DateFormat, NumberFormat , . ,
getNumberlnstance () , a getNumberlnstance (Locale) - , .
, , , .
8.9 JSP-, ,
, ,
. . 8.5.

File

d,t

View

Fsvofltei

Toot

Help

I | ] htip //loeaihosi 8Q8Q/j1 BnmtimAesl isp

2]

Numbers:
English (United States): 150,012.88
German (Germany): 150 012.88
Currency:
English (United States): $29.99
Japanese (Japan): 30
Percents:
English (United States): 73%
Korean (South Korea): 737a

& Local nlionet

. 8.5. ,

215

8.9 JSP-, . 8.5.


8.9. ,
<htmlxhead><title>Number. Currency and Percent Formatting</title>
<%@ page contentType='text/html; charset=UTF-8' %>
<l@ page import='Java,text.*' %>
<l@ page import='java.util.Locale' %>
</head>
<body>
<*
NumberFormat enjnumber_fmt =
NumberFormat.getNumberInstance(Locale.US);
NumberFormat fr_number_fmt
NumberFormat.getNumberInstance(Locale.GERMANY);
NumberFormat en__currency_fmt NumberFormat.getCurrencyInstance{Locale.US);
NumberFormat fr_currency_fmt =
NumberFormat.getCurrencylnstance(Locale.JAPAN);
NumberFormat en_percent_fmt =
NumberFormat.getPercentInstance(Locale.US);
NumberFormat fr_percent_fmt =
NumberFormat.getPercentInstance{Locale.KOREA);
<font size='4'>
Numbers:<br>
<%= Locale.US.getDisplayName() %>:
<%= en_number_fmt.format(150012.88) %><br>
<%= Locale.GERMANY.getDisplayName() %>:
<%= fr_number_fmt.format{150012.88} %>
<p>Currency:<br>
<%= Locale.US.getDisplayName() %>:
<*= en_currency_fmt.format(29.99) %><br>
<%= Locale.JAPAN.getDisplayName() %>:
<%= fr_currency_fmt. format {29. 99) % x / p >
<p>Percents:<br>
<%- Locale.US.getDisplayName() %>:
<%= en_percent_fmt.format(.73) %><br>
<%= Locale.KOREA.getDisplayName() %>:
<%= fr__percent_fmt.format (.73) %></p>
</font>
</body>
</html>

NumberFormat , . format
NumberFormat .

216

. I18N

"I'm going to store" (" ") ;


"I'm going to {0}", {0} store (). , "I'm going to {0} to get {1}" (" {0} {!}").

3. , "TheJSP page shown in {0} is listed in {1}" {JSP-, {0), {1}.)

Java . t e x t .MessageFormat.
(, {0}, [1], ,{}) .
MessageFormat fmt = new MessageFormat("I'm going to {0] for { I ! " ) ;
Object [] p a r a m e t e r s = {"the d r u g s t o r e " , " r a z o r s " } ; %>
MessageFormat . *
MessageForraat. format,
{} . , MessageFormat , , formattedStrirtg "I'm
going lo drugstore for razors".
S t r i n g formattedstring = fiat .format (parameters) ;
. , , , . , ,
, :
MessageFormat frat = new MessageFormat("I went to 10) on 11,date)");
Object[] parameters = ("the d r u g s t o r e " , new J a v a . u t i l . D a t e () }; %>
String formattedstring = fmt.format(parameters);
. , ,
{n, time), {n, p e r c e n t } . , (, {n, time}), .
, MessageFormat. setLocale.
,
HessageFormat. a p p l y P a t t e r n ,
.
. 8.6 JSP-, ,
, .
, , JSP-;
(), . , , ,
8.10,.
2 - . - . .

, 217

^FomettiroMttsasej-Miaasoit Internet
] ib

Edit

View

Favorites

Toolt

_ j | |

tjFoimeHtngMewagej-M(cfoeo(tlWetiKpkifet

fktlp

| ] ocddhosieOBOMBn-rriEssages/lesLisp^

: File
(^Go

View

Fgrarllei

Toots

_ _ ! ! x|

Vtolp

Adcbsw |J0J ages^5howMe3Eage.J3p?lartguage*es_^J t ^ G o |

Disque rempii sur20:49:29 a


viernes 27 de octubre de 200Q

Selects Language:
1

Edit

| Spanish zi
... |

Show Message

_d
Done
isJFormaeingfcleMagej-MiaOTrft Internal Enototer

; file

Edit

view

Fgrarfl

IooEs

, - j E j *l

File

Seiect a Language:

::

Edit

View

Fgvarttej

Holp

A^dett j ^ J ages/3howMe?sdafi.js[)?tflrtqu^Qe-en T | i y G o

Disk number 3 filled up at 8:44:12 PM on


Oct27,2000

| English 21
Show Message

i,

Ti Lcealintieiel

. S.6.
8.10,a. /test.jsp
<htmlxtitle> Format ting Messages</title>
<head><%@ page import='Java.util.Locale' %></head>
<body>
<font size='4'

coloc='blue'>Select a Language:</font>

<form action='showMessage.jsp'>
<select name='language' >
<option value='en'>
<%= (new Locale ("en","")).getDisplayName() %>
<option value='es'>
<%= (new Locale("es",""]).getDisplayName () %>
</select>
<pxinput type='submit' value='Show Message' /></p>
</form>
</body>
</html>

s,

^iFotmatling H e t t s a - 5<1 Internet Enpfcmi _ ^ ! J<J

:4|] hUpiy/locaho^SOSO/iiBn^messsges/J r'Go

Ji> Local intranet

218

8.118N

. action
showMessage . jsp.
8.10,6.
8.10,6. /showMessage.jsp
<html><head><title>Formatting Messages</title>
<%@ page import='Java.text.MessageFormat' %>
<%9 page import^'java.util.Locale' %>
<%@ page import^'java.util.ResourceBundle' %>
</head>
<body>
<% // , .
String language - request.getParameter("language");
Locale locale " new java.util.Locale(language, " " ) ;
ResourceBundle bundle ~ ResourceBundle.getBundle(
"message_formats", locale);
// ...
String pattern bundle.getString("message.diskFull");
// ...
// -.
MessageFormat fmt * new MessageFormat(pattern);
// , , ,
II {0} {1} ... {}
// parameters [0] parameters[1] ... parameters[n]
Object[] parameters = (new Long(3), new java.util.Date()}; %>
<font size=f 4'>
<% II (parameters[1])
// ,
fmt.setLoeale(locale) ;
II .
fmt.applyPattern (pattern) ,- %>
<%= fmt.format(parameters) %></p>
</font>
</body>
</html>
JSP- ,
English Spanish. -, ,
MessageFormat, format
. , {) {1} .
8.10, 8.10, .
8.10,. /WEB-INF/claases/app_arL.properties
message.formatstring=Disk number <b>{0}</b> on computer <b>{l)</b> is full

219

.10,. /WEB-INF/classes/app es.properties

message.formatString=El numero <b>{0}</b> de disco sobre la computadora el


<b>U)</b> es lleno

,
4.0, Netscape, Internet Explorer ,
. ,
.
, , ,
.


,
. , , ServletRequest.getLocales ServletRequest.getLocale. getLocales Enumeration, ,
, getLocale .
. 8.7 Language Preference Internet
Explorer JSP-, , .
.2

Language Pidnencc

Some Web stet offer vxtan in (n*pte languages. Von can


choose ieve<d linguegei below; 4 te treated ri ordec
purity.

^jDetecttigLocatetFiomBreiwtetSeWna! MiciospdInter... ^
frte

d.t

Visw

Fovorltei

look

Language
[ko]
Fiencn(Franlili)
Chinese [*]
Croatian [hr|
[cs]
Danish [da]
English [Urated S U I K I |en-u:]

Locales:

6*1.

Menyt and duiog txjwjs eie cui


h E ^ h t U d S )

Korean
French
Chinese
Croatian
Czech
Danish
English (United Stales)

Orat
'f Local intrant

. . 7. ,
^-, . 8.7, 8.11.

8.11.
<html><title>Detecting Locales From Browser S e t t i n g s < / t i t l e >
<head>
<%@ page import=' Java.util.Enumeration' %>

220

8.118N

<%@ page
<%@ page
</head>
<body>

Import^'Java.util.Locale' %>
import='Java.util.Vector' %>

<font

>Locales:</font>

<% Enumeration eri = request. getLocales {) ;


while(en.hasMoreElements[)} f
Locale locale = (Locale)en.nextElement(); %>
<= locale.getDisplayNam^O %><br>

</body>
</html>

JSP- request .getLocales


Enumeration, , .


, ,
. ; , .
. 8.8 JSP-, , . , ,
.
. 8.8 , English,
, Czech.
p] Locattis Bunds Given a Lit! ol Locate! Micro ...
|

Fi

dit

Klcw

Firants1

loots

] Addren | g ] ./-:l/iiBn-bunde-toi

-IDtxj

0}LocMinoBuntto Given a Lirt ol Locates - Miowcft... . IDl x|


j[ Eib
!

^it

yisw

Fjyorltes

Locales:

Locales:

French
English ^United States)
Finnish
Chinese
Croatian
Ciech
Danish

French
English (United States)
Finnish
Chinese
Croatian
Czech
Danish

Got a bundle for English

Got a bundle for Czech

L^cdinlr anet

IOQIS

I Dane

"

Puc. 8.8. ,

221

JSP-, . 8.8, 8.12,.


8,12,a. / t e s t . j a p
<htmlxtitle>Locating Bundles Given a List of Locales</title>
<head>
! <ii taglib uri='/WEB-INF/tlds/il8n.tld' prefix='il8n' %>
<%@ page import='java.util.*' %>
</head>
<body>
<font size='4'>Locales:</font>
p
<4 Enumeration en = request.getLocales{);
while(en.hasMoreElements{)) {
Locale locale = (Locale)en.nextElement(); %>
<%= locale.getDisplayName[) %><br>

<jsp:useBean id=' locator'

scope='request'

class='beans.ilBn.BundleLocator' />
<% ResourceBundle bundle = locator.locateBundle(request,

"app");

if(bundle == null) t %>


No bundle found
<% ) e l s e ( %>
Got a bundle for: <%= bundle.getLocale().getDisplayName(} %>
<% } % >

</body>
</html>
JSP- , ,
HttpServlet Re quest. getLocales. BundleLocator .
, BundleLocator,
8.12,6.
8.12,6. / WEB - INF/ classes /beans /il8n/B\indleLocato r. jiav a
package beans.ilSn;
import
import
import
import

java.util.Enumeration;
java.util.Locale;
java.util.MissingResourceException;
java.util.ResourceBundle,-

222

8.118N

import javax.servlet.ServletRequest;
import javax.servlet.jsp.JspException;
public class BundleLocator {
public ResourceBundle locateBundle(ServletRequest request,
String base)
throws JspException (
Enumeration en = request.getLocales();
Locale defaultLocale - Locale.getDefault();
ResourceBundle fallbackBundle = null;
try [
fallbackBundle = ResourceBundle.getBundle(base,
defaultLocale);
\
catch(MissingResourceException ex) {
throw new JspException(ex.getMessage());
while(en.hasMoreElements ()) {
Locale locale = (Locale)en.nextElement();
ResourceBundle bundle = null;
try (
bundle ~ ResourceBundle.getBundle(base, locale);
catch(MissingResourceException ex2) {
II ...
continue;
if(bundle != fallbackBundle)
return bundle;
if (fallbackBundle !- null ss bundle = fallbackBundle) (
String lang - locale.getLanguage();
String defaultLanguage - defaultLocale.getLanguage();
if(lang.equals(defaultLanguage)}
return bundle;
return null;

, . ,
.
"" , , . "", ;
. , BundleLocator. locateBundle n u l l .

223


JSP-, , Java-,
. message format, Java- H3jSP-npKVMeHTOB.

message
, , , .
<% t a g l i b u r i = ' / W E B - l N F / t l d s / i l 8 n . t l d p r e f i x = ' i l 8 n '
<:il8n:message base=' R e s o u r c e s '
<il8n:message

%>

key='messages .welcome' />

base= Resources'
key='messages.welcome'
l o c a l e - ' < % = Locale.UK %>'/>

b a s e , ,
R e s o u r c e s _ e s . p r o p e r t i e s R e s o u r c e s _ f r . p r o p e r t i e s R e s o u r c e s . key
.
message, ,
. , message
. , ,
, .
message .
params, .
, params.
. 8.9 JSP-, message.
UTF-8 , , . , 8.9
(), ,
, .
JSP-, . 8.9, :
<%@ t a g l i b u r i = ' / W E B - I N F / t l d s / i l 8 n . t l d ' p r e f i x = ' i l 8 n ' %>
<%@ page c o n t e n t T y p e = " t e x t / h t m l ; charset=UTF-8" %>
<il8n:message

base-'app'

<il8n-.message base=' app'

key='messages.welcome'/>
key='messages, i n t r o d u c t i o n '
locale='<%= Java.util.Locale.KOREAN %>'/>

<hr>
<il8n:messaqe base='app' key='messages.today'
locale='<%= Java.util.Locale.ENGLISH 4>'
params='<%= new Object[] { new Java.util.Date () ) %>'/>

224

8.118N

<ilSn:message

base='errors'/>

key='errors.test'

- 1 t w i k n l u u i Mh JSP * I IB> WoriHML


Some Web liCnotfc* corfcnt in mufciplc language* Vou un
chooie tevqcd taguagn Wow: they *** be UMtod in otd of
priority.

-Ml^l

* ^J **" !

WiilcjHfftuotmiii^^iiM.

Lano>oe;
Crojtr#i|hr]
Chinese t * ]
Kenan Pol
English [United S 1*1 es) [en-ut]
Fiench [France] |r)
Czech [ a i
Danith [da]

Today i> 0: 2. 3000

frtL

MttMflttHHHBa
Menui d cUag bonn *t curgnVdiptatad
nEnobh[UniledStelwl

OK

Chens..
Cancel

-' INofMcr^utcn i * i JSP Curtan Ti ^ Hicio*lrt*n<_. _ | D |

ob

Some W e b v'et oflff content TI mJtple LanguugeT. You cjn


choa levoal langue$ei below, they * be lie ned r adet cf
poa*li.

D |

Bonjour
Cmalian |hi]

Move Up
Move [town

Kcrein |ko|
English (Urted SlalesllHUJt!
Cich ( )

TodJjiiOctia.ZIOO

D^hldal

Menus and dWog bowt an currentV deployed

kiEn*Ml)riJSrtil

OK

i > i m s s ^ s g n f l ^ r r c i i f <Cc e .ii i

rh,-.

i^ienne...

Cancel
-^J Done

. fi.9. message
( ) , :
. l o c a l e
, , .
params. e r r o r s , ,
, .
, , .
WEB-INF/classes/app_en.properties
WEB-INF/classes/app_fr.properties
WEB-INF/classes/app_ko.properties
WEB-INF/classes/errors_fr.properties
WEB-INF/classes/errors_en.properties

225

. 8.9 , . , , , .
.
e r r o r s ;
English , French.
, . 8.12, .
8.12,-8.12,, , . Java-, . 8.9.
8.12,. /WEB-INF/classes/app an.properties
messages.welcome=Good Morning
messages.introduction=Welcome to the meeting

8.12,.

/WEB-XNF/claases/app_r.properties

messages.welcome=Bonjour
messages.introduction-Bienvenue

8.12,.

meeting

/WEB-XNF/elasaes/appJco.properties

messages.introduction=\ud68c\uc758 \ucc38\uclld \uc744


\ud658\uc601\ud569\ub2c8\ub2e4

8.12,6. /WEB-XKF/classes/errors_en.properties
errors.test=A t e s t error message

8.12,. /WEB-INF/classes/errora_fr.properties
errors.test=Un message d'erreur d ' e s s a i
message 8.12,.
. 12,3. /WEB-INF/classes/tags/ilSn/MessageTag. Java
package

tags.i!8n;

import Java.text.MessageFormat;

226

8. 118N

import java.util.Locale;
import java.util.ResourceBundle;
import javax.servlet.jsp.JspException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.jsp.tagext.TagSupport;
import beans.il8n.BundleLocator;
import beans.il8n.BundleCache;
public class MessageTag extends TagSupport {
private static BundleCache bundles = new BundleCache ();
private String base, key;
private Locale locale;
private Obj ect[] params;
public
public
public
public

void
void
void
void

setBase(String base)
{
setLocale(Locale locale) {
setKey(String key)
{
setParams(Object[] params)

this.base = base; )
this.locale = locale; )
this.key = key; )
{ this,params = params;}

public int doEndTag() throws JspException {


MessageFormat fmt = null;
String message null;
ifflocale !- null)
message = bundles.getstring(base, locale, key);
if(message == null)
message = getMessageUsingBrowserLocales();
iffparams != null) {
fmt = new MessageFormat(message);
ifdocale != null) {
fmt.setLocale(locale);
fmt.applyPattern(message);
)
message = frat.format[params);
}
try (
pageContext.getOut().write(message);
}
catch(Exception ex) ( // lOException
// MissingResourceException
throw new JspException(ex.getMessage());
)
return EVAL_PAGE;
)
private String getMessageUsingBrowserLocales()
throws JspException (
String message = null;
BundleLocator locator = new BundleLocator();
ResourceBundle bundle = locator.locateBundle (

227
pageContext.getRequest(),

if[bundle != null) (
bundles.addBundle(bundle, base);
message = bundle.getString(key);

base);

return message;
//
public void release() (
base = key = n u l l ;
locale = n u l l ;
params = n u l l ;

message : base, key, l o c a l e


params. , . message .
.
, .
, out.
l o c a l e
. , , , key. , n u l l .
.
, getMessageUsingBrowserLocales. , . bean,
, .
params, message , .
, , , message , out.

format
format, ,
, , , . message; .
^-, format, . 8.10.

228

8.118N

*J

I
J

Currency:

i:' ; C U K m r 4 .taHiiFwrtog.MK*lnliMI<pk>

Edii

J-.

l^mto

^JffljSJ

Times:

English [United States): $134,588.99

English (United States): 7:2115 PM

E l f i s h (United Kingdom). 134.588 99

French:721:15PM
Chinese: 7:21:15 PM

Numbers;
English (United Stales): 134.538 93

Dates;

English (United Kingdom). 134.588.99

English (United States)- Oct 28.2000


German: Samstag.IS. Oktcber2000

Percents:

Chinese: 2 0 0 0 ^ 1 0 ^ 2 8

English (United States): 99%

Dateimes:

Korean 88%

English (United States): Oct 23,2000 7:21:15 PM

Italian Oct28,2O00 7:2V15PM


Japanese 2000 1 OS 28 198#21^15WMDT

.-J

. 8.10.
,
JSP-, . 8.10,
format :
<il8n:format

currency='13458B.99'/>

<ilBn:format currency='134588.99'
<il8n:format

number^'1345B8.99'/>

< i l 8 n : f o r m a t number^'134588.99'
<il8n:format

l o c a l e = ' < $ = Locale.UK %>'/>

locale='<%= Locale.UK %>'/>

percent='.99'/>

< i l 8 n : f o r m a t p e r c e n t = ' . 8 8 ' locale='<%= Locale.KOREAN %>'/>


JSP-, . 8.10, :
< i l 8 n : f o r m a t time='<%= new J a v a . u t i l . D a t e ( ) %>'/>
< i l 8 n : f o r m a t time='<%= new J a v a . u t i l . D a t e %>'
locale='<%= java.util.Locale.FRENCH %>'/>
< i l 8 n ; f o r m a t time='<%= new J a v a . u t i l . D a t e { ) %>'
locale='<%= Java.util.Locale.CHINESE >'
dateStyle='<%= Java.text.DateFormat.FULL %>'/>
< i l 8 n : f o r m a t date='<%= new J a v a . u t i l . D a t e ( )

%>'/>

< i l 8 n ; f o c m a t date='<%= new j a v a . u t i l . D a t e ( ) %/>


dateStyle='<%= java.text.DateFormat.SHORT %>'/>

229

<il8n:forroat date='<%= new Java.util.Date() %>'


locale=f<%= java.util.Locale.CHINESE %>'
dateStyle='<%= 3ava.text.DateFormat.FOLL %>'/>
<il8n:format dateTime='<= new Java.util.Date(} %>'/>
<il9n:format dateTime='<%= new Java.util.Date (J %>'
locale='<%= Java.util.Locale.JAPANESE %>'/>
<il8n:format dateTime='<%=
locale'<%=
timeStyle='<%=
dateStyle='<%=

new Java.util.Date() %>'


Java.util.Locale.JAPANESE %>'
Java.text.DateFormat.FULL %>'
Java.text.DateForraat.FULL %>'/>

format 8.13. format , ,


.
8.13./WE8-INE7classea/tag3/il8n/FormatTag
package tags.il8n;
import
import
import
import
import

Java.text.*;
Java.util.Date;
Java.util.Locale;
javax.servlet.jsp.JspException;
javax.servlet.jsp.tagext.*;

public class FormatTag extends TagSupport {


private static DateFormat dateFormat;
private static NumberFormat numberFormat;
private static final int UNASSIGNED=-1,
TIME=0, DATE=1, DATE_TIME=2y
NUMBER=3, CURRENCY=4, PERCENT=5;
private Date date;
private double number = (double)UNASSIGNED;
private Locale locale = null;
private int dateStyle
timeStyle
formatStyle
numberStyle

=
=

UNASSIGNED,
UNASSIGNED,
UNASSIGNED,
UNASSIGNED;

// doEndTagO
public int doEndTag() throws JspException {
if(date != null) { // date
if(formatStyle == TIME)
processTime();
else if(formatStyle = DATE)
processDate();
else if(formatStyle == DATEJTIME) processDateTime()
showFormatted[dateFormat.format(date));

230

8.118N
if(number != UNASSIGNED) { // number
if(numberStyle = NUMBER)
processNumber();
else if[numberStyle = CURRENCY) processCurrency() ;
else if(numberStyle == PERCENT) processPercentt);
showFormatted(numberFormat.format(number));
)
return EVAL_PAGE;

)
private void showFormatted(String string) throws JspException {
try (
pageContext.getOut().write(string);
}
catch(Exception ex) {
throw new JspException(ex.getMessage());

// Set- .
public void setLocale(Locale locale)I this.locale locale; }
public void setDateStyle(int style) { this.dateStyle = style; )
public void setTimeStyle(int style) { this.timeStyle = style; )
public void setNumber(Double number)(
this.number = number.doubleValue(); numberStyle = NUMBER;
)
public void setCurrency(Double number) (
setNumber. (number) ; numberStyle = CURRENCY;
}
public void setPercent(Double number) {
setNumber(number); munberStyle = PERCENT;

public void setDate(Date date) {


this.date = date; formatStyle =
}
public void setDateTime(Date date)
this.date = date; formatStyle =
)
public void setTime(Date date) {
this.date = date; formatStyle =
}

DATE;
{
DATEJTIME;
TIME;

// , .
private void processNumber() (
numberFormat = (locale = null) ?
NumberFormat.getNumberInstance () :
NumberFormat.getNumberInstance(locale);
)
private void processCurrency() I
numberFormat < (locale == null) ?
NumberFormat.getCurrencylnstance() :
NumberFormat.getCurrencylnstance(locale);

private void processPercent() {

231
numberFormat = (locale == null) ?
NumberFormat.getPercentInstance() :
NumberFormat.getPercentInstance(locale);
>
private void processTime() (
if(timeStyle = UNASSIGNED) {
dateFormat = DateFormat.getTimelnstance();
>
else (
dateFormat = (locale == null) ?
DateFormat.getTimelnstance(timeStyle) :
DateForraat.getTimelnstance(timeStyle,locale}
)
>
private void processDate() (
if(dateStyle == UNASSIGNED) (
dateFormat = DateFormat.getDatelnstance();
}

else t

dateFormat = (locale == null) ?


DateFormat.getDatelnstance(dateStyle} :
DateFormat.getDatelnstance(dateStyle,locale)
private void processDateTime() throws JspException (
if(timeStyle == UNASSIGNED Si dateStyle UNASSIGNED) {
dateFormat - DateFormat.getDateTimeInstance();
}
else {
if(timeStyle == UNASSIGNED N dateStyle == UNASSIGNED) {
throw new JspException ("You must assign both" +
"timeStyle and dateStyle, or" +
"neither");
}
dateFormat = (locale == null) ?
DateFormat.getDateTimeInstance(
timeStyle, dateStyle) :
DateFormat.getDateTimelnstance(
timeStyle, dateStyle, locale);

11 .
public void release() (
numberFormat = n u l l ;
dateFormat = n u l l ;
date = null;
number = (double)UNASSIGNED;
locale = null;
dateStyle = timeStyle formatStyle = numberStyle = UNASSIGNED;

232

8.118N

FomTag.doEndTag. d a t e number, doEndTag , , .


.

, , , , Java , . Web- Web-, .


World Wide Web . ,
Web, , ,
.
, .

...
.
- .

j*

- .
- .
- .
.
-.
.

SSL .

.
- Resin.
- Tomcat 4.O.
Web-.
.

. World Wide Web


, .. Web- , .
, Java,
, . Web ,
Servlet 2.2 (
http://java.3un.com/products/5ervlet/download.html).

, , .
1. , ,
JSP-.
2. ,
,
.
3. ,
.
, . ,
, , . ,
.

236

9.


.
, .
, , . , , WEB-INF/web. xml, . web. xml .
<web-app>
<securifcy-constraint>
< 1 Web- >
<web-resource-llection>
<web-resource-name>Protected Resource</web-resource-name>
<ur1-pattern>/page_l.jsp</ur1-pattern>
</web-resource-collection>
<auth-constraint>
< ! , ,
Web- >
<role-name>customer</role-name>
</auth-constraint>
</security-constraint>
<security-constraint>
< ! Web- >
<web-resource-collection>
<web-resource-name>Protected Resource2</web-resource-name>
<url-pattern>/page_2.jsp</url-pattern>
</web-resource-collection>
<auth-constraint>
< ! , ,
Web- >
<role-name>eniployee</role-name>
</auth-constraint>
</security-constraint>
<web-app>
/page_l.jsp /_2.j sp
, customer employee.
,
, . Tomcat tomcatusers . xml :
<tomcat-users>
<user name="rwhite" password="tomcat" roles="customer", "other"/>
</tomcat-users>

237

rwhite customer other;


tomcat. , , rwhite
/page_l. j sp, /page_2 , j sp .

, Resin .
. 9.1 HttpServletRequest, .
9 . 1 . HttpServletRequest

Principal getQserPrincipal ()


Java.security.Principal

boolean isUserlnRole(String)

,
,

String getRemoteUser ()

API set-, get-, . 9.1. , ; .


,
.
. 9.2 ServletRequest, , .
9.2. ServletRequest,
{ getAuthType
HttpServletRequest)

String getAuthType ()

: BASIC, SSL n u l l

boolean isSecure ()

t r u e , HTTPS

String getSchemef)

: h t t p , https...

238

9.

get-, . 9.2,
set-. ,
.


. XML- . ,
, , .
, , ,
, , .
,
, .
.

. , , . ,
, , , . , Tomcat XML-, Resin, .
, , , ,
, , ,
. ,
.


Web- ( ).
"

-.

SSL .

239

.
-
RFC2617, f t p : / / f t p . i s i .edu/
in-notes/rfc2617.txt.
/WEB-INF/web. xml ,
.
<web-app>
<login-config>
<auth-method>BASIC</auth-method>
<realm-name>Basic Authentication Example</realm-name>
</login-config>
</web-app>
, SSL.
H t t p S e r v l e t R e q u e s t .
getAuthType.


HTML/1.1.
, . , ,
. , .

. base64, ..
.
, Tomcat 4.0,
. 9.1.
. 9,1 / p r o t e c t e d - p a g e , j sp, ,
.
, JSP-;
. JSP- 9.1,.
9.1,. /protected-page.jsp
<htmlxheadxtitle>A Protected Page</title></head>
<body>
<S@ include file='show-security.jsp' %></p>
<p>
<% if(request.isUserlnRole("tomcat")) { %>
You are in <i>tomcat</i> role<br/>

240 9.
<% } e l s e (%>
You are <b>not</b> in <i>tomcat</ixbr/>
<% if(request.isUserlnRole("rolel")) ( %>
You are in <i>rolel</ixbr/>
<% } else {%>
You are <b>not</b> in <i>rolel</ixbr/>

</body>
</html>

1BI2J
fill

d.t

fffnjilrn

JeoSi

El
Rtquti) AulhnticlBil with: BASIC,
This connection It nol secure
Remoie Addr localhnst
Remote Host localhosl
Remote Addr 127 D.O.I
You ere in tomcat role
You *ra net in TOief

. 9. /. , Tomcat 4.0

,
, : tomcat r o l e l .
JSP-, 9.1,6.
.1,6. /show-security.jsp
<font size='4' color='blue'>
Security Information:
</font><br>
User p r i n c i p a l : <%= request.getUserPrincipal[).getHame!) %>.<br/>
User name: <%= request.getRemoteUser(} 4>,<br/>
Request Authenticated with: <%= request.getAuthType() %>.<br/>

241

<* i f ( r e q u e s t . i s S e c u r e ()) { %>


This c o n n e c t i o n i s s e c u r e . < b r / >
<t ) e l s e ( %>
This connection is not secure.<br/>
<* } %>
Remote Addc: <l= request.getServerName() %><br/>
Remote Host: <%= request.getRemoteHost() %><br/>
Remote Addr: <%= request.getRemoteAddr() %>

, , .
, 9.1,, . 9.1,.
.1,. /WEB-INF/web.xml
<?xml version="l." encoding="ISO-8859-l"?>
<!DOCTYPE web-app
PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.2//EN"
"http://Java.aun.com/j2ee/dtds/web-app_2.2.dtd">
<web-app>
<security-constraint>
<! Web- -->
<web-resource-collection>
<web-resource-name>A Protected Page</web-resource-name>
<url-pattern>/protected-page.jsp</url-pattern>
</web-resource-collection>
<auth-constraint>
<! , ,
Web- >
<role-name>tomcat</role~name>
<role-name>rolel</role-name>
</auth-constraint>
</security-constraint>
<login-config>
<auth-method>BASIC</auth-method>
<realm-name>Basic Authentication Sxample</realm~name>
</login-config>
</web-app>
/protected-page . j sp , tomcat r o l e l . BASIC.
Tomcat $TOMCAT_H0ME/conf/tomcat-users.xml, 9.1, .

242

9.

9.1,. $ HOME/eonf/tomcat-users .xml


<tomcat-users>
<user narae="tomcat" password="tomcat" roles="tomcat" />
<user name="rolel" password="tomcat" roles="rolel" />
cuser name="both" password="tomcat" roles="tomcat,rolel" />
</tomcat-users>
tomcat tomc a t , ,
tomcat. . 9.1 , tomcat, r o l e l .
, 9.1, ,
both. . , . 9.1, both, , tomcat, r o l e l .

-
^ ,
. , , -, 1.
. 9.2 - Tomcat. , , . 9.1, . 9,2 , .
-
DIGEST.
<login-config>
<auth-method>DIGEST</auth-method>
<realm-name>Digest Authentication Example</realm-name>
</login-config>
</web-app>
-
.
, -,
, Tomcat 4.0, Tomcat 3.2.1.


, . , 1 - / /1.1,
ftp:/'/fllt.isi.edu/in-notes/rfc2617.txt. - . .

243
Wcb-. , , ,
.

Tnii l e a n Web Sit (Jt todtmtj fou to too on


type Ux Ui Name id Patnmd Ibst

SWIed Pa
]

j jAdjtfem |C] htp7/1oc

Security Information.
User name. Iome at.
Request Aulhenticated with: BASIC.
This connection is not secure.
Remote Addn localhasi
Remote Hosi- localhost
Remote Mtiv 1 2 7 0 0 1
You 5r& m tomcat role
Vou are not in rotef

. 9.2. - Tomcat

,
, .
-, HTTP, .
, . .
.
1. Web-.
2. , , .
3. , , .
, ,
. 9.3.
, . 9.3 , . ,
. ,
, Web-,
-.

244

9.

Inlx;

; 1 [.ogh Pige * Wane* *


Ed''

lit"

&

AjJdun|jT] hp//kKi*loil:

hltprVkjcalhoilBOSflAocurly/fam/efra ^

Please Login
Name:

[badneme

-IDlxl

-HeromH internet *

Ifb

"he usemame and password you supplied are


not valid.

ii

Click 1 to ratty login

Pes sword: r*~~

'

IBIxl

Bl Wfeoiiie - Mbwoft Irnmrf 4*1


fill

dlr

fill

Jl.

Please Login

sttw

nnnia

lool:

Welcome (om ca(

1
Mams: | ID meat

dit

,;

You are in fa meat role


You are not Inra/ef
You are not in tole2

Password: I

' ' Local ntunM

. 9.. Tomcat

, . 9.3, , 9.2,.
9.2,a. /login.jap
<htmlxheadxtitle>Login Page</titlex/head>
<body>

<font size='5' color-'blue'>Please Login</font><hr>


<form action^'j_security_check' method-'post'>
<table>
<tr><td>Name:</td>
<tdxinput type-' text' name=' j_usemame' ></tdx/tr>
<trxtd>Password:</td>
<tdxinput type=' password' name-' j_password' size=' B' ></td>
</tr>
</table>
<br>
<input type='submit' valuer'login'>
</form></body>
</html>

245

JSP-, , ,
. j _ s e c u r i t y _ c h e c k , j_username
j_password
, . . 9.3.
9.3. ,

j_username

j_password

i_security_check

a c t i o n

Web-, , 9.2,6.
9.2,6. / e r r o r . j s p
<html> <head> <title>Error! </titlex/head>
<body>
<font size='4' color= f red f >
The username and password you supplied are not valid.
Click <a href='<%= response.encodeURL("login.jsp") %>'>here</a>
to retry login
</body>
</form>
</html>

Web- .
9.2,.
9.2,. /WEB-INF/web.xml
version="1.0" encoding="ISD-88S9-l"?>
<!DOCTYPE web-app
PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.2//'
"http://java.sun.com/j2ee/dtds/web-app_2.2.dtd">
<web-app>
<security-constraint>
<web-resource-collection>
<web-resource-name>A Protected Page</web-resource-name>
<url-pattern>/protected-page.jsp</url-pattern>

246

9.
</web-resource-collection>

<auth-constraint>
<role-name>tomcat</role-name>
</auth-constraint>
</security-constraint>
<login-config>
<auth-method>FOFM</auth-method>
<form-login-config>
<form-login-page>/login.jsp</form-login-page>
<form-error-page>/eri:or.jsp</form-error-page>
</form-login-config>
</login-config>
</web-app>

, 9.2,, protected-page . j sp. , tomcat. FORM, Web-, .

SSL
SSL {Secure socket layer ) , . , SSL .
SSL http://home.
netscape.com/eng/ssl3/3-SPEC.HTM.
SSL , "" . SSL
. , ,
SSL Resin
http://www,caucho.com/products/resin/ref/faq.xtp.

SSL. Tomcat , .


:
. , ,
. , , .
, .

247

, , , . Resin Tomcat. ,
.

Resin
Resin . , A u t h e n t i c a t o r .
Resin, , . , Resin Apache IIS;
Wcb-. Resin
.
, Resin, . 9.4.

Kin

Fannie

Bob

. rto Network Poinrat!

TjxJ

hHpV/bcoKjrt
dnd p n v d

6*1 yitw

Aiihamic^ai E(fe
Ioob

Wp /) /

SeciBfty Wormaticin
User principal: resin
Usarnama: resin
Re4"5t Auihenlicsteif wilh basic.
This connection is not secure.
H e m ' .'.*! localhost
Remote Hosl: localhosi
RemoleAddr 127 0.0.1
You are in reein-uset rote

. 9.4. Resin
, . 9.4, JSP- ( 9.3,).
9.3,a. /protected-page.jsp
<htmlxheadxtitle>A Protected Page</title></head>
<body>
<%@ include file='show-security.jsp' %></p>

248

9.

<% if(request.isUserlnRole("resin-user")) { %>


You are in <i>resin-user</i> role<br/>
<% ) else (%>
You are <b>not</b> in <i>resin-user</i> role<br/>
</body>
</html>

JSP- show-security, j sp, . , .


, 9.3,, .
9.3,6 .
9.3,6. /WEB-INF/web.xml
<?xml version="l.0" encodings"ISO-8859-l"7>
<!DOCTYPE web-app
PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.2//EN"
"http://Java.sun.com/j2ee/dtds/web-app_2.2.dtd">
<web-app>
<security-constraint>
<! Web- >
<web-resource-collection>
<web-resource-name>A Protected Page</web-resource-name>
<url-pattern>/protected-page.j sp</url-pattern>
</web-resource-collection>
<auth-constraint>
<role-name>resin-user</role-name>
</auth-constraint>
</security-constraint>
<login-config>
<auth-method>BASlC</auth-method>
<realm-name>Basic Authentication Example</realm-name>
<! , Resin >
<authenticator id='beans.SimpleAuthenticator'/>
</login-config>
</web-app>

BASIC,
/protected-page. j sp ,
r e s i n - u s e r . L-
a u t h e n t i c a t o r ,
. 9.3,.

249

9.3,. /WEB-INF/classes/beans/SimpleAuthenticator. Java


package beans;

import com.caucho.server.http.AbstractAuthenticator;
import com.caucho.server.http.BasicPrincipal;
import Java.security.Principal;
public class SimpleAuthenticator extends AbstractAuthenticator {
public Principal authenticate(String user, String password) {
boolean valid password != null &&
password.equals("resin") ss
user != null 5b user.equals("resin");

if(valid) return new BasicPrincipal(user);


else
return null;

public boolean isUserlnRole(Principal user, String role) (


return user.getName().equals("resin") &&
role.equals("resin-user");

, 9,3,,
AbstractAuthenticator; a u t h e n t i c a t e
isUserlnRole. A u t h e n t i c a t e s , A b s t r a c t A u t h e n t i c a t o r .
, a u t h e n t i c a t e B a s i c P r i n c i p a l ,
null. B a s i c P r i n c i p a l com.caucho. s e r v e r , h t t p .

Tomcat4.0
Tomcat 4.0 (realm), , Resin. Resin,
Tomcat /WEB-INF/web.xml,
$TOMCAT_HOME/conf / s e r v e r . xml.
<\ $TOMCAT_HOME/conf/server.1. >
< ! - - . >
< ! ,
"/" >
Server p o r t = " 8 0 0 5 " shutdown="SHUTDOWN" debug="0">
<!

,

<Realm className="org.apache.catalina.realm.MemoryRealm"
/>
>
<ReaIm className="CuatomRealm"/>
</Server>

250

9.

S e r v e r
o r g . a p a c h e . c a t a l i n a . realm.MemoryRealm, . ( Tomcat
.) , , org.
a p a c h e , c a t a l i n a . r e a l m . Memo Re aim, . , .
, ,
RealmBase, Realm,
RealmBase , , . . 9.4.
9.4. RealmBase

boolean hasRole (Principal


p r i n c i p a l , String role)

t r u e ,

String getPassword {String


user)

Principal
getPrincipal {String user)

P r i n c i p a l ,

CustomRealm, s e r v e r . xml { ), 9.4.


9.4, ,
import Java.security.Principal;
import org.apache.catalina.realm.RealmBase,public class CustomRealm extends RealmBase {
public boolean hasRole{Principal principal, String role) (
String name = principal.getName(};
if[name.equals("tomcat"))
return role.equals("tomcat");
if(name.equals("rolel"))
return role.equals("rolel");
if[name.equals{"both"))
return role.equals("tomcat") |[ role.equals("rolel");
return false;
}
protected String getPassword(String username) (
return "tomcat";
}
protected Principal getPrincipal[String username) (

Web-

251

return new CustomPrincipal(username) ;


)
class CustomPrincipal implements Principal {
private final String name;
public CustomPrincipal(String name} {
this.name = name;
)
public String getNameO {
return name;
}
public String toString[) (
return getName();

, 9.4,
, $T0MCAT_HOME/conf / t o m c a t - u s e r s .xrnl, . , hasRole t r u e ,
, t o m c a t users.xml. g e t P r i n c i p a l C u s t o m P r i n c i p a l ,
J a v a , s e c u r i t y . P r i n c i p a l .
, ,
Tomcat , ..
BjAR-, $_/server. , CustoraRealm. Java, $TOMCAT_HOME/server.
, , , -
Tomcat 4.0, , ,
, , , .

Web-
Servlet 2.2 , . , , , 9.1,.
. 9.5 , s e c u r i t y c o n s t r a i n t . s e c u r i t y - c o n s t r a i n t , .

9.5. s e c u r i t y - c o n s t r a i n t

web-resource-collection

Web-,

auth-constraint

,
Web-

252

9.
. 9.5

user-data-constraint

"" :
1 ;
? .
web-resource-collection , a a u t h - c o n s t r a i n t ,
. u s e r - d a t a - c o n s t r a i n t .
, web-resource-collection, . 9.6.
9.6. web-resource-collection

web-resource-name

Web-

description

Web-

url-pattern

URL-, Web-

http-method

HTTP-, Web-

"" :
1 ;
? - ;
+ ,
Web- .
URL-,
-. , HTTP- GET, GET.
HTTP- , HTTP-
.
, auth-constraint, . 9.7.

Web-

253

9.7. auth-eonstraint.

description

role-name

"" :
;
+ .
a u t h - c o n s t r a i n t , . .
, u s e r - d a t a - c o n s t r a i n t ,
. 9.8.

9.8. user-data-constraint

description

>

transport-guarantee

NONE, INTEGRAL CONFIDENTIAL

"" :
? ;
1 .
u s e r - d a t a - c o n s t r a i n t t r a n s p o r t - g u a r a n t e e
. t r a n s p o r t - g u a r a n t e e
NONE, INTEGRAL CONFIDENTIAL. NONE
, INTEGRAL ,
. CONFIDENTIAL
, .
, , INTEGRAL
CONFIDENTIAL , SSL. Resin ,
CONFIDENTIAL , S e r v l e t R e q u e s t . i s S e c u r e t r u e .

254

9.


, , , " ".
,
. ,
.
, H t t p S e r v l e t R e q u e s t . g e t U s e r P r i n c i p a l ,
HttpServletRequest.getRemoteUser HttpServletRequest.isUserlnRole.
;\ , API.
, " ".
, ,
.
\, , , JSP- ,
< ! JSP- -->
<%@ t a g l i b = ' / W E B - I N F / t l d s / s e c u r i t y ' p r e f i x = ' s e c u r i t y '

%>

< ! e r r o r P a g e - ; ,
,
,
loginPage >
<security:enforeeLogin loginPage='/login.jsp'
errorPage='/error,jsp' />
< i ,
>
enf orceLogin
. , , Web- . , , loginPage.
, Web-
. e r r o r P a g e . e r r o r P a g e ,
.
, , , . , enf orceLogin.
, ,
enf orceLogin, . 9.5.

255

,
pEnfortcLcgin

:::::::

loginPage rPage

User ugr= getAttnbuEef user")


[user !- mill]
EVAL PAGE

!
i
.



, ^
[ " " null] --"
1
Suing reques!_uji = gelReque 1URIQ t We-CTTJ

I
selAMnbut&("eirors etAll ri but efprot ect
(otward

SKIP PAGE

. 9.5. enforceLogin

enforceLogin , .
. 9.9. loginPage errorPage . protected-page URI .

9.9. enforceLogin

login-page

enforceLogin , .
, ,
,

error-page

, ,

protected-page

, enforceLogin. ,

256

9.

Web- , , . , , Web .
. 9.6 .
sJljggnPigC'ttawiltinmmEifilna
:

Sit

Bi*

Fgwonus

-101 |

iJBl*l

Cibvitai-McnMtliumlEiifew
I pit

dn

Ki

fganut

i*

a>f

* [ '.'>1>)0'1111/<1

_l

Please Login

$}
Name-

|lred

^J <*ao

SCBIHS:

ijj^rrram^ a i d Password aw rw y ^ d
Cbck naa login

Password:

Mole, valid name 19 e l and lid pjssworo is Ham

Bis """*""1

aoon

e ] ;

" ~ Loci

- ^ - - 3 ^ i - ' 1 n p f ,-
4Q9 ' MCfHAI HDW1 t rvvv

14

In*

Fawnfc

Iwt

( and L s i ^ > r ; i v-iSvsH'-irsKj: 8 d

Fit

'"

I * ' *t>

This is a proreatd PSg* Wekrjme rttall

J
.ICIJii

KB
_)

Please Login
Nime:

Nun: valid name 13 w e ! and valid password is

J
JflOon.

::

. 9.6.
, , . .
. 9.7 , .
, .
LoginDB, User. LoginDB User 5, 5.1, 5.1,6. LoginDB , .
9.5,.

2 hand
- web-inf - : . ! classes
beans -
tags

M f 1 vv=u

/ / %} Authentic

- ^ " ^ - (

Ibeans
\ U J tags

EnforceLoginTag

^JSP

4/1

Java

|^XML

[SJ

. 9 . 7 . , ,

9.5,a. /WEB-INF/classes/beans/IioginDB. Java


// User .1,.
public c l a s s LoginDB implements J a v a . i o . S e r i a l i z a b l e {
p r i v a t e Vector u s e r s = new V e c t o r ( ) ;
p r i v a t e User[] d e f a u l t U s e r s (
new U s e r ( " w t e l l " , " w i l l i a m " , "my f i r s t name"),

public LoginDB() (
for tint i=0; i < defaultUsers.length; ++i)
users.add(defaultUsers[i]);
)
public void addUser(String uname, String pwd, String hint} {
users.add(new User(uname, pwd, hint));
// LoginDB,
// 5 . 1 , 6 .

257

258

9.

, . 9.6, ; 9.5,6.
9.5,6. /protectedPage.jsp
<htmlxheadxtitle>A Protected Page</titlex/head>
<%@ taglib uri='security' prefix='security' %>
</body>
<J- errorPage ,
.
>
<security: en force Login J.ogi;aPage=' /login, jsp'
errorPage='/error.j sp'/>
<jsp:useBean id='user' type='beans.User' scope='session'/>
This is a protected page. Welcome <%= user.getDserName f] %>.
</body>
</html>
.
enforceLogin. enf orceLogin 9.5,.
9.5,. /WEB-INF/classes/tags/EnforeeLoginTag. Java
package tags;
import
import
import
import
import

javax.servlet.http.HttpServletRequest;
javax.servlet.http.HttpSession;
javax.servlet. jsp. JspException,javax.servlet.jsp.PageContext;
javax.servlet.jsp.tagext.TagSupport;

public class EnforceLoginTag extends TagSupport {


private String loginPage, errorPage;
public void setLoginPage(String loginPage) {
this.loginPage = loginPage;
}
public void setErrorPage[String errorPage) (
this.errorPage = errorPage;
)
public int doEndTagf) throws JspException {
HttpSession session = pageContext.getSession();
HttpServletRequest req = (HttpServletRequest)pageContext.
getBequest();
String protectedPage = req.getRequestURI();
if(session.getAttributef"user") == null} (
session.setAttribute("login-page",
loginPage);
session.setAttribute("error-page",
errorPage];

259

session.setAttribute("protected-page", protectedPage);
try {
pageContext.forward(loginPage);
return SKIP_PAGE;
}
catch (Exception ex) (
throw new JspException(ex.getMessage());
return EVAL_PAGE;
)
public void released (
loginPage = errorPage = null;

t
,
doEndTag EVAL_PAGE, . , ,
. 9.9, .
JSP-, , 9.5,.
9.5,. /login, jap
<htmlxheadxtitle>Login Page</titlex/head>
<%8 t a g l i b uri='/WEB-INF/tlds/security.tld' p r e f i x = ' s e c u r i t y ' %>
<body>
<font size='4' color=' red' Xsecurity: showErrora/x/font>
<p><font size='5' color='blue'>Please Login</fontxhr>
<form action='<%= response.encodeORL("authenticate") %>'
method^'post' >
<table>
<tr>
<td>Name:</td>
<tdxinput type=' text' name='userName' />
</td>
</trxtr>
<td>Password:</td>
<tdxinput type=' password' name=' password' siee=' 8' ></td>
</tr>
</table>
<br>
<input type='submit' value='login'>
</formX/p>
Mote: valid name is <i>wtell</i> and valid
password is <i>william</i>
</body>
</html>

260

9.

, , * a u t h e n t i c a t e ,
, ; , * .
securityishcwErrors \\ eb- . ( a u t h e n t i c a t e
.!, / 9.5,. /WEB-INF/web.xml
<?xml version=**l. " en ading "
<!DOCTYPE web-app
PUBLIC "-//Sun Microsystems, I n c . / / ! I
"ht :
.
is/web-a]

Web Application 2.2//"


. .

<web-app>
<servlet>
<servlet-name>2iither. ticatie</servlet-Tiame>
<servlet-class>Autheni:icate3ervlet^
et-class>
</servlet>
<s&rvlet-name
I .
/servlet-nai
<url-pal
;uthenticate</url-.
</servlet-mapping>
<ta;

i B-INF/tltts/s
<taglib-location>/WEB-INB

\ 9.5,.
9.5,. /WEB-INF/classea/AuthenticataServlet. Java
import
import
import
import
impoi

javax.sei

javax.servl'-
Java
et.httj
javax.servlc

import
import
Import
import

javoX.KJava.ic.
beans.Loginl
beans

.
pServlet

Lc v o i d

super. . ; :

: onse;

public class An
private
;

Let (

. .

. ptionl

260

9.

, , a u t h e n t i c a t e ,
. , .
s e c u r i t y : showErrors Web- . a u t h e n t i c a t e
web. xral, 9.5,,
9.5,. /WEB-IMF/web.xml
<?xml version="1.0" encoding="ISO-8859-l"?>
<!DOCTYPE web-app
PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.2//EK"
"http://java.sun.com/j2ee/dtds/web-app_2.2.dtd">
<web-app>
<servlet>
<servlet-name>authenticate</servlet-name>
<servlet-class>AuthenticateServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>authenticate</servlet-name>
<url-pattern>/authenticate</url-pattern>
</servlet-mapping>
<taglib>
<taglib-uri>/WEB-lNF/tlds/security.tld</taglib-uri>
<taglib-location>/WEB-INF/tlds/security.tld</taglib-location>
</taglib>
</web-app>
9.5,.
9.5,. /WEB-INF/classes/AuthenticateServlet. Java
import
import
import
import
import
import
import
import
import

javax.servlet.ServletConfig;
javax.seuvlet .ServletException,
javax.servlet.http.HttpServlet;
javax.servlet.http.HttpServletRequest;
javax,servlet.http.HttpServletResponse;
javax.servlet.http.HttpSession;
Java.io.IOException;
beans,LoginDB;
beans,User;

public class AuthenticateServlet extends HttpServlet {


private LoginDB loginDB;
public void init(ServletConfig config) throws ServletException[
super.init(config];
loginDB = new LoginDB();

261

public void service(HttpServletRequest req,


HttpServletResponse res)
throws lOException, ServletException {
HttpSession session req.getSession();
String
uname
- req.getParameter("usetWame");
String
pwci
m req. getParameter ("password");
User
user
= loginDB.getUser[uname, pwd) ;
if(user != null) ( //
String protectedPage = (String)session.
getAttribute("protected-page");
session,removeAttribute("login-page");
session.removeAttribute("error-page");
session.removeAttribute["protected-page");
session.removeAttribute("login-error");
session.setAttribute("user", user);
res.sendRedirect(res.encadeURL(protectedPage));
}
else { //
String loginPage = (String)session.
getAttribute("login-page");
String errorPage = (String)session.
getAttribute("error-page"I;
String forwardTo = errorPage != null ? errorPage :
loginPage;
session.setAttribute("login-error",
"Username and Password are not valid.");
getServletContext().getRequestDispateher(
res.encodeURL(forwardTo)).forward(req, res) ;

I
.
, , ,
. ,
, . 9.8.
,
l o g i n - e r r o r Web- , ,
, . , , . 9.9.
9.5,. / e r r o r . j s p
<htmlxheadxtitle>Login Error</titlex/head>
<%@ t a g l i b uri='/WEB-INF/tlds/security.tld' p r e f i x = ' s e c u r i t y '
<body>
<font s i z e = M ' c o l o r = ' r e d ' >
Login f a i l e d because;<p>

%>

262

9.

<security:showErrors/x/font></p>
f

Click <a href= login.jsp'>here<7a> to retry login.


<7body>
</html>

login

jsp

HttpSerdetgeauesi

Authentic aleSe^e:

Hup Session

LmioSB

Htlp$8rvteiResponse

seivicap

,
:
, 8)

Siring unanne =

Sinng pw = gel Pa

TJ

User user = gslUse/funame, pwd)


. user)

J
String | tectedPage = gelAllnbulefprDl$cled-page")

remrweAllrib
femoyaAttrrhuleClcigin-page"]
removBAlt nbulefeiror-pageT
removeAliritwl e(*Fogrn- error")

seiAtin bin ef user", user)

. &.8. ,

Authe mi rattv

SaMsl

HtmServtetRequest

| Hi Ip Seas ion

LoqinDB

263

ReouastDisoaicher

serviceO
String uname = DelParameteffuserNanne'1)

= getParamelerfpassword')

J
getUser(unama, p
g alAtl ribul e("l ogi n-paga")
getAfi ributefSrror- p a 'J

! login. e r n r - p i 3 0 u;OG!3ian : jll.

setAtlri but e("loji(Ve , *., ")

i
:.
:
; j tip

(orwantQ

. 9.9. , ,

, s e c u r i t y :
showErrors, 9.5,.
9.5,3. /WEB-INF/elasses/tags/ShowErrorsTag. Java
package tags;
import javax.servlet-jsp.JspException;
import javax.servlet.jsp.PageContext;
import javax.servlet.jsp.tagext.TagSupport;
public class ShowErrorsTag extends TagSupport {
public int doStartTagO throws JspException (
String error = (String)pageContext.getSession().
getAttribute("login-error'
ifterror != null) {
try 1
pageContext.getOut().print(error) ;
>
catch(Java.io.IOException ex) {
throw new JspException(ex.getMessage());
return SKIP BODY;

264

9.

showErrors
l o g i n - e r r o r , .

,
. , -.
, ,
Web-, . , , SSL , J2EE-cOBMeCTHMbix .
, , , JSP Java Web-. ; , .
, " ".

...
.


.
-

query.
columnnames.
column.
rows.
release.

.
- .
- .

.
.

"Web-
. JSP, JDBC (Java
Database Connectivity), . , , JSP

. , ,
, .
, SQL JDBC.
JSP, JDBC,
/ API Tutorial and Reference (Addison-Wesley).
JSP- . ,
, . 10.1: Query, , , - . , ; .
1 0 . 1 . ,

query

.
SQL-

rows

268

10.

. 10.1

columns

columntJames

release

, query

prepareStatement

executePreparedStatement

, prepareStatcmenl

transaction

. SQL-

, , ,
. , .


Java-, . 10.1. , , .
10.1.
import
import
import
import

java.sql.Connection;
java.sql.DriverManager;
j ava.sql.Statement;
java.sql.SQLException;

public class CreateDB {


private Connection conn;
private Statement stint;
public
new
)
public
try

s t a t i c void main(String argsfj)


CreateDB();

CreateDB0 {
{
loadJDBCDriver();
conn = getConnection("F:/databases/sunpress'
stmt = conn.createStatement();

createTables(stmt);
populateTables(stmt);
stmt.close() ;
conn.close();
DriverManager.getConnection(
"jdbc:loudscape:;shutdown=true")
catch(SQLException ex} {
ex.printStackTrace(
private void createTables(Statement stmt) (
try {
stmt.execute("CREATE TABLE Customers (" +
"Customer_ID INTEGER, " +
"Name
VARCHAR(25)
"PhoneJSIumber VARCHAR (301 ) ") ;
stint.execute ("CREATE TABLE Orders (" +
"Customer_ID INTEGER, " +
"Order_ID
INTEGER, "
"Amount
FLOAT)");
)
catch(SQLException ex) [
ex.printStackTrace() ;
private void populateTables(Statement stmt) (
try <
stmt.execute("INSERT INTO Customers VALUES
"(1, 'William Dupont',
(652)462-0931'
'(2, 'Kris Cromwell',
(652)462-0932'
' (3, 'Susan Randor',
(652)462-0933'
'{4, 'Jim Wilson',
(652)482-0934(5, 'Lynn Seckinger',
(652)482-0935'
(6, 'Richard Tatersall',
(652)482-0936'),' +
[?, 'Gabriella Sarintia', ' (652)482-0937-),
+
1
1
(8, 'Lisa Hartwig ,
(652}482-09381
)">;
stmt.executeC'INSERT INTO Orders VALUES
'(2, 2, 49.86) , " +
"(IF 1, 29. 99),
'(3, 4, 9 9 . 1 3 ) , " +
"(1, 3, 39. 99),
'(3, 6, 1 1 2 . 2 2 1 , " +
"(1, 5, 24. "?),
"(8 f 7, 29. 99),
'(2, 8, 4 9 . 8 6 ) , " +
" (3, 10, 9 9 . 1 3 ) , " +
"(1. 9, 39. 99),
"(! U , 24.87)," + " ( 3 , 12, 1 1 2 . 2 2 ) , "
"(7, 13, 21.12}," + " ( 1 , 14, 2 7 . 4 9 ) " ) ;
catch(SQLException ex) {
ex.printStackTrace(
:

private void loadJDBCDriver[)


try {

270 10.
Class.forName("COM.cloudscape.core.JDBCDriver");
)
catch(ClassNotFoundException e) {
e.printStackTrace() ;
private Connection getConnection(String dbMame) (
Connection con = null;
try |
con = DriverManager.getConnection(
"jdbc:cloudscape:" + dbName + ";create=true");
)
catchfSQLException sqe) {
System, err .p tint In ("Couldn' t access " + dbName) ;
}
return con;

, . CreateDB JDBC-
. , C o n n e c t i o n . c r e a t e S t a t e m e n t , S t a t e m e n t , JDBC-. ,
.
, 10.1,
JDBC- .
URL ; , URI. . 10.1 Cloudscage, ,
URL .


,
JDBC- URLJDBC. DataSource, , Java Naming and Directory Interface (JNDI), . , , , JNDI .
Context context = new InitialContext();
DataSource dataSource = (DataSource)context.lookup("sunpress_db");
Connection connection = dataSource.getConnection("uname", "pwd");
,
. , JNDI, .
, , JDBC-.

271



. 10.1 JSP-.
{ , ), .
1 Ojutma Eiersk < *
|j ,

&,,

favwlie

< >.

-MiCHKO'tln'

Il

* * ^ | > I . W 'P " l > c i ^ n ! b . B c a I ' t J W i v ' -.[|

zi

Expkttr

Ad**** |fi] ttp ^locatod eOffiydHa

^^

Customers
CUSTOHER 10

NAME

PHONE_NUHBER

William Oupant

(652)421

! Kris Cromwell

[652^492-0932

SussnRandM

(282-09

Jim Wilson

(65232-094

Lynn Seckingsr

(652)432-0535

Richard T a l e n t !

[652>)B2-936

Sabnslla Satin!la

(552)482-0937

; Lisa Hartwig

(652)482-0938

^ ] Dare

T>: Local rtrawl

. 10.1. ,
JSP- , , 10.1 , 10.2,.
10.2,a. /test.jsp
<htmlxhead><title>Database Example</title>
<%@ t a g l i b uri='/WEB-INF/tlds/database.tld'
</head>
<body>
<database:query id='customers'
SELECT * FROM Customers
</database:query>

prefix^'database'%>

scopes'session'>

<font size-' A'>


<a href='showCustomerQuery.jsp'>3how Customers</a><p>
</font>
</body>
</html>

272 10.
JSP-, 10.2,, query. , ()
Customers.
customers,
, .
query id scope. , jsp:useBean,
.
JSP-, 10.2,,
showCustomerQuery. jsp. showCustomerQuery . j sp
10.2,6.
10.2,6. /showCustomerQuery.jap
<htmlXheadxtitle>Customers</title>
<*@ taglib uri='/WEB-INF/tlds/database.tld'
</head>
<body>

prefix='database'%>

<p><font size=' 4' >Custome ITS : </fontx/p>


<table border='2' cellpadding=' 5' >
<database:columnNames query='customers' id-'name'>
<th><!= name %x/th>
</database:columnNames>
<database:rows query='customers'><tr>
<tr>
<database;columns query-'customers' id='value'>
<td><%= value 4x/td>
</database:columns>
</tr>
</database:rows>
</table>

<database:release

query-'customers'/>

</body>
</html>
JSP-, 10.2,6, , : columnNames, rows columns.
query,
.
(rows) (columnNames columns).
columns columnNames . id; 10.2,6 . id 2.

273

JSP- 10.2,6 r e l e a s e .
, query.
. q u e r y . r e l e a s e . .

query
query, ,
10.2,, SQL-,
b o d y c o n t e n t t a g d e p e n d e n t .
<tag>
<name>query</name>
<tagclass>tags.jdbc.QueryTag</tagclass>
<bodycontent>tagdependent</bodycontent>
</tag>
JSP- , tagdependent.
, query, ,
. ,
bodycontent tagdependent, , 2,
query 10.3,.
10.3,a. /WEB-lMF/claeaee/tage/jdbe/QueryTag. Java
package tags.jdbc;
import
import
import
import
import
import
import

Java.sql.Connection;
java.sql.DriverManager;
Java.sql,Statement;
Java.sql.SQLException;
Java.sql,ResultSet;
javax.servlet.jsp.JspException;
javax.servlet.jsp.tagext.BodyTagSupport;

import beans.jdbc.Query;
public class QueryTag extends BodyTagSupport (
private String scope = "page";
private boolean update false, driverLoaded = false;
public void setScope (String scope) {
this.scope = scope;
>
public void setupdate{boolean update) (
this.update - update;

274 10.
public int doAfterBody() throws JspException (
Connection conn = getConnection("f:/databases/sunpress");
try {
String query = bodyContent.getString(};
Statement statement = conn.createStatement[
ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_READ_ONLY);
ResultSet rs = null;
int rows = 0;
if (update) I
rows = statement.executeUpdate(query);
Query.save(new Query(statement, rows),
pageContext, id, scope);
else {
rs = statement.executeQuery(query) ;
Query.save(new Query(statement, rs),
pageContext, id, scope);
catch(SQLException ex) {
throw new JspException(ex,getMessage 0 ) ;
>
return SKIP_BODY;
}
private Connection getConnectionfString dbName)
throws JspException {
Connection con = null;
try (
if('driverLoaded) {
Class.forName("COM.cloudscape.core.JDBCDriver");
driverLoaded = true;
)
con = DriverManager.getConnection(
"jdbc:cloudscape;" + dbName + ";create=false");
}

c a t c h (Exception, ex) {
t h r o w new J s p E x c e p t i o n ( e x . g e t M e s s a g e ( ) ) ;
)
r e t u r n corw

, 10.1, query
JDBC- DriverManager . g e t C o n n e c t i o n , . , ,
. , JDBC 2.0, ,
.
, , JDBC 2.0.

275

id scope query
update, . update false ( ), Statement .executeQuery,
. update true, Statement .executeUpdate, , , , INSERT UPDATE.
Query
. Query
10.3,6.
10.3,6. /WEB-INF/classes/beans/jdbc/Query. Java
package tags.jdbc.beans;
import Java.sql.ResultSet;
import Java.sql.Statement;
import javax.servlet.jsp.PageContext;
import javax.servlet.jsp.JspException;
public class Query {
public static final String QUERY_FREFIX = "query-";
private static final int UNASSIGNED = -1;
private final Statement statement;
private final ResultSet result;
private final int updateCount;
public Query(Statement statement, ResultSet result) (
this.statement = statement;
this.result = result;
this.updateCount = UNASSIGNED;
}
public Query(Statement statement, int updateCount) {
this.statement = statement;
this.updateCount = updateCount;
this.result = null;
)
public Statement getStatement() { return statement; }
public ResultSet getResult()
( return result; }
public int getUpdateCount0
( return updateCount; )
public static void save[Query query, PageContext pageContext,
String name, String scope) {
pageContext.setAttribute(QUERY_PREFIX + name, query,
getConstantForScope(scope));
)
public static ResultSet getResult(PageContext pageContext,
String name) throws JspException {
Query query = findQuery(pageContext, name);
return query.getResult(};
}
public static int getUpdateCount(PageContext pageContext,
String name) throws JspException {

276

10.
Query query findQuery(pageContext, name);
return query.getUpdateCount();

I
public static Query findQuery(PageContext pageContext,
String name) throws JspException {
Query query (Query)pageContext.findAttribute (
QUERY_PREFIX + name);
if(query == null) ( // ?
throw new JspException("Query " + name + " not found." +
" Please retry the query");

return query;
|
private static int getConstantForScope(String scope) {
int constant = PageContext.PAGE_SCOPE;
if(scope.equalsIgnoreCase("page"}}
constant * PageContext.PAGE_SCOFE;
else if(scope.equalslgnoreCase("request"))
constant * PageContext.REQUEST_SCOPE;
else if[scope.equalslgnoreCase("session"))
constant = PageContext.SESSION_SCOPE;
else if(scope.equalslgnoreCase("application"))
constant PageContext.APPLICATION_SCOPE;
return constant;

Query , , ,
, .
Query .
Query , ; ,
, . save QueryTag.doEndTag (. 10,3,), Q u e r y . g e t R e s u l t columns, columnNames rows, , .

columnNames
query, , , . , , columnNames,
.
columnNames :
<database:columnNames query='customers' id='name'>
<%- name %>
</database:columnNames>

2 7 7

columnNames ,
query, , .
i d .

customers.
columnNames columns
.
C o l u i m l t e r a t o r T a g ,
10.4,. , . ColuninI t e r a t o r T a g ,
a b s t r a c t . ,
.
10.4,. /WEB-INF/classes/tags/3dbc/ColuiniiI.teratorTag. Java
package tags.jdbc;
import java.sql.ResultSet;
import Java.sql.ResultSetMetaData;
import Java.sql.SQLException;
import javax.servlet.jsp-JspException;
import javax.servlet.jsp.tagext.BodyTagSupport;
import beans.jdbc.Query;
public abstract class ColumnlteratorTag extends BodyTagSupport (
protected int columnCount, currentColumn;
protected ResultSet rs;
protected ResultSetMetaData rsmd;
protected String query;
public void setQuery(String query) {
this.query query;
}
public int doStaxtTagf) throws JspException {
rs = Query.getResult(pageContext, query);
try {
rsmd = rs.getMetaData();
columnCount = rsmd.getColumnCount();
currentColumn = 1;

1
catch(Exception ex) (
throw new JspException(ex,getMessage());
}
if(columnCount > 0) return EVAL_BODY_TAG;
else
return SKIP_BODY;
}
public int doAfterBody() throws JspException {
if(++currentColumn <= columnCount} {
return EVAL_BODY_TAG;

278 10.
else {
try {
bodyContent.writeOut[getFreviousGut() ) ;
)
catch(Java.io.lOException e) (
throw new JspException(e.getMessage());
}

return SKIP_BODY;

DoStartTag C o l u m n l t e r a t o r T a g , ;
Query. g e t R e s u l t .
qu e r .
, C o l u m n l t e r a t o r T a g . d o S t a r t T a g , , . , .
C o l u m n l t e r a t o r T a g . doAf terBody ,
.
doAf terBody , , SKIP_BODY,
.
doAf terBody 2.
,
C o l u m n l t e r a t o r T a g BodyTag.
C o l u m n l t e r a t o r T a g ,
p r o t e c t e d . columnNames.
10.4,6.
10.4,6. /WEB-INF/classea/ tags/ j dbc/ColumnNames Tag. Java
package tags.jdbc;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import javax.servlet.jsp.JspException;
public class ColumnNamesTag extends ColumnlteratorTag {
public void doInitBodyO throws JspException {
setAttribute();
}
public int doAfterBody(J throws JspException {
int whatNext = super.doAfterBody(};
if(whatNext = EVAL_BODY_TAG)
setAttribute{);

279
return whatNext;
>
private void setflttribute() throws JspException \
try {
pageContext.setAttribute(getldf), rsmd.getColumnNameI
currentColumn]);
}

catch(SQLException ex) {
throw new JspException(ex.getMessage());

ColumnNamesTag ColumnlteratorTag; doInitBody doAfterBody. ,


id. ColumnNamesTag , ( s e t A t t r i b u t e
rsmd, ColumnlteratorTag protected).
columnNames ; , TagExtralnfo. 10.4, columnNames. . 2.
10.4,. /WEB-INF/classea/tags/jdbc/ColumnNaiaesTaglnfo. Java
package tags.jdbc;
import javax.servlet.jsp.tagext.TagData;
import javax.servlet.jsp.tagext.TagExtralnfo;
import javax.servlet.jsp.tagext.Variablelnfo;
public class ColumnNamesTaglnf extends TagExtralnfo {
public Variablelnfo[] getVariablelnfo(TagData data)
return new Variablelnfo[] {
new Variablelnfo(data.getld(),
"Java.lang,String",
true,
Variablelnfo.NESTED)

, 10.4, (
Java.lang. String) id .
true, Variablelnfo, ,.
. , , Variablelnfo.NESTED
.

280

10.

column
column columnNames; . , columns , columnNames .
columnNames, columns,
10.5,, .
10.5,a. /WEB-INF/alassea/tags/jdbc/ColumnsTag. Java
package tags.jdbc;
import Java.sql.ResultSetMetaData;
import j ava.sql.SQLException;
import j avax.servlet.j sp.JspException;
public class ColumnsTag extends ColumnlteratorTag {
public void doInitBody{) throws JspException {
setAttribute ;
)
public int doAfterBody() throws JspException (
int whatNext = super.doAfterBody(} ;
if{whatNext =
setAttribute

EVAL_BODY_TAG)
();

return whatNext;
}
private void setAttribute0 throws JspException {
try (
pageContext.setAttribute(getId(), rs.getstring(
currentColumn));
}
catch (SQLException ex) [
throw new JspException(ex.getMessage());
)
)

ColumnsTag, ,
DO .
columnNames, columns TagExtralnf, . ColumnsTaglnfo, TagExtralnfo, 10.5,6.
10.5,6. ColumnlteratorTaglnfo. Java
package tags.jdbc;
import javax.servlet.jsp.tagext.TagData;

281

import javax.servlet.jsp.tagext.TagExtralnfo;
import javax.servlet.jsp.tagext.VariableInfo;
public class ColimnsTaglnfo extends TagExtralnfo (
public Variablelnf[] getVariablelnfo(TagData data)
return new Variablelnf[] {
new Variablelnfo(data.getld(),
"Java.lang.String",
true,
Variablelnfo.NESTED)

columnNames,
columns id. Java,
lang. String; .

rows
rows ,
.
.
<database:rows query='customers'>
<database:columns query=' customers' id='value'>
<%= value %>
</database:columns>
</database:rows>
rows customers. rows columns, .
rows 10.6.
10.6./WEB-INF/classes/tags/jdbc/RowsTag.Java
package tags.jdbc;
import
import
import
import
import

Java.sql.ResultSet;
Java.sql.Statement;
Java.sql.SQLException;
javax.servlet.jsp.JspException;
j avax.servlet.jsp.tagext.BodyTagSupport;

import beans.jdbc.Query;
public class RowsTag extends BodyTagSupport (
private ResultSet rs;
private boolean keepGoing;
private String query;
public void setQuery[String query) {

282 10.
t h i s . q u e r y = query;
)
public int doStartTag[) throws JspException {
rs = Query.getResult(pageContext, query);
try j
keepGoing = rs.next(); //
}
catch(Exception ex) {
throw new JspException(ex.getMessage ) ;
)
if(keepGoing) return EVAL_BODYJTAG;
else
return SKIP_BODY;

I
public int doAfterBody() throws JspException (
try (
if(rs.isLast()) {
rs.beforeFirst() ;
try {
bodyContent.writeOut(getPreviousOut());
>
catch(Exception e) {
throw new JspException(e.getMessage()};
)
return SKIP_BODY;
}
rs.next[);
}
catch[Java.sql.SQLException ex) {
throw new JspException(ex.getMessage);
}
return EVAL_BODY_TAG;

column Names, 10.4,,


rows d o S t a r t T a g . n e x t ,
(
). R e s u l t S e t . n e x t boolean, , . RowsTag. d o S t a r t T a g R e s u l t S e t . n e x t f a l s e , ,
; d o S t a r t T a g SKIP_BODY. .
RowsTag . doAf terBody . , . R e s u l t S e t . n e x t .
ColumnNames . doAf terBody, RowsTag. doAf terBody
.

233

release
release, 10.7, , query.
10.7./WEB-INF/elas3ea/tag3/jdbc/ReleaseTag.Java
package tags.jdbc;
import
import
import
import

java.sql.Connection;
Java.sql,Statement;
javax.servlet.jsp.JspException;
javax.servlet.jsp.tagext. TagSupport;

import beans.jdbc.Query;
public class ReleaseTag extends TagSupport {
private String query = "null";
public void setQuery(String query) {
this.query = query;

public int doEndTag() throws JspException (


Query q = Query.findQuery(pageContext, query);
try {
Connection con = q.getStatement(}.getConnection()
if(con != null & ! con. isClosedO ) {
con.close ();
catch(java.sql.SQLException sqlex) (
t h r o w new J s p E x c e p t i o n ( s q l e x . g e t M e s s a g e ( ) ) ;

t
pageContext.removeAttribute(query);
return EVAL_PAGE;
\

ReleaseTag. doEndTag Query


.


, , , .
, .

284 10.
Web- . , . PoolMan, , h t t p : / / p o o l m a n . s o u r c e f o r g e . n e t / P o o l M a n / i n d e x . s h t m l .
-, JDBC 2.0
Optional Package API, , JNDI. ( .)
-, . , .
, .
,
.


, ,
, q u e r y r e l e a s e , 10.3, 10.7, , query
, a r e l e a s e . !.
, , ,
query, .

import beans.jdbc.DbConnectionFool;
import beans,util.ConnectionException;
public class QueryTag extends BodyTagSupport {
public int doEndTag() throws JspException {
DbCormectionPool pool = (DbConnectionPool)
pageContext.getServletContext().
getAttribute("db-connection-pool") ;
Connection conn;
try (
conn = (Connection)pool.getResource();
}
catch(ConnectionException cex) {
throw new JspException(cex.getMessage(});

QueryTag g e t R e s o u r c e , .
r e l e a s e r e c y c l e Resource. ReleaseTag
.

285

import beans.jdbc.DbConnectionPool;
public class ReleaseTag extends TagSupport {
public int doEndTagO throws JspException {
Query q = (Query)pageContext.findAttribute(query);
ServletContext app pageContext.getServletContext();
DbConnectionPool pool = (DbConnectionPool)
pageContext.getServletContext
().
getAttribute("db-connection-pool");
try {
pool.recycleResource(q.getStatement().getConnection());
}
catch{Java.sql.SQLException ex) [
throw new JspException(ex.getMessage(}) ;


, query release,
. . 10.8,.
10.8,3. /WEB-INF/classes/SetupServlet.Java
import
import
import
import
import

javax.servlet.ServletConfig;
javax.servlet.ServletContext;
javax.servlet.ServletException;
javax.servlet.http.HttpServlet;
beans.jdbc.DbConnectionPool;

public class SetupServlet extends HttpServlet {


private DbConnectionPool pool;
public void init(ServletConfig config) throws ServletExceptionl
super.init(config) ;
ServletContext app = config.getServletContext();
pool = new DbConnectionPool(
config.getlnitParameter("jdbcDriver"),
config.getInitParameter("jdbcORL") ,
config.getlnitParameter("jdbcUser"},
config.getlnitParameter("jdbcPwd")};
app.setAttribute("db-connection-pool",
)
public void destroy() {
pool.shutdown(};
pool - null;
super.destroy();

pool);

286

10.

, 10.8,, DbConnectionPool. DbConnectionPool : JDBC-, JDBC URL, .


db-connection-pool.
destroy, ,
.
, ,
Web-.
load-on-startup .
.
<web-app>
<servlet>
<servlet-name>setup</ser:vlet-name>
<servlet-class>SetupServlet</servlet-class>
<init-paj:am>
<param-name>jdbcDriver</param-name>
<param-value>C0M.cloudscape,core.JDBCDriver</param-value>
</init-param>
<init-param>
<param-name>jdbcURL</param-name>
<param-value>
jdbc:cloudscape:f:/databases/sunpress;create=false
</param-value>
</init-param>
<init-param>
<param-name>jdbcUser </param-name>
<param-value>roymartin</param-value>
</init-param>
<init-param>
<param-name>jdboPasgword</param-name>
<param-value>royboy</param-value>
</init-param>
<load-on-starti>p/>
</servlet>
</web-app>

,
^- URL.
, ,
.

287


, ,
, JSP- . .


,
. , , , (socket) .
, . . 10.8,6.
10.6,6. ,

package bearis . u t i l ;

import Java.util.Iterator;
import Java.util.Vector;
public abstract class ResourcePool {
protected final Vector availableResources = new Vector (),protected final Vector inUseResources = new Vector();
//
// :
public abstract Object createResource0
throws ResourceException;
public abstract boolean isResourceValid(Object resource);
public abstract void
closeResource(Object resource);
public Object getResource() throws ResourceException (
Object resource = getFirstAvailableResource();
if(resource = null) //
resource = createResource();
inUseResources .adclElement (resource) ;
return resource;
}
public void recycleResource(Object resource) {
inUseResources.removeElement(resource);
availableResources,addElement(resource);
}
public void shutdown!) {
closeResources(availableResources);

288

10.
closeResources(inUseResources);
availableResources.clear() ;
inUseResources.clear(] ;

}
private Object getFirstAvailabLeResource() (
Object resource = null;
if(availableResources.size[) > 0) {
resource = availableResources.firgtElement();
availableResources.removeElementAt(0);
}
if(resource != null && !isResourceValid(resource))
return getFirstAvailableResource();

return resource;
}
private void closeResources(Vector resources)
Iterator it = resources.iterator();
while(it.hasNext >
closeResource(it.next() ) ;
}

ResourcePool : c r e a t e Resource, isResourceValid. closeResource.


, ResourcePool.
ResourcePool , , , .

shutdown. , 10.S,.
getResource recycleResource .
getResource , getFirstAvailableResource. , g e t F i r s t AvailableResource ,
isResourceValid, ResourcePool .
, , -; , .
,
getFirstAvailableResource , .
, getResource ,
.
recycleResource ,
.
, . -, ResourcePool . j ava. u t i l . Vector final. ;
, .

289

-, R e s o u r c e Pool. , , .
-, , , c r e a t e R e s o u r c e g e t R e s o u r c e R e s o u r c e E x c e p t i o n .
E x c e p t i o n , .
package beans,util;
public class ResourceException extends Exception {
public ResourceException(String s) 1
super(s) ;


ResourcePool . , .
1. . .
2. .
, .
.
3.
. , . ,
.
R e s o u r c e P o o l , , 10.8,.
10.8,.

package beans.util;
import java.util.Iterator,import Java.util.Vector;
public abstract class ResourcePool implements Runnable {
protected final Vector availableResources - new Vectorf),
inUseResources = new Vector();
private final int maxResources;
private final boolean waitIfMaxedOut;
private ResourceException error = null; //
// run()
//
II :

290

10.

public abstract Object

createResource ()
throws ResourceException;
public abstract boolean isResourceValid(Object resource);
public abstract void
loseResource (Object resource);
public ResourcePool() (
this(10, //
// 10
false); // ,
//
}
public ResourcePool[int max, boolean waitlfMaxedOut) {
this.maxResources = max;
this.waitlfMaxedOut = waitlfMaxedOut;
}
public Object getResource() throws ResourceException {
return getResource(0);
}
public synchronized Object getResource(long timeout)
throws ResourceException
Object resource = getFirstAvailableResource();
if(resource == null) ( //
if[countResources[) < maxResources) {
waitForAvailableResource();
return getResource(};
}
else { //
if{waitlfMaxedOut) {
try (
wait(timeout) ;
\
catch(InterruptedException ex) {}
return getResource();
)
throw new ResourceException("Maximum number " +
"of resources reached. Try again later.");
}
)
inUseResources.addElement(resource) ;
return resource;
}
public synchronized void recycleResource(Object resource) {
inUseResources.removeElement(resource);
availableResources.addElement(resource);
notifyAllt); //
// .

1
public void shutdown() {
closeResources(availableResources);
closeResources(inUseResources) ;
availableResources.clear() ;
inUseResources.clear() ;
I
public synchronized void run{) 1 //

291

//
Object resource;
error = null;
try f
resource = createResource[); //
)
catch(ResourceException ex) (
error = ex; //
notifyAll0; //
//
return;
)
availableResources.addElement(resource);
notifyAll; // .

private Object getFirstAvailableResource() (


Object resource = null;

if(availableResources.size() > 0) {
resource = availableResources.firstElement();
availableResources.removeElementAt(0);
}
if(resource != null Sfi !isResourceValid(resource))
resource = getFirstAvailableResource();
return resource;

private void waitForAvailableResource[)


throws ResourceException (
Thread thread = new Thread(this);
thread.start(); // : . run()
try {
wait[); // ,
}
//
catch(InterruptedException ex) ( )
if(error != null) // run()
throw error;
// ,
// run()
}
private void closeResources(Vector resources) {
Iterator it = resources.iterator[);
while (it. hasSextO )
closeResource(it.next());

private int countResources() {


return availableResources . size () -f-inUseResources.size [) ;

)- , 10.8,6 10.8,,
getResource, waitForAvailableResource run.
, getResource
; , getResource , .

292

10.

, g e t R e s o u r c e . ResourcePool getResource, - . -
.
w a i t F o r R e s o u r c e , .
ResourcePool (
Runnable), , t h r e a d , s t a r t
run .
run c r e a t e R e s o u r c e , .
c r e a t e R e s o u r c e ResourceException,
run. , run Runnable
throws. run , .
w a i t For A v a i l ableRe s o u r ce.
, . ,
, 10.8,.
10.8,. /WEB-INF/claeses/beans/jdbc/DbCormectionPool. Java
package beans.jdbc;
import j ava.sql.Connection;
import Java.sql.DriverManager;
import j ava.sql.SQLException;
import beans.util.ResourcePool;
import beans.util.ResourceException;
public class DbConnectionPool extends ResourcePool {
private final String driver, url, user, pwd;
private final int initialConnections = 5;
private boolean driverLoaded = false;
public DbConnectionPool(String driver, String url) (
this(driver, url, null, null);
}
public DbConnectionPool[String driver, String url,
String user. String pwd) (
this.driver = driver;
this.url
= url;
this.user
= user;
this.pwd
= pwd;
try (
for [int i=0; i < initialConnections; ++i)
availableResources.addElement(createResource());
)
catch(Exception ex) {}
)
public Object createResource() throws ResourceException {

293

Connection connection = null;


try (
if [! driverLoaded) {
Class.forWame(driver);
driverLoaded = true;
}
if(user == null II pwd == null)
connection = DriverManager.getConnection(url);
else
connection = DriverManager.getConnection(url, user,
pwd) ;
)
catch(Exception ex) {
II ex ClassNotFoundException
// SQLException
throw new ResourceException(ex.getMessage());
}
return connection;

I
public void closeResource(Object connection) {
try {
( [Connection)connection),close();
}
catch(SQLException ex) (
//
)
)
public boolean isResourceValid(Object object) (
Connection connection = (Connection)object;
boolean valid = false;
try {
valid = ! connection.isClosed();
}
catch[SQLException ex) {
valid = false;
}
return valid;

DbConnectionPool
JDBC-, JDBC URL . DbConnectionPool .
DbConnectionPool ,
: createResource, isResourceValid closeResource.
JDBC- , createResource
, DriverManager.
getConnection. , .
DbConnectionPool .closeResource , i s ResourceValid , . isResourceValid , Connection. isClosed.
isClosed , , .

294

10.


SQL- , . , . , , , .
JDBC P r e p a r e d S t a t e m e n t ,
S t a t e m e n t , P r e p a r e d S t a t e m e n t C o n n e c t i o n . p r e p a r e d S t a t e m e n t .
String query = "SELECT * FROM Orders WHERE Amount > ?";
PreparedStatement pstate;
try (
pstate = connection,prepareStatement{query);
)
catch(SQLException sqlEx) {
// SQL-
}
;
.
,
, , ,
, :
p s t a t e . setDoubleU,

100.00);

try (
ResultSet result = pstate.executeQuery[);

1
catch(SQLException sqlEx) (
// SQL-
}
setXXX P r e p a r e d S t a t e m e n t {XXX ). : ( I), . , P r e p a r e d S t a t e m e n t . s e t Double 100.00 ( )
.
:
, .
10.2 JSP-, .
, , , , .

295

* lifemrf ^
t%

bdi'

^ M *

i jJ?J if /

Tom's Candy Store Sales Database


Find orders over this noun fjaaii
hoasaln I

CUSTOHEHJD

OMXRJD

01

9 13

JUJUBE D i

*e*

112 22

19.B6

in

9913

12

...!! (2^0532

; 112 22

. 0.2. ,

JSP-. . 10.2, 10.9,.


10.9,a. /test_preparedstatements. jsp
<html><head><title>Using Prepared Statements</title>
<% taglib uri='/WEB-INF/tlds/database.tld' prefix='database'%>
</head>
<font size='5'>Tom'5 Candy Store Sales Database
</fontxhr>
<database:prepareStatement id='candyQuery' scope='application'>
SELECT * FROM Orders JOIN Customers USING {Custoraer_ID)
WHERE Amount > ?
</database:prepareStatement>
<font

='A'

<form action='showPreparedStatementQuery.jsp'>
Find orders over this amount: $
<input type^'text' name^' amount' size='6'xp>
<input type='submit' value='show sales'></p>
</form>
</font>

JSP-, 10.9,, preparestatement. .


1. .
2. , .
prepareStatement SQL-.

296

10.

Submit
showPreparedStatementQuery. jsp, 10.9,6.
10.9,6. /showPreparedStatementQuery.jsp
<html><head><title>Using Prepared Statements</title>
<fc@ taglib uri='/WEB-INF/tlds/database.tld' prefix='database'%>
</head>
<body>
<% Double amount = new Double[request.getParameter("amount")); %>
<database:executePireparedStatemenfc id='candyQuery' scope='session'
variables='<%= new Object[] (amount) %>'/>
<p><font size='4'>0rders Over $<%= amount %>:</fontx/p>
<table border='2f cellpadding='5'>
<database:columnHames query='candyQuery' id='name'>
<th><%= name %></th>
</database:columnNames>
<database:rows query='candyQuery'><tr>
<tr>
<database:columns query='candyQuery' id='value'>
<td><%= value 4><7td>
</database:columns>
</tr>
</database:rows>
</table>
<database:release query='candyQuery'/>
</body>
</html>

JSP-, 10.9,6, executePreparedStatement.


.
1. .
2. , .
3. , .
JSP-,
10.9,6, columnNames, columns rows ( ).
prepareStatement 10.9,.

10.9,. /KEB-INF/clagses/fcags/jdbe/PrepareStatementTag. Java


package tags.jdbc;
import
import
import
import

java.sql.Connection;
Java.sql.PreparedStatement;
Java.sql.ResuitSet;
Java.sql.SQLException;

import javax.servlet.jsp.JspException;
import javax.servlet.jsp.FageContext;
import javax.servlet.jsp.tagext.BodyTagSupport;
import beans.jdbc.DbConnectionPool;
import beans.util.ResourceException;
public class PrepareStatementTag extends BodyTagSupport {
private String scope = "page";
public void setScope(String scope) {
this.scope = scope;
}
public int cioAfterBody () throws JspException {
DbConnectionPool pool = [DbConnectionPool)
pageContext.getServletContext().
getAttribute("db-connection-pool");
Connection con;
try {
con = (Connection)pool.getResource();
}
catch(ResourceException ex) (
throw new JspException(ex.getMessage{));
}
PreparedStatement ps = prepareStatement(con);
pageContext.setAttribute(id,ps,getConstantForScope(scope));
return SKIP_BODY;
}
private PreparedStatement prepareStatement[Connection con)
throws JspException {
PreparedStatement pstate = null;
try (
pstate = con.prepareStatement(bodyContent.getstring(),
ResultSet.TYFE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_READ_ONLY);
}
catch(SQLException ex) {
throw new JspException(ex.getMessage());
}
return pstate;
}
private int getConstantForScope(String scope) {
int constant = PageContext.PAGE_SCOPE;
if(scope.equalsIgnoreCase("page"))

297

298 10.
constant = PageContext. PAGE__5COPE;
else if(scope.equalsIgnoreCase("request"))
constant = PageContext.REQUEST_SCOPE;
else if(scope.equalsIgnoreCase("session"))
constant = PageContext.SESSION_SCOPE;
else if(scope.equalsIgnoreCase("application"))
constant = PageContext. APPLICATIONS COPE;
return constant;
)
!
prepareStatement. doAfterBody
( ). ,
, , .
, scope . id.
executePreparedStatement, 10.9,.
10.9, . /WEB- IMF/classes /tags/ jdba/Execu tePreparedSta tementTag.Java
package
import
import
import
import
import
import

tags.jdbc;
Java.sql.SQLException;
Java.sql.PreparedStatement;
Java.sql.ResultSet;
javax.servlet.jsp.JspException;
javax.servlet.jsp.tagext.TagSupport;
beans.jdbc.Query;

public class ExecutePreparedStatementTag extends TagSupport


p r i v a t e Object[] variables = n u l l ;
p r i v a t e String scope = "page";

public void setScope(String scope) {


t h i s . s c o p e = scope;
\
public void setVariables(Object[] variables) {
this.variables = variables;
]
public int doEndTag() throws JspException [
PreparedStatement ps = (PreparedStatement)
pageContext.findAttribute(id);
if(ps == null) (
throw new JspException("No prepared statement " + id);
>
try {

299

setVariables(ps, v a r i a b l e s ) ;
ResultSet rs = ps.executeQuery0;
Query query = new Query(ps, r s ) ;
Query.save(query r pageContext, id, scope);

}
catch(SQLException sqlex) {
throw new JspException(sqlex.getMessage[));

return

EVAL_FAGE;

private void setVariables(PreparedStateHient ps,


Object[] variables)
throws SQLException, JspException {
for(int i=0; i < variables.length; ++i) {
Object object = variables[i];
if(object instanceof String) {
ps.setString[i+1, (String)object);
}
if(object instanceof Integer) [
int value = ( (Integer) object) . irttValue (} ;
ps.setInt(i+1, value);
}
if (object instanceof Double) (
double value = ((Double)object).doubleValue();
ps.setDouble(i+1, value);
)
//
II .
// Java.sql.PreparedStatement.
else (
throw new JspException("ExecuteStatementTag:" +
"setVariables(): unkown parameter type"};

executePreparedStatement
PageContext. findA t t r i b u t e , id .
,
Object. objects.
, ,
query, Query , scope . columnNames, columns rows.

300

10.

SQL-, .
,
(roll back). , (commit).
t r a n s a c t i o n ,
. ,
.
<database: transaction>
INSERT INTO C u s t o m e r s VALUES (100,
INSERT INTO C u s t o m e r s VALUES ( 1 0 1 ,
INSERT INTO C u s t o m e r s VALUES (102,
</database:transaction>

' B i l l ' , ' (882)863-4971');


'Roy', '(882)863-4972'};
'Ron', '(882)863-4973'}

t r a n s a c t i o n .
:
<database:transaction file='addCustomers.tx'/>

JSP-, t r a n s a c t i o n ,
10.10,.
10.10,a. /test_transaction.
<html><title>Database Example</title>
<head>
<%@ taglib uri='/WEB-INF/tlds/database.tld' prefix^'database'%>
</head>
<body>
<database:transaction file='addCustomers.tx'/>
<database:query id='addCustomers'>
SELECT * FROM Customers
</database:query>
<table border='2' cellpadding='5'>
<database:columnNames query='addCustomers' id='column_name'>
<th><%= column_name %></th>
</database:columnNames>
<database:rows query='addCustomers'><tr>
<trxdatabase: columns query=' addCustomers' id=' column_value' >
<td><%= column_value % / d
</database:columns></tr>
</database:rows>
</table>
</body>
</html>

301

JSP-, 10.10,, transaction


SQL-, addCustomers.tx. JSP , Customers,
query, columnNames, columns rows.
transaction 10.10,6.
10.10,6. /WEB-INF/classas/tags/jdbc/TransactionTag.Java
package tags.jdbc;
import Java.sql.Connection;
import Java.sql.Statement;
import Java.sql.SQLException;
import Java.io.BufferedReader;
import Java.io.InputStreamReader;
import java.util.StringTokenizer;
import javax.servlet.jsp.JspException;
import j avax.servlet.j sp.tagext.BodyTagSupport;
import beans.util.ResourceException;
import beans.j dbc.DbConnectionPool;
public class TransactionTag extends BodyTagSupport {
private String file;
public void setFile[String file) {
this.file = file;
)
public int doAfterBody() throws JspException {
Connection con getConnection();
String stmts = null;
if (file !<= null) stmts - getStatementsFromFile () ;
else
stmts - bodyContent.getString();
try {
executeTransaction(con, stmts);
}
catch(SQLException ex} {
throw new JspExeeption(ex.getMessage());
}
return SKIP_BODY;
)
private Connection getConnection() throws JspException {
DbConnectionPool pool = (DbConnectionPool)
pageContext.getServletContext().
getAttribute("db-connection-pool");
Connection con;
try {
con (Connection)pool.getResource(};

catch(ResourceException ex) {

302

10.
throw new JspException[ex.getMessage());

return con;
)
private String getStatementsFromFile[) throws JspException {
Buf f eredReader reader - new Buf f eredlReader {
new InputStreamReader[
pageContext.getServletContext()
getResource&sStream(file)));
String stmts = "", line = null;
try {
while((line = reader.readLine()) != null) {
stmts += line;
catch(Java.io.IOException ex) {
throw new JspException(ex.getMessage[));
)
return stmts;
}
private void executeTransaction(Connection con, String stmts)
throws SQLException {
boolean wasAutoCommit = con.getAutoCommit();
try (
StringTokenizer tok = new StringTokenizer(stmts, " ; " ) ;
con.setAutoCommit(false);
while(tok.hasMoreElements[)) (
Statement stmt = con.createStatement();
String query = (String) tok.nextElement 0;
stmt.execute(query);
stmt.close();
)
catch [Exception ex) {
con.rollback();
)
finally {
con.commit() ;
con.setAutoCommit(wasAutoCommit);

TransacionTag . doAf terBody .


f i l e , , ,
, f i l e , .
executeTransacion .
1. autocommit .
2. ^ false.

303

3. .
4. , .
5. , .
6. autocommit .


.
, , rows, . , , . bean,
. , rows, . 10.3.
|
4* *-*-

a^>vt Iwii

L-IJI.J.'.I..I'.HHJ
9 * 4* *#

>,

ift= ' ft^etL'jfo-KnlUi aoKJ

ADDRESS

WHiam Duponl (5!)482-01


Kfi; Cromwell

.3

"ll

Customer:

Customers.
CUSTOMERJD

_^ .

| John Smith

CUSTOMER..ID
-

(652)482-0932
(652H82-OB33

.6

NAME

ADDRESS

Jim Wtleon

(852)482-0634

Lynn Seckinger

(652)482-0935

Richard Tatersan (6522-0936

<>
in

. ..

.
, . 10.3, JSP, 10.11,.

10.11,,/test

scroll,

<html><title>Database Example</title>
<head>
<%@ taglib uri='/WEB-INF/tlds/database.tld' prefix-'database'%>
</head>
<body>
<database:query id='customers' scope='session'>
SELECT * FROM Customers
</database:query>

304

10.

<font size='4'>
< href=' scrollQuery. jsp' >Show Customers</aXp>
</font>
</body>
</html>
JSP- query . scrollQuery. jsp,
10.11,6.
10.11,6. /scrollQuery.jep
<htmlxtitle>Customers</title>
<head>
<*@ taglib uri='/WEB-INF/tlds/database.tld' prefix='database'4>
</head>
<body>
<jsp:useBean id=f scroller' class='beans.ScrollBean'
scope='session' >
<jsp:setProperty name='scroller' property='position' value='1'/>
<jsp:setProperty name='scroller' property='pageSize' value='3'/>
</j sp:useBean>
<% scroller.scrolHrequest.getParameter ("scroll") ); %>
<pxfont size=M' >Customers:</fontx/p>
<table border-'2' cellpadding='5'>
<database:columnNames query='customers' id='name'>
<th><%= name %></th>
</database:columnNames>
<database:rows query='customers'
startRow='<%= scroller.getPosition() %>'
endRow='<%= scroller.getEndPositionO *>'>
<tr>
<database:columns query='customers' id='value'>
<tdx%= value %></td>
</database:columns>
</tr>
</database:rows>
</table>
<database:release query='customers'/>
<a href='scrollQuery.jsp?scroll=back'>slt;</a>
<a href='scrollQuery.jsp?scroll-fwd'>&gt;</a>
</body>
</html>

305

, 10.11,6, rows, , .
ScrollBean, .
ScrollBean s c r o l l , "f wd"
"back". s c r o l l ,
. ScrollBean 10.11, .
10.11,. /WEB-INF/classes/beans/util/ScrollBean . Java
package b e a n s . u t i l ;
public class ScrollBean {
private i n t position, pageSize;
public ScrollBean[) {
t h i s d , 4);
}
public ScrollBean(int start, int pageSize) {
this.position = start;
this.pageSize pageSize;
)
public synchronized int scroll(String direction) (
if("fwd".equalsIgnoreCase(direction)) (
position += pageSize + If
)
else if("back".equalsIgnoreCase(direction)) (
position -= pageSize;
position = (position < 1} ? 1 : position;
)
else
position = 1;
return position;
}
public synchronized void setPosition(int position) (
this.position = position;

public synchronized void setPageSize(int pageSize)


this.pageSize = pageSize;
}
public synchronized int getPosition () {
return position;
)
public synchronized int getEndPositionO {
return position + pageSize;

rows 10.11,.

306

10.

10.11,. /WEB-INF/classes/taga/jdbc/RowsTag. Java


package tags.jdbc;
import
import
import
import
import
import

java.sql.ResultSet;
java.sql.Statement;
Java.sql.SQLException;
javax.servlet.jsp.JspException;
javax.servlet.jsp.tagext.BodyTagSupport;
tags.jdbc.beans.Query;

public class RowsTag extends BodyTagSupport {


private static int UNASSIGNED=-1;
private
private
private
private

ResultSet rs;
boolean keepGoing;
String query;
int startRow = UNASSIGNED, endRow = UNASSIGNED;

public void setQuery(String query) {


this.query = query;
)
public void setStartRow(int startRow) {
this.startRow = startRow;
}
public void setEndRow(int endRow) {
this.endRow = endRow;
}
public int doStartTagO throws JspException {
rs = Query.getResult(pageContext, query);
try {
if(startRow = UNASSIGNED) {
keepGoing = rs.next(); //
}
else {
iffstartRow < 1)
startRow = 1;
keepGoing = rs.absolute(startRow);
catch(Exception ex) (
throw new JspException(ex.getMessage());
)
if(keepGoing) return EVAL_BODYJTAG;
else
return SKIP_BODY;
}
public int doAfterBody() throws JspException 1
try {
if(endRow == UNASSIGNED) {
if(rs.isLast {)) (
rs.beforeFirst ();
writeBodyContent();
return SKIP BODY;

307

else (
if(rs.getRow() == endRow || rs.isLast()) {
rs.beforeFirst();
writeBodyContent();
return SKIP_BODY;
rs.riext () ;
|
catch(java.sql.SQLException ex) {
throw new JspException(ex.getMessage() ) ;
}
return EVAL_BODY_TAG;
}
public void writeBodyContent() throws JspException
try i
bodyContent.writeOut(pageContext.getOut0 ) ;
}
catch(Exception e) {
throw new JspException(e.getMessage[));

rows
. .

.
1. .
2. , .
3. , .
,
, ,
JDBC.
. , . , , , , .

XML

...

L-.

bean XML-.

XML-.

XML-.

SimpleAPIforXML(SAX).
SAX-
.
Document Object Model (DOM).
DOM-.

XML-.

XSLT JSP.

HTML- XSLT-
.

XSLT JSP-
.

Xpath.

ava XML
XXI . , Java XML,
JSP XSLT.
.
XML- .
XML- .

XML- XML.

XML- , HTML
WML.

XML- JSP , JSP , XML-. ( JSP-, , ,


. , ,
, 4.) JSP bean XML-.
JSP XML; ,
. 11.1 Model 2, XML- , . XSLT
XML : HTML, JSP ""
XML, WML (Wireless Metalanguage).
XML-
SAX (Simple API for XML) DOM (Document Object Model).
API .

310 11. XML

Web-

XML

WML

JSP

~
HTML

. 11.1. M o d e l 2 XML XSLT

XML-, XML- ; ,
WML- HTML-, XSLT , . XSLT-n ,
, .
, ,
:
Java Development Kit (JDK) 1.3

Tomcat 3.2.1 Final

Apache Xeices-J a va version 1.2.2

Apache Xalan-Java version 1.2.2

JDK , h t t p : //www. Java, aun.com, a


Tomcat h t t p : / / j a k a r t a . a p a c h e . o r g / t o m c a t / i n d e x . html,
Xerces Xalan XML- XSLT-,
h t t p : //
xml.apache.org/xalan/index.html.

XML-

311

XML-
11.1 JSP-, . JSP- XML-.
11.1. /date.jsp
<%@ page contentType='text/xml' %>
version="1.0" encoding="ISO-8859-l"?>
<document>
<date>
<%= new J a v a , u t i l . D a t e () %>
</date>
</document>
JSP-, XML-, , 11.1, t e x t / x m l .
JSP- HTML, , -,
XML-. 11.1.
Web-, , 11.1,
. 11.2.
Web- . . 11.2, ,
XML-.
|
*

Favorite

Took tfslp

?xml version-" 1.0" encoding-1150-8S59-1" ?>

d'.-::i.inler-it>

<ti3tt>Thu Dec 14 10:51:59 MST 2000</dats>

J
' ; 4 j Local inhanrt

. 11.2. XML- JSP

XML-
bean
, ,
XML-, JSP- , .
JSP-,
bean. . 11.3.

312 1 1 . XML

Ioo!s

Jjflt

Addnstjg] htlp MrKjItosI Wffil/vml/rwenlCTy.jip

:.

Oml version-" 1.0" enU)ding-"(SCi-B359-r J>

>Anttque breo
<ci*i.;iiiJti^iF>frim the early 170Q's</ci^tcnudari>
< t* i i e > 12 38.99 < >
name > Gum by nit -/??
<;?=;!>11 ettion naurBSi/descrian>
<pries>2.99 -/*?

. excellent s

<d9#cripl ^r->One of the first gds -engine


<!>4995</11:>

. 11.3. XML- JSP


JavaBeans
JSP- 11.2,.
1.2,a. /inventory.jap
<%@ page contentType='text/xml' %>
<%@ page import='beana.Inventory' %>
<%@ page import='beans.Item' %>
<jgp:useBean id='inventory' class='beans.Inventory' scope='page'/>
<% java.util.Iterator it = inventory.getItems();
Item item - null;
version="1.0" encoding-"ISO-8B59-l"?>
<inventory>
<% while(it.hasNextO) { %>
<% item = (Item)it.next(); l>
<item>
<name><%= item.getName() %></name>
<description><%= item.getDescription() %></description>
<price><%= item.getPrice() %></price>
</item>
<% ) %>
</inventory>

T, 11.2,, >
Item, bean i t e r a t e . -

XML- 313
, JSP- XML- .
XML- .
I n v e n t o r y Item
, .
11.2,6. /WEB-INF/classes/beans/Inventory. Java
package beans;
import j a v a . u t i l . I t e r a t o r ;
import java.util.Vector;
public class Inventory implements Java.io.Serializable {
private Vector items = new Vector();
public Inventory() {
items .addElement (new itemfAntique broach",
"from the early 1700's",
(float)1238.99)) ;
//

public I t e r a t o r getltems()
return items.iterator()

11.2,. /WSS-INF/classes/beans/Item. Java


package beans;
public class Item implements Java,io.Serializable (
private String description, name;
private float price;
public ItemfString name, String description, float price) {
this.description = description;
this.name - name;
this.price - price;
}
public String getName()
( return name; }
public float getPriceO
{ return price; }
public String getDescription{) { return description; }

, XML- JSP- -. .
XML- - . , XML-, JSP-,
.

314 11. XML

XML-
text/xral
jSP-, XML-, text/xml, . ,
JSP-. 11,1 . 11.2, , , .
JSP- XML-, , XML, .
:
<xslt:apply xsl='date.xsl'>
<%@ include file='genXML.jsp'
</xslt:apply>

%>

xslt:apply , XSLT XML-. XML-


genXML. jsp, text/xml,
, , HTML.

bean, XML-
XML- JSP . , 11.2,, JSP- , ,
JSP- , , ,
Web-.
XML- JSP bean, XML, ,
XML-, Inventory Item, 11.3, 11.3,6.
XML- JSP, 11.2,,
Inventory Item .
11.3,a. /WEB-INF/classea/beans/Inventory.Java
//
// 11.2,6.
public class Inventory implements java.io.Serializable (
public void prirttXml (PrintStream s)
s.println["<inventory>") ;
Iterator it = getltemsf);
while(it.hasNext[)) {
Item item = [Item]it.next();

XML-

315

item.printXml[s, 1) ;
s.println("</inventory>") ;
J

11.3,6. /WEB-INF/classes/beans/Item, Java


//
// 11.2,.
public class Item implements Java.io.Serializable {
public void printXml[PrintStream s) {
printXml(s, 2) ;
}
public void printXml(PrintStream s, int indent) I
dolndent(s,indent);
s.printIn("<item>");

doIndent(s,indent, 2)
dolndent(s,indent, 3)
dolndent(s,indent, 2)

s.println("<name>");
s.println(getName
);
s.println("</name>");

dolndent(s,indent, 2)
dolndent(s,indent, 3)
dolndent(s,indent, 2)

s.printIn("<description>");
s.printIn(getDescription()) ,
s.printIn("</description^'}

dolndent(s,indent, 2)
dolndent(s,indent, 3)
dolndent(s,indent, 2)

s.println("<price>");
s.printIn(getPrice()) ;
s.printIn("</price>");

dolndent(s,indent);

s.printIn("</item>");

private void dolndent(PrintStream s, int indent, int cnt) {


fortint i=0; i < cnt;
dolndent(s,indent)j
private void dolndent(PrintStream s, int indent) {
fortint i=0; i < indent;
s.print{" " ) ;

I
}

bean XML-
Java XML ,
XML- bean,
. Adelard Sun, bean -

316 11. XML


XML. Adelard XML Productivity Kit
UR.L:
http://Java.sun.cora/xml/

http://ww.alphaworks.ibm.com/tech/xmlproductivity
XML- JSP .
, . bean,
JSP-, XML- . , , XML-.
JSP-, XML-.

XML-
, JSP- XML- , , , .
,
.
.
Servlet 2.3 , , . 11.4, JSP-,
XML-, , 11.2,.
.
11.4,a. / t e s t . j s p
<%@ taglib uri='/WEB-INF/tlds/util.tld' prefix='util' %>
<jsp:useBean id='inventory' class='beans.Inventory' scope='page'/>
<%

Java.util.Iterator it = inventory.getltems();
beans.Item item - null;

<util:streantToFile
file='f:/books/jsp/sre/xral/inventory.xml'>
version="1.0" encoding="ISO-8859-l"?>
<inventory>
<l while(it.hasNext()) { %>
<% item = (beans.Item)it.next 0; %>
<itejn>
<name><%= item.getName(j %></name>
<description>
<%= item.getDescriptionO %>
</description>
/"
<price><%- item.getPriceO %></price>
</item>

XML- 317

</inventory>
:streamToFile>
u t i l : s t r e a m T o F i l e 11.4,6.

11.4,6. WEB-INF/claeses/tags/util/StreamToFileTag. Java


package tags.util;
Import java.io.File;
import java.io.FileWriter;
import j avax.servlet.j sp.JspException;
import javax.servlet.jsp.tagext.BodyTagSupport;
public class StreamToFileTag extends BodyTagSupport (
private String filename;
public void setFile(String filename) {
this.filename = filename;
)
public int doAfterBody[) throws JspException (
try {
FileWriter writer new FileWriter(new File(filename)
writer.write(bodyContent.getString[).trim());
writer.closet)t
}
catch(java.io.IOException e) {
throw new JspException[e.getMessage());
>
return SKIP_BODY;

,
, , . , , 11.4,6,
, .
XML-, XSLT-, .

XML-
, , XML-,
"". , XML, XML-.
API: SAX DOM,

318

11.XML

Simple API for XML (SAX)


SAX de facto XML-. SAX XML-DEV; SAX,
SAX1, 1998 .
SAX1 SAX2, 2000 . SAX2 SAX1, .
SAX, , SAX2. SAX h t t p : //www .megginson. com/SAX.
SAX , Document Object
Model (DOM), , XML-.
SAX ;
, (handler),
, . ,
SAX, , 7.
SAX2 ,
:

org.xml.sax.ContentHandler
org.xml.sax.DTDHandler
org.xml.sax.ErrorHandler
SAX .

1. .
2.

XML {org. xml. s a x . XMLReader).

3. , , ,
.
4.

(org. xml . s a x . I n p u t Sour se).

5. XMLReader . p a r s e ; , 4.
XML ; , E r r o r H a n d l e r warning, , SAX .
SAX- , 19 .
D e f a u l t H a n d l e r , o r g . x m l .
s a x . h e l p e r s . ; .
, . 11.5, bean, SAX- Apache Xerces.

1 SAX2 Entity-Reference,
in-liatt-vrimpitutiemm. - . .

XML-

319

11.5,a. /WEB-INF/classBs/beans/annl/sax/SAXParserBean. Java


package beans.xml.sax;
import
import
import
import
import
import
import
import
import
import

java.io.FileReader;
org.xml.sax.Attributes;
java.io.IOException;
java.util.Vector;
org.xml.sax.Attributes;
org.xml.sax.InputSource;
org.xml.sax.SAXException;
org.xml.sax.XMLReader;
org.xml.sax.helpers.DefaultHandler;
org.apache.xerces.parsers.SAXParser;

public class SAXParserBean extends DefaultHandler {


private Vector vector = new Vector[);
private SAXElement currentElement = null;
private String elementText;
public Vector parse(String filename) throws SAXException,
IOException {
XMLReader xmlReader = new SAXParser();
FileReader fileReader = new FileReader{filename);
xmlReader.setContentHandler(this);
jcmlReader.parse(new InputSource(fileReader)};
return vector;
!
public void startElement[String uri, String localName,
String qName, Attributes attrs) {
cu^rentElement = new SAXElement(uri,localName,qName,attrs);
vector.addElement(currentElement);
elementText = new StringO;
}
public void characters(char[] chars, int start, int length) {
if(currentElement != null & elementText != null) {
String value = new String[chars, start, length);
elementText += value;

1
}
public void endElement (String uri, String localName,
String qName) {
if(currentElement != null && elementText != null)
currentElement.setValue(elementText.trim
0);
currentElement = null;

SAXParserBean DefaultKandler
SAX-,
.

320 11. XML


SAX, Xerces, SAXParserBean,
XMLReader, .
, , 11.5,,
.
SAXParserBean startElement, endElement
characters, Content Handler. 11.5,
,
XML-.
SAXElement, 11,5,6.
11.5,6. /WEB-INF/ classes /bean s/xml/sax/SAXElement. Java
package beans.xml.sax;
import org.xml.sax.Attributes;
public class SAXElement (
String namespace, localName, qualifiedName, value=null;
Attributes attributes;
public SAXElement(String namespace, String localName,
String qualifiedName, Attributes attributes){
this.namespace
= namespace;
this.localName
= localName;
this.qualifiedName - qualifiedName;
this.attributes
= attributes;
}
public void setValuefString value) (
this.value = value;
)
public String getNamespace()
{ return namespace; }
public String getLocalName()
( return localName; )
public String getQualifiedName() ( return qualifiedName; I
public String getValueO
( return value; }
public Attributes getAttributes() ( return attributes; }

SAXElement XML-, . SAXElement ContentHandler. startElement


(. 11.5,).
. 11.4 JSP-, ,
11.5,, XML-, .

XML-

321

'SAX E m * *
fill

ysr

xin

Book Inventory:
T l d i : Pomls Unknown
prict: .96
Title; A New Kind of Science
pries: 110.75
TWi: 111 Sciential in Ih Crib
P'ict. (9.95
Tllle. Ttrs Ajiceleisling IJniieise
phce: (19 55
Tle: Saundan Pharmsceuncjl Wind Book
price: S i : 25

i*; Dn

-^

-Loral Him*

. 11.4. SAX
XML-, ,
II,5,.
11.5,. /booklnventory.xml
version="1.0" encoding="I30-e859-l"?>
<inventory>
<book>
<ISBN>0393040009</ISBH>
<title>Points Unknown</title>
<price>$23.96</price>
</book>
<book>
<ISBN>1579550086</ISBN>
<title>A New Kind of Science</title>
<price>$10.75</price>
</book>
<book>
<ISBN>0416399760</ISBN>
<title>The Accelerating Universe</title>
<price>$19,55</price>
</book>
</inventory>

322 11. XML


JSP-, . 11.4, 11.5,.
11.5,. /test^sax. jsp
<htmlxheadxtitle>SAX Example</title>
page import='Java, lit il.Collection' %>
page import='Java.util.Iterator' %>
<@ page import='beans.xml.sax.SAXParserBean' %>
<%@ page import='beans.xml-sax.SAXElement' %>
</head>
<body>
<jsp:useBean id='parser' class='beans.xml.sax.SAXParserBean'
scope='page'/>
<% Collection elements = parser.parse(
"f:/books/jsp/src/xml/booklnventory.xml");
Iterator it = elements.iterator();
%>
<font size='5'>Book Inventory:</font><p>
<% while(it.hasNext() ) (
SAXElement element = (SAXElement)it.next();
String tagName = element.getLocalName{);
String showThis = null;
if(tagName.equals("title")) f
showThis = "<b>Title:</b> " +
element.getValue() + "<br/>";

else if(tagName.equals("price")) {
showThis = "price: " + element.getValue() + "<p>";
<%=> showThis =- null ? "" : showThis %>

</body>
</html>
JSP-flOK)pMCHT, ,
(SAXElement}, SAXParserBean. SAXElement .getLocalName,
SAXElement. getValue.

XML-

323

SAX-

, , 11.6, Java- ^-. , 11.6, , JSP. 11.5,.


11.6. /test_sax.jsp , ,
11.5,
<html><head><title>SAX Example</title>
<%@ taglib uri='/WEB-INF/tlds/sax.tld' prefix^'sax' %>
<l@ page import='beans. xml.sax.SAXElement' %>
</head>
<body>
<font size=' 5' >Book Inventory: </fontxp>
<:iterateElements id='element'
xmlFile='f:/books/jsp/sre/xml/booklnventory.xml'>
<sax:ifElementNameEquals element='<%= element %>'
names='title'>
<b>Title:</b> <%= element.getValue() %><br/>
</sax:ifElementNameEquals>
<sax:ifElementNameEquals element^'<%= element %>'
names=fprice'>
price: <%= element.getValue() %><p>
</sax:ifElementNameEquals>
</sax:iterateElements></p>
</body>
</html>

iterateEleraents SAXParserBean,
11.5,, XML- , a ifElementNameEquals .
iterateElements ; id .
, XML-, inventory.xml, element.
, iterateEleraents, ifElementNameEquals. , , names.
. 11.5 ,
(TLD Tag Library Descriptor).

324 1 1 . XML
-lOlx
'.flip

Edit

IOOIJ

ffl hlip: //loeelhotl: BlMO/mlrtBLMi(.lld. itp

Sun Microsystems Press Database Tag Library


You can execute database queries and iterate over the results witri the tags in this library. This
library also includes tags for prepared statements and transactions.
Tag Class

TsgNama
transaction

19 g s. jtJbc. TransactionTag

p re p e 3l a [ e m e nt t a g s.j d be PrepareStatementTag

Body Content

Attributes

tagdependent

file

tagdependent

scope id

xscutePrepare d 5t at e ment 11 ags.jdbc. EzxecutePreparedSt 3t ntTa gNone

id scope variables

query

tagdependent

id scope update

JSP

query startRow endRow

JSP

query id

sTag

JSP

query id

tags. jdbc. RalaaseTa g

JSP

query

lags.jdbc. OueryTag

raws

tags.jdbc.
1

columns
release

umnNames
lags

Rows

jtags.jdbc.
jdbc.

Tag

ColumnNamasTag

Column

;*fc Local i t t m l

Puc. 11.5. TLD- JSP


,7, TLD-, JSP-, . 11.5.
11.7,a. database. t l d
version="1.0" encoding-"!SO-a859-l" ?>
<!DOCTYPE t a g l i b PUBLIC
"-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.1//EN"
"http://Java.sun.com/j 2ee/dtds/web-j sptaglibrary_l_l.dtd">
<taglib>
<tlibversion>l.0</tlibversion>
<jspversion>l.l</jspversion>
<shortnarae>
Sun Microsystems Press Database Tag Library
</shortname>
<info>
You can execute database queries and iterate over the
results with the tags in this library. This library also
includes tags for prepared statements and transactions.
</info>
<tag>
<name>transaction</name>
<tagclass>tags.jdbc.TransactionTag</tagclass>
<bodycontent>tagdependent</bodycontent>
<attribute>
<name>file</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>

XML-
</attribute>
</tag>
... ...
</taglib>
}5-, . 11.5, 11.7,6.
11.7,6. /test
<htmlXheadxtitle>SAX Example</title>
<%@ taglib uri='/WEB-INF/tlds/sax.tld' prefix='sax'%>
<%@ page import='tags. util.IteratorTag' %>
<4 boolean inAttributes = false, bodyContentSpecified = false;
String attributeData = null; %>
</head>
<body>
<%-- --%>
<sax:iterateElements id='element'
xmlFile='f:/books/jsp/src/xmi/database.tld'>
<sax:ifElementNameEquals element^'<%=element%>'
names='shortname'>
<font size='5'x%= element.getValue () %></fontxp>
</sax:ifElementNameEquals>
<sax:ifElementNameEquals element='<%=element%>'
names='info'>
<p><font size='4'X%= element.getValueO %></fontx/p>
</sax:ifElementHameEquals>
</sax:iterateElements>
< % ,
name, tagclass, bodycontent attribute % >
<table border'1' cellpadding='2'>
<th>TagName</th>
<th>Tag Class</th>
<th>Body Content</th>
<th>Attributes</th>
<sax:iterateElements id='element'
xmlFile='f:/books/jsp/src/xml/database.tld'>
<% if( ! inAttributes) { %>
<sax:ifElementNameEquals element^'<%=element%>'
names='name'>
<trxtd><%= element.getValueO %></td>
</sax:ifElementNameEquals>
<saxrifElementKameEquals element-'<%=element%>'
names='tagclass'>
<td><%= element.getValueO %x/td>
</sax:i fElementNameEquals>

325

326

11. XML

<sax:ifElementNameEquals element='<%=element%>'
names='bodycontent'>
<td><%= element.getValue() %></td>
<% bodyContentSpecified = true; %>
</sax:ifElementNameEquals>
<sax:ifElementNameEquals element^'<%=element%>'
names='attribute'>
<% inAttributes = true;
attributeData = new StringO;
if[ I bodyContentSpecified) [ !>
<td>JSP</td>
<% }
bodyContentSpecified = false; %>
</sax:ifElementNameEquals>
<% }
else { %>
<sax:ifElementNameEquals element^'<%=element%>'
names='name'>
<% attributeData += element.getValue[) + " "; %>
</sax:ifElementNameEquals>
<sax:ifElemenfNameNotEquals element-'<%=element%>'
names='attribute name required rtexprvalue'>
<td><%= attributeData %></td>
<% inAttributes = false; %>
</sax:ifElementNameNotEquals>
<%
} %>
</sax:iterateElements>
<td><%- attributeData %></td></tr>
</table></p>
</body>
</html>
JSP-, 11.7,6,
d a t a b a s e . t l d ; shortname i n f o ,
HTML-. XML- ( d a t a b a s e . t l d ) .
i t e r a t e E l e m e n t s s w i t c h ,
; . , shortname , 5.
11.7, i t e r a t e E l e m e n t s .
11.7,. /WEB-INF/classes/tags/xml/sax/SAXParserTag. Java
package tags.Kinl. sax;
import Java.util.Collection;
import Java.util.Vector;

XML-
import
import
import
import
import

327

javax.servlet.jsp.JspException;
javax.servlet.jsp.PageContext;
beans.xml.sax.SAXParserBean;
tags.util.IteratorTag;
rg.xml.sax.SAXException;

public class SAXParserTag extends IteratorTag (


private String xmlFile;
public void setXmlFile(String xmlFile) {
this.xmlFile = xmlFile;
}
public int doStartTag() throws JspException {
setCollection(getCollection{));
return super.doStartTag();
}
public void release{) {
xmlFile = null;
)
private Collection getCollection[) throws JspException (
Collection collection = (Collection)
pageContext.getAttribute(
xmlFile,
PageContext.FAGE_SCOFE);
if {collection == null) {
try {
SAXParserBean parserBean = new SAXParserBean();
collection = parserBean.parse(xmlFile);
setCollection(collection);
pageContext.setAttribute(xmlFile,
collection,
PageContext.PAGE_SCOPE);
)
catch(java.io.IOException ex) {
throw new JspException("10 Exception: " +
ex.toString());
catchfSAXException ex) {
throw new JspException("SAX Exception" +
ex.toString()};

}
return collection;

SRXParserTag, 11.7,,
IteratorTag, 2. i t e r a t e Elements , .
SAXParserTag , SAX-
{ ). parse ,
XML-.
SAXParserTag. doStartTag; .

328 11. XML


, SAXParserTag XML-
.
.
iterateElements, .
TagExtraInfo, 2. SAXParserTaglnfo
11.7,.
11.7,. /WEB-INF/classes/tage/aaru/saji/SAXParserTagXnf . Java
package tags.xml.sax;
Import
import
import
import

javax.servlet.jsp.tagext.TagData;
javax.servlet.jsp.tagext.TagExtraInfo;
javax.servlet.jsp.tagext.VariableInfo;
beans.xml.sax.SAXElement;

public class SAXParserTaglnfo extends TagExtralnfo {


public Variablelnfol] getVariableInfo(TagData data} (
return new Variablelnf[] {
new Variablelnfo(data.getld(),
"beans.xml.sax.SAXElement",
true, Variablelnfo.NESTED),
new Variablelnfo("next", //
"beans.xml.sax.SAXElement", II
true, //
Variablelnf.NESTED)

SAXParserTaglnfo ,
. id iterateElements.
sax: ifEleraentNameEquals

11.7
11,7,. /WEB-INF/classes/tags/xml/aax/
IfElementNameEqualsTag.Java
package tags.xml.sax;
import
import
import
import
import

java.util.StringTokenizer;
java.util.NoSuchElementException;
javax.servlet.jsp.JspException;
javax.servlet.jsp.tagext.TagSupport;
beans.xml.sax.SAXElement;

public class IfElementNameEqualsTag extends TagSupport {


private SAXElement element = null;
private String names = null;

XML-

329

public void setElement(SAXElement element) (


this.element = element;
}
public void setNames(String names) [
this.names = names;
}
public int doStartTag() throws JspException {
StringTokenizer tok new StringTokenizer(names);
String nextName - null,
elementName = element.getLocalName();
boolean nameFound = false;
try 1
while(!nameFound)
nameFound = elementName.equals(tok.nextToken
)
catch(NoSuchElementException ex) {
//
}
return nameFound ? EVAL_BODY_INCLUDE : SKIP_BODY;
)
public void released {
names - null;
element = null;

IfElementNameEqualsTag : SAXElement , , . , .
sax: ifElementNaraeNotEquals .7,.
11.7,. /WEB-INF/classes/tags/. . ./
IfElementNameNotEqualsTag.Java
package tags.xml.sax;
import
import
import
import
import

Java.util.StringTokenizer;
Java.util.NoSuchElementException;
javax.servlet.jsp.JspException;
javax.servlet.jsp.tagext.TagSupport;
beans.xml.sax.SAXElement;

public class IfElementNameNotEqualsTag extends


IfElementNameEqualsTag {
public int doStartTag() throws JspException (
int rvalue = super.doStartTagO;
return rvalue == EVAL_BODY_INCLUDE ? SKIP^BODY :
EVAL_BODY_INCLUDE;

330 1 1 . XML
IfElementNameNotEqualsTag IfElementNameEqualsTag. doStartTag ,
.
, . iterateElements SAXParserBean
XML-. , SAXElement. ifElementNameEquals ifElementNameNotEquals.

Document Object Model (DOM)


Document Object Model ,
. , , , .
XML, Swing,
. 11.6; .
-inlx
1 inventory
book
9 ISBN
D 0393040009
|j Points Unknown
9 price

9 book
9 ISBN
1579550088
9 title
Q A New Kind of Science
9 C3 price
D 0.75

-tonok
-book

l ~ l ,
[_| ,
, T f . e , , DOM

, . 11.6, XML-,
version="1.0" encoding="ISO-6859-l"?>
// 11.5,
<inventor>
<book>
<ISBN>0393040009</ISBN>

XML-

331

<title>Points Unknown</title>
<price>$23.96</price>
</book>
<book>
<ISBN>157 9550088</ISBN>
<title>A New Kind of Science</title>
<price>$10.75</price>
</book>
</inventory>
Java-, . 11.6, XML- DOM
bean DOMParserBean. , 11.8,, Apache Xerces2.
11.8,a. /WEB- INF/ c l a s s e s /bean s/wnl/dom/DQMParserBean. Java
package

beans.xml.dom;

import J a v a . i o . I Q E x c e p t i o n ;
import J a v a . i o . F i l e I n p u t S t r e a m ;
import o r g . a p a c h e . x e r c e s . p a r s e r s . D O M P a r s e r ;
import o r g . x m l . s a x . I n p u t S o u r c e ;
import
org.xml.sax.SAXException;
import org.w3c.dom.Document;
p u b l i c c l a s s DOMParserBean {
p r i v a t e DOMParserBean() U //
// .
p u b l i c s t a t i c Document getDocument(String f i l e )
throws SAXException, IOException {
DOMParser p a r s e r = new DOMParser();
p a r s e r . p a r s e ( n e w InputSource(new F i l e I n p u t S t r e a m ( f i l e ) ) ) ;
return parser,getDocument();

, , DOMParserBean. getDocument, DOM.


. DOMParserBean getDocument, ,
.
p r i v a t e . ( DOMParserBean "" bean.)
, DOMParserBean.
getDocument, .
XML-. . 11.7 , XML-, . 11.6.
2 Java-, . 11.6, ,
, http://-unma.phplr.mm/advisp. - . .

332 1 1 . XML
. 11.7 JSF- , DOM-.
XML- DOM-.

XML- .

$>JDQM ExHrffe-MEmoft Intend

Book Inventory:

pie

dlr

<i inventory
<book>

: Points Unknown
price i*23 96

0393040009
</ISBN>
titles
Points Unknown

TW: A New Kind of Science


: |* 7
*: The Accelerating Universe

J23.S6

price: 1*19-55

<;
Update DOM Dscument
PrimXML 1
nel

21

1579550088

</ISB

. 7.7. XML-
JSP-, . 11.7, XML-
. Update DOM Document, , , . Print XML, JSP-,
.
XML-.
JSP-, . 11.7, 11.8,6,
11.8,6. /test_dom_booka.jsp
<htmlxheadxtitle>DOM Example</title>
t a g l i b uri='/WEB-INF/tlds/dom.tld' prefix='dom'%>
page import='org.w3c.dom.Document' %>
page import^'org.w3c.dom.Node' %>
r
f
page import= org.w3c.dom.ModeList %>
page import='beans.xml.dom.DOMParserBean' %>
page import='javax.servlet.http.HttpServletRequest'
page import='Java.util.Enumeration' %>
</head>
<body>

XML-

<% Document document = (Document)application.getAttribute(


"document");
if(document == null) {
document = DOMParserBean.getDocument(
"f:/books/jsp/src/xml/booklnventory.xml");
application.setAttribute("document", document);
}
updatePrices(document, request);
showDocument(document, out};
addButtons[out];
<%! private void updatePrices(Node node,
HttpServletRequest request)
throws JspException (
NodeList list - node.getChildNodest);
int childCnt = liat.getLengthO;
if(childCnt > 0) {
String lastTitle - null;
for(int i=0; i < childCnt; ++i) (
Node next = list.item(i);
String value = next.getNodeValue();
if(next.getNodeTypeO Node.ELEMENT_NODE)
String nodeName - next.getKodeKame();
String text getElementText(next);

if(text != null) {
if(nodeName.equals("title")) {
lastTitle - text;
}
else if(nodeName.equals("price")) (
String pval = getParameterValue(request,
lastTitle);
if (pval != null Si Ipval.equals(text))
setElementText(next, pval);
updatePrices(next, request);

)
private void showDocument(Node node, JspWriter out)
throws JspException [
NodeList list = node.getChildNodes();
int childCnt = list.getLengthO;
if{childCnt > 0) 1
String lastTitle = null;
for(int i=0; i < childCnt;

333

334

11. XML
Node next = list.item(i);
try {
String value = next.getNodeValue ();
if(next.getNodeTypet) == Node.ELEMENT_NODE) {
String nodeName = next.getNodeName();
String text = getElementText(next);
if(text != null) {
if(nodeName.equals("inventory")) {
out.print("<font size='5'>Book " +
"Inventory:</fontxf orm>") ;

else if(nodeName.equals("title")) I
LastTitle = text;
out.print ("</pxb>Title: </b>" + text +
else if(nodeName.equals("price")) {
out.print("price: " +
"<input type=' text' size='6' name='" +
lastTitle + ' value='" + text+ "

catchfJava.io.IOException ex) (
throw new JspExceptioniex.getMessage()

I
showDocument(next, out);

private void addButtons(JspWriter out) throws JspException {


try (
out.print ("<hrxinput type=' submit' " +
"value='Update DOM Document'/></form><p>");
out.print("<form action='printXML.jsp'>");
out.print("<input type-'submit' value='Print XML'" +
/
catchfJava.io.IOException ex) {
throw new JspException(ex.getMessage());
private String getParameterValue(HttpServletRequest request,
String param) {
Enumeration parameterNames = request.getParameterNames();
while(parameterNames.hasMoreElements()) {
String next = (String)parameterNames.nextElement();

if(next.equals(param))
return request.getParameterValues(next)[0];

XML-

335

return null;
}
private String getElementText(Node element) (
Node child = element.getFirstChildf);
String text = null;
if(child != null)
text = child.getNodeValue();
return text
}
private void setElementText(Node element, String text) {
Node child = element.getFirstChildO;
if(child [= null)
child.setNodeValue(text);
\
</body>
</html>
JSP-, 11.8,6, , , ; . .
<% Document document - (Document)application.getAttribute(
"document");
if(document == null) {
document - DOMParserBean.getDocument(
"f:/books/jsp/src/xml/booklnventory.xml"];
application.setAttribute("document",
}
updatePrices(document, request);
showDocument(document, out);
addButtons(out) ;

document);

l>
, , ; , XML-
. u p d a t e P r i c e s , showDocument
addButtons.
u p d a t e P r i c e s showDocument
DOM . u p d a t e P r i c e s
, , , showDocument XML- . DOM-, , 11.8,.

336

1 1 . XML

11.8,. DOM-
// DOM
// showDocument() updatePricea ,
// 11.8,6.
NodeList list = node.getChildNodes();
int childCnt = list.getLengtht);
if[childCnt > 0) {
for[int i=0; i < childCnt; ++i) {
Node next = list,item(i);
// next.
// updatePrices(node)
// showDocument(node, out)

updatePrices, showDocument , , , .
DOM.
addButtons. HTML- , . 11.7.
Print XML, ,
. 11.7, printXML.jsp,
11.8,.
11.8,. /printXMX,- jep
<htmlxheadxtitle>DOM Example</title>
<%@ taglib uri='/WEB-INF/tlds/dom.tld' prefix='dom'%>
<%@ page import='org.w3c.dom.Document' %>
<%@ page import^'org.w3c.dom.Node' %>
<%@ page import='org.w3c.dom,NodeList' %>
<l@ page import='javax.servlet.jap.JspWriter' %>
<%@ page import='javax.servlet.http.KttpServletRequest' l>
<%@ page import='Java.util.Enumeration' %>
</head>
<body>
<4 printXML( (Document)application.getAttribute("document") ,out);
%>
<% ! private void printXMMNode node, JspWriter out)
throws JspException {
NodeList list = node.getChildNodes();
int childCnt = list.getLengthO;
for(int i=0; i < childCnt;

XML-

337

Node next = list.item(i);


if (next.getNodeType[) Node.ELEMENT_NODE) (
String name = next.getNodeNamef);
try {
out.print ("Sit,- " + name + "figt; <br/>"};
if(name.equals("inventory"))
out.print("<br/>");

catch(Exception ex) {}
>
String value = getElementText(next);
if (value != null is value.charAt(0) != l\n') (
try {
out.print(value + "<br/>");
}
catch(Exception ex) (}
printXML(next, out);
if(next.getNodeTypef) Node.ELEMENT_NODE) {
String name - next.getNodeNamef);
try (
out.print("filt;" + "/" + name + "Sgt;<br/>")
if(name.equals("book"))
out.print ("<br/>");
}
catch{Exception ex)

private String getElementText(Node element) (


Node child - element.getFirstChildt);
String text null;
iflchild != null)
text = child.getNodeValue();
return text;

showDocument u p d a t e P r i c e s , printXML
. , , , .
JSP-
. , , ; , DOM . , Java-, Web-.

338 11. XML

DOM-
JSP-, 11.9,,
, 11.8,6. ,
, . 11.7.
11.9,a. test_dom_books_with_tags. jap
<htmlxheadxtitle>DOM Custom Tags Example</title>
taglib uri=f/WEB-INF/tlds/dom.tld' prefix='dom'%>
taglib uri='/WEB-INF/tlds/app.tld' prefix='app'l>
</head>
<body>
<dom:parse id='document'
xmlFile='f:/books/jsp/src/xml/booklnventory.xml'/>
<app:updateFrices/>
<font size='5'>Book Inventory:</font>
<form>
<dom:iterate node='<%= document %>' id='book'>
<dom:ifKodeKameEquals node='<%= book %>' names='book'>
<% String lastTitle = null; %>
<dom:iterate node='<*= book %>' id=fbookElement'>
<dom:ifNodeIsElement node='<%= bookEleraent %>'>
<dom:elementValue id='value'
element='<%= bookElement %>'/>
<dom:ifNodeNameEquals node='<%= bookElement %>'
names^'title'>
<% lastTitle = value; %>
</pxb>Title:</b>finbsp;<%= value %><br/>
</dom:ifNodeNameEquals>
<dom:ifWodeNameEquals node='<%= bookElement %>'
names='price' >
price:Snbsp;
<input type='text' size=f 5' value='<%= value %>'
name='<%= lastTitle %>'/>
</dom:ifNodeNameEquals>
</dom:ifKodeIsElement>
</dom:iterate>
</dora:ifNodeKameEquals>
</dom;iterate>
<p><hrxinput type='submit' value='Update DOM Document'/></p>
</form>
<form action='printXML.jspf>
<input type='submit' value='Print XML'/>
</form>
</body>
</html>

XML-

339

JSP- , 11.8,6,
. . 11.1.

11.1. ,
, 11.9,

<dom:parse>

,
xmlFile,

id xmlFile force

<dom:iterate>

, node,

id

<dom:ifNodeNameEquals>


, node
names

node names

<dom:ifNodelsElement>

,
node

node

<dom:elementValue>

element

id element

<app:updatePrices>

, , , <dom: parse>

, . 11,1. 11.9,6
parse.
11.9,6. /WEB-IKP/clasaes/tags/ionl/dom/DOMParserTag. java
package tags.xml.dom;
import javax.servlet.jsp.PageContext;
import javax.servlet.jsp-JspException;
import javax.servlet.jsp.tagext.TagSupport;
import org.w3c.dom.Document;
import beans.xml.dom.DOMParserBean;
public class DOMParserTag extends TagSupport [
private String xmlFile;
private boolean force = false;
public void setXmlFile[String xmlFile) {

340

11. XML

this.xmlFile = xmlFile;
)
public void setld(String id) (
this.id id;
)
public void setForce(boolean force) {
this.force force;
}
public int doStartTag[) throws JspException {
Document document - (Document)pageContext.
getServletContext{).getAttribute(id);
if(document == null II force)
parsed ;
return SKIP_BODY;
)
private void parse() throws JspException {
try {
pageContext.setAttribute(id,
DOMParserBean. get Document (xmlFile) ,
PageContext. AFPLICATION_SCCiPE);
)
catch(Exception ex) {
throw new JspException(ex.getMessage());
public void released
xmlFile = null;
force false;

parse XML-; . DOM-


. parse , t r u e force {
true).
parse DOMParserBean. getDocument. , ,
.
DOM-
DOMParserTaglnfo, TagExtralnfo.
DOMParserTaglnfo 11.9,.
11.9,. /WEB-XNF/classes/taga/xml/dom/DOMParaerTaglnf. Java
package tags.xml.dom;
import
import

javax.servlet.jsp.tagext.TagData;
javax.servlet.jsp.tagext.TagExtralnfo;

XML- 341
import javax.servlet.jsp.tagext.Variableln.fo;
public class DOMParserTaglnfo extends TagExtralnfo {
public VariableInfo[] getVariableInfo(TagData data) {
return new Variablelnfo[] {
new Variablelnfo(data.getld(),
"org.w3c.dom.Document",
true, Variablelnfo.ATTEND)

, ,
id parse.
, parse, updatePrices. updatePrices .
updatePrices 11.9,.
11.9,. /WEB-INF/elassee/fcags/app/OpdatePricesTag. Java
package tags.app;
import
import
import
import
import
import
import
import

java.util.Enumeration;
javax.servlet.ServletRequest;
javax.servlet.jsp.JspException;
javax.servletjsp.PageContext;
javax.servlet.jsp.tagext.TagSupport;
org.w3c.dom.Document;
org.w3c.dom.Node;
org.w3c.dom.NodeList;

public class UpdatePricesTag extends TagSupport {


public int doEndTag() throws JspException {
Document document = (Document)pageContext.getAttribute(
"document",
PageContext.APFLICATION_SCOPE);
if(document != null)
updatePrices(document);
return EVAL_PAGE;
}
private void updatePrices(Node node) throws JspException [
ServletRequest request = pageContext.getRequest();
NodeList list - node.getChildNodesf);
int childCnt - list.getLength();
if(childCnt > 0) {
String lastTitle = null;
for(int t=0( i < childCnt; ++i) {
Node next = list.item(i);
String value = next.getNodeValue();

342 11. XML

if(next.getNodeTypeO == Node.ELEMENT_NODE) f
String nodeName = next.getNodeName();
String text = getElementText(next);
if(text != null) [
if(nodeName.equals("title"}) {
lastTitle = text;
)
else if(nodeName.equals("price")) {
String pval = getParameterValue(request,
lastTitle);
if (pval ! null & !pval.equals(text))
setElementText(next, pval);

updatePrices(next);

private String getParameterValue(ServletRequest request,


String param) {
Enumeration parameterNames = request.getParameterNames();
while(parameterNames.hasMoreElements()} {
String next = (String)parameterNames.nextElement();
if (next.equals(param))
return request.getParameterValues(next)[0];
}
return null;
)
private String getElementText(Node element) {
Node child = element.getFirstChild();
String text = null;
if(child != null)
text = child.getNodeValue();
return text;
)
private void setElementText(Node element, String text) {
Node child = element.getFirstChild() ;
if[child != null)
child.setNodeValue(text) ;

doEndTag
. ,
updatePrices, .
11.8,.

XML-

343

price, , updatePrices
, . ,
.
XML- JSP-,
11.8,, ,
i t e r a t e . 11.9,.
11 -9,. /WHB-INF/dasses/tags/xaLl/dom/HodelteratorTag. Java
package

tags.xml.dom;

import Java.util.Collection;
import java.util.Vector;
import j avax.servlet.jsp.JspException;
import org.w3c. clom. Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
public class NodelteratorTag extends tags.util.iteratorTag
private Node node;

public void setNode(Mode node) [


this.node = node;
)
public int doStartTagO throws JspException (
Node parent = node;
if(node instanceof Document)
parent = ((Document)node).getDocumentElement();
setCollection(collection(parent.getChildNodes{))) i
return super.doStartTag();

I
public void released f
node = null;
}
private Collection collection(NodeList list)
Vector vector = new Vector();
int length = list.getLength () ;

for(int i=0; i < length;


vector.addElement(list.item(i));
}
return vector;

t a g s . u t i l .
IteratorTag, 2.
.
, NodelteratorTag,
11.9,, IteratorTag;

344 11. XML


cioStartTag. super .doStartTag, I t e r a t o r Tag .setCollection.
NodelteratorTag DOM-. , node. Document, parent , Document .getDocumentElement.
.
, NodelteratorTag, NodelteratorTaglnfo, 11.9,.
id i t e r a t e .
11.9,. /WEB-INF/claases/tags/janl/dam/NodelteratorTaglnf. Java
package tags.xml.dom;
import javax.servlet.jsp.tagext.TagData;
import javax.servlet.jsp.tagext.TagExtralnfo;
import javax.servlet.jsp.tagext.VariableInfo;
public class NodelteratorTaglnfo extends TagExtralnfo {
public VariableInfo[] getVariableInfo(TagData data) (
return new Variablelnfo[] (
new Variablelnfo(data.getld() ,
"org.w3c.dom.Node",
true, Variablelnfo.NESTED)

JSP-, 11.9,,
: ifNodeNameEquals, ifNodelsElement elementValue.
, . elementValue
.
ifNodeNameEquals .9,.
11.9,./WEB-INF/classes/tags/xml/dom/IfNodeNameEqualsTag.Java
package tags.xml.dom;
import
import
import
import
import

java.util.StringTokenizer;
java.util.NoSuchElementException;
javax.servlet.jsp.JspException;
javax.servlet.jsp.tagext.TagSupport;
org.w3c.dom.Node;

public class ifWodeNameEqualsTag extends TagSupport (


private Node node = null;
private String names - null;
public void setNode(Node node)

( this.node node; }

XML-

345

public void setNames(String names) { this.names = names; }


public i n t doStartTag() throws jspException (
StringTokenizer tok = new StringTokenizer(names);
String nextName - n u l l , nodeName = node.getNodeName();
boolean nameFound = false;
try f
while(!nameFound)
nameFound - nodeName.equals(tok.nextTokenU);
}
catch(NoSuchElementException ex) {
//
i
r e t u r n nameFound ? EVAL_BODY_INCLUDE : SKIP_BODY;
)
public void r e l e a s e ! ) {
names = n u l l ;
node = n u l l ;

, 11.9,, DOM
( ).
, , , .
ifNodelsElement , . 11.9,.
11.9,3. /WEB-INF/olasses/tags/ionl/dom/IfNoclelsElemaiitTag, Java
package tags.xml.dom;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.TagSupport;
import org.w3c.dom.Node;
public class ifNodelsElementTag extends TagSupport (
private Node node = null;
public void setNode(Node node) (
this.node = node;
}
public int doStartTag() throws JspException {
return node.getNodeTypeO == Node.ELEMENT_NODE ?
EVAL_BODY_1NCLODE : SKIP_BODY;

public void release!) {


node - null;

346

11. XML

11.9, elementValue, .
11.9,. /WEB-INF/classes/togs/xml/dom/GetElementValueTag. Java
package tags.xml.dom;
import
import
import
import

javax.servlet.jsp.JspException;
javax,servlet.jsp.tagext.TagSupport;
org.w3c.dom.Element;
org.w3c.dom.Node;

public class GetElementValueTag extends TagSupport (


private Node element = null;
public void setElement(Node element) {
this.element = element;
}
public void setldfstring id) (
this.id = id;
)
public int doEndTag() throws JspException {
if(element.getNodeType() = Node.ELEMENT_NODE) f
String value - getElementText(element);
pageContext.setAttribute(id, value);
}
else
throw new JspException("Node must be an element");
return EVAL_PAGE;
)
public void released I
element - null,)
private String getElementText(Node element) {
Node child = element.getFirstChild ();
String text = null;
if(child I- null)
text - child.getNodeValue();
return text;

TagExtralnf elementValue GetElementValueTaglnfo - 11.9,.


11.9,. /WEB-lHF/classea/taga/jonl/dom/GetEXeaeiitValueTag. Java
package tags.xml.dom;
import j a v a x . s e r v l e t . j s p . t a g e x t . TagData,-

XML-

347

import javax.servlet.jsp.tagext.TagExtralnfo;
import javax.servlet.jsp.tagext.VariableInfo;
public class GetElementValueTaglnfo extends TagExtralnfo {
public Variablelnfo[] getvariablelnfo(TagData data} f
return new Variablelnfo[] {
new Variablelnfo(data.getldO ,
"Java.lang.String", true,
variablelnfo.AT_END)

, GetElementValueTaglnfo, id e l e m e n t Value.
, 11.8,6 11.9,, , DOM,
Web-, JSP- Java-.

XML-
Internet Web- (, XML, HTML WML) .
XML- XSLT {Extensible Stylesheet Language: Transformations
: ).
XSLT ; ,
XML-, . 10, { JSP-, 11.2,),
11.10,a. date.ami
<?xml version="1.0" encoding="ISO-8859-l"?>
<document>
<date>
Fri Dec 15 11:46:45 MST 2000
</date>
</document>
11.10,6 XSLT, XML-,
11.10,. HTML-, . 11.8.

348

1 1 . XML

' Frocesang XMl Gwxsitod Wi JSP Intem* E plus


| lte

Edit

Jlmi

forefltes

look

,,|Q1 x|

tht>

i Addretl |a hBnVyiocAosLSOTOAmWert^^deta

Today's Date is: Fri Dec 1511:46:45 MST 2000

i
. 11.8. XSLT
XML- HTML-
11.10,6. /date.xsl
<xsl:stylesheet

xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="l.0">

<stsl:template match="/">
<htmlxhead>
<title>Processing XML Generated with JSP</title>
</head>
<body><fant size='4'>
Today's Date is: Otsl:apply-templatas/> </font>
</body>
</html>
</xsl:template>
<acsl: template match="date">
<xsl:apply-templates/>
</xsl:template>
</xsl:stylesheet>
XSLT , -. - (pattern) (action), x s l : t e m p l a t e .
, 11.10, -:
<xsl:template match-"/">...</xsl:template>
<xsl:template match="date">...</xsl:template>
- "/" ( )
" d a t e " ( d a t e ) . .
, ("/")>
HTML-.
<html><head>
<title>Processing XML Generated with JSP</title>
</head>
<body><font size=M'>

XML-

349

Today's Date is: </font>


</body>
</html>

;
x s l : apply-templates,
, . "date" date.
"date" x s l : apply-templates.
, x s l : apply-templates
. "Fri Dec 15 11:46:45
MST2000".
XSLT
XSLT JSP.

XSLTnJSP
JSP XSLT . . 11.9.
. 11.9, XSLT- XML-
, .
, XSLT XML
JSP-. .
/

XML

*-

XSLT

JSP

???

XML

XSLT

JSP

JSP


. 11.9. XML- JSP XSLT

HTML- XSLT-

JSP XSLT
, XSLT- . , XML-. ,
XSLT-, :
<xslt:apply xsl='inventory.xsl' >
<%@ include file='inventory,xml' %>
</xslt:apply>

350

1 1 . XML

, i n v e n t o r y . x s l , XML-, i n v e n t o r y .xml. XML- ; .


<xslt:apply xsl='inventory.xsl'>
<?xml version='1.0' encoding^'ISO-8859-1'?>
</xslt:apply>
. 11.10 Web-, x s l t : a p p l y XSLT- XML-. XML 11.11,.
itsl

]DDM Emmpte Msngt *


lilt

Edit

Bw

Fj/or/kj

loot

19

Go_|

Inventory as of Sat Dec 16 16:24:16 MST 2000


Item

Description

Price

LjU'j broach

from Ihe early 1700's

123.99

Gumhy and Pokey

pliable atlion figures

:.M

Underwood lypewnler

192. excellent shape

299 95

LawnnKMnt

On? of Ihe firs! gas-engine mowers

Superman comic book

Series 1A7, quite rare

2 99

Escher original drawing

signed in blue ink

3459.95

Roman helmet

estimated 200

School desk

made in1949. with inkwell

995.99

Done

499.39

! Local intranet

. 11.10.
XSLT-
11.11,a. /inventory.itml
<?xml version"1.0" encoding="iso-a859-l"?>
<inventory>
<item>
<name>Antique broach</name>
<description>from the early 1700's</description
<price>1238.99</price>
</item>
<item>
<name>Gumby and Pokey</name>
<description>pliable action figures</description>
<price>2.99</price>

XML-

351

</item>
. . . ....
</inventory>

^-, . 11.10, 11.11,6.


11.11,6. /test xslt.jsp
<html><head><title>XSLT Example*:/1itle>
<%@ t a g l i b uri='/WEB-INF/tlds/xslt.tld' p r e f i x = f x s l t '
</head>
<body>
<font size=' 5'>
Inventory as of <%= new java.util.Date() %>
</font>
<xsIt:apply x s l = ' i n v e n t o r y . x s l ' >
<%6 include file='inventory.xml' %>
</xslt:apply>
</bodyx/html>
JSP-, 11.11,6, i n v e n t o r y , x s l
i n v e n t o r y , xml, xs I t : apply. i n v e n t o r y , x s l 11.11,.
11.11,. /inventory.
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
:template match="/">
<html>
<head>
<title>lnventory</title>
</head>
<body>
<table cellspacing^'15'>
<th><u>Item</u></th>
<th><u>Bescription</u></th>
<thxu>Price</u></th>
<xsl:apply-templates/>
</table>
</body>
</html>
:template>
cxsl:template match="item">

352

11. XML

<trxxsl:apply-templates/x/tr>
</xsl:template>
<xsl;template match="item/*">
<tdxxsl: apply-templates/x/td>
</xsl:template>
:stylesheet>
, 11.1,, HTML. HTML-, TABLE , .
item,
name, description price.
xslt: apply
11.11,.
11.11,. /WEB-INF/classes/tags/xml/xslt/XSLTApplyTag. Java
package tags. xml, xslt;
import
import
import
import
import
import
import

Java,io.StringReader;
javax.servlet.ServletContext;
javax,servlet.jsp.JspException;
javax.servlet.http.HttpServletRequest;
javax.servlet.http.HttpServletResponse;
javax,servlet.jsp.tagext.BodyTagSupport;
beans.xml.xsit.XSLTProcessorBean;

public class XSLTApplyTag extends BodyTagSupport (


private String salt
public void setXsl(String xsl) (
this.xsl = xsl;

public int doAfterBody(} throws JspException {


XSLTProcessorBean xslBean = new XSLTProcessorBean();
ServletContext context = pageContext.getServletContext()
String body = bodyContent.getstring().trim();
try {
if(body.equals("")) {
throw new JspException("The body of this tag " +
"must be XML.");
)
xslBean.process(new StringReader(body),
context.getResourceAsStream(xsl),
getPreviousOut()) ;
}
catch(Exception ex) (
throw new JspException(ex.getMessaget));
}
return SKIP_BODY;

XML-

353

, 11.11,,
XSLT- bean. , , p r o c e s s bean, .
11.1,.
11.11,
XaltProcessorBean.Java
package beans.xml.xslt;
import
import
import
import
import
import

Java.io.InputStream;
Java.io.Reader;
javax.servlet.ServletException;
javax.servlet.http.HttpServletRequest;
javax.servlet.http.HttpServletResponse;
javax.servlet.jsp.JspWriter;

import
import
import
import

org.apache.xalan.xslt.XSLTInputSource;
org.apache.xaIan.xslt.XSLTProcessor;
rg,apache.xaIan.xslt.XSLTProcessorFactory;
org.apache.xalan.xslt.XSLTResultTarget;

public class XSLTProcessorBean implements Java.io-Serializable {


public void process(Reader xmlrdr, InputStream xslstrm,
JspWriter writer)
throws Java.io.IOException, ServletException (
process(new XSLTInputSource(xmlrdr),
new XSLTInputSource[xslstrm), writer);
}
public void process(XSLTInputSource xmlsrc,
XSLTInputSource xslsrc,
JspWriter writer)
throws Java.io.IOException, ServletException {
try {
XSLTProcessorFactory.getProcessor().process(
xmlsrc, xslsrc,
new XSLTResultTarget(writer));
}
catch(Exception ex) {
throw new ServletException(ex[ ;

XSLT- Apache Xalan,


, . XSLT-, p r o c e s s XSLT-,
XSLT-n J s p W r i t s r .

354

1 1 . XML

XSI- JSP-


XSLT- .
XSLT- XML-, ,
JSP-. , , HTML-,
. 11.10.
, i n v e n t o r y , xml, II.12,.
11.12,. , JSP-
<xsl:stylesheet xmlns:xsl="http://www,w3.org/1999/XSL/Transform"
version="1.0">
<xsl:template match="/">
<jsp:root xmlns : jsp="http: //Java. sun.com/jsp_l_2">
<head>
<title>Inventory</title>
</head>
<body>
<font size='4'>
Inventory as of <jsp:expression>
new java.util.Date()
</jsp:expression>
</ont>
<table cellspacing='15'>
<thxu>ltem</ux/th>
<th><u>Desctiption</ux/th>
<th><u>Price</ux/th>
<xsl:apply-templates/>
</table>
</body>
</jsp:root>
</xsl :terciplate>
:template match="item">
<tr><xsl:apply-templates/x/tr>
</xsl:template>
<xsl:template fflatch="itero/*">
<tdxxsl:apply-templates/x/td>
</xgl:template>
</xsl:stylesheet>
inventory, xsl, 11.12,,
;
> java org.apache.xalan.xslt.Process -in inventory.xml -xsl
inventory.xsl -out inventory.jsp

XML* 355

inventory. xird 6 . 11.3. JSP-


{inventory. j sp), ,
11.12,6.
11.12,6. JSP-,
JSP-
<?xml version="l. " encoding="UTF-8"?>
<jsp:root xmlns:jsp="http://java.sun.com/jsp_l_2"xhead>
<title>Inventory</title></headxbody><font size="4">
Inventory as of
<jsp:expression>
new java.util.Date()
:expression>
</font><table cellspacing="15">
<thxu>item</ux/th>
<thxu>Description</uX/th>
<thxu>Price</ux/th>
<tr>
<td>Antique broach</td>
<td>from the early 17OO's</td>
<td>1238.99</td>
</tr>
<tr>
<td>Gumby and Pokey</td>
<td>pliable action figures</td>
<td>2.99</td>
</tr>
... ...
</tablex/body>
</jsp:root>

JSP-, 11.12,6, HTML-,


, . 11.10, , XML-. , XSLT XML-, ( JSP 1.2, JSP.)

XML- JSP
, JSP XML-. JSP 1.1 XML- MeHTOBjSP, , j s p : s c r i p t l e t
.

356 11. XML

, JSP- XML-
. ,
JSP- XML. , XSLT-
XML-;
JSP-, , .

XSLT-
XSLT-
.
; HTML-.
XML-, JSP; , , HTML-,
XML, HTML-. ,
. , XSLT- . , .

XPath
XPatli , XSLT-
XML- . , " / " :
<xsl:template match="/">...</xsl:template>
,
XPath- " / " , .. . XPath- , .
XPath XML-, XSLT-,
XPath , XSLT-
XPath XSLT. XPath
XSLT- Apache Xalan.
JSP-, . 11.11, ,
XML-.
bean, , , XPath
XML-.

XPath

File

Edit

XKW

FjjvorjiB

Took

357

Jjc|)

Conference Attendees
Cslesline. Horace
Graves. Samuel
Lopez.Jose
Martin. Roy
Royat, Stanley
Woodard, Daniel

2] Oa

' I ']SlaIHMnir

. 11.11. XPath

|5-, . 11.11, 11.13,.


11.13,a. test_xpath.jsp
<htmlxheadxtitle>XPath Example</title>
<%S t a g l i b uri='xpath' prefix='xpath' l>
<%@ page import=f org. w3c.dorrL.Node' %>
</head>
<body>
<font size=' 4' >Conference Attendees</fontxp>

<xpath:selectNodes id='node'
xmlFile='f:/books/jsp/sre/xml/names.xml'
expr='//name'>
<% Node f i r s t = node.getAttributes().getNamedltemf"first");
Node i a s t = noda.getAttributes.getNamedltemC'last"); %>
< l i x % = l a s t . getNodeValue () %>,

<%=first. getNodeValue () %x/li>

</xpath:selectNodes></p>
</bodyx/html>

selectNodes, 11.13,,
XML-. )^ia
XPath-. ,
, .
.13,, node.

358 11. XML


XML- names.xml, JSP-, 11.13,6.
11.13,6. names,xml
<?xml version="1.0"?>
<doc>
<name first="Horace" last="Celestine"/>
<name first="Samuel" last="Graves'7>
<name first="Jose" last="Lopez"/>
<name first="Roy" last="Martin"/>
<name first="Stanley" last="Royal'7>
<name first="Daniel" last="Woodard"/>
</doc>
11.13,
selectNodes.
11.13,s.

/WEB-INF/cIasses/tags/soni/xpath/XPathTag.java

package tags.xml.xpath;
import
import
import
import
import
import
import
import
import
import

java.util.Collection;
Java.util.Vector;
javax.servlet.jsp.JspException;
javax.servlet.jsp.PageContext;
org.w3c.dom.Document;
org.w3c.dom.Node;
org.w3c.dom.NodeList;
beans.xml.dom.DOMParsecBean;
beans.xml.xpath.XPathBean;
tags.util.IteratocTag;

public class XPathTag extends IteratorTag {


private String file, expr;
private boolean force = false;
public void setXmlFile{String file) { this.file = file; }
public void setExpr(String expr)
( this.expr = expr; }
public void setForce(boolean force) ( this.force = force; }
public int doStartTagO throws JspException {
Document document = (Document)pageContext.getAttribute{file,
PageContext.SESSION_SCOPE);
NodeList list = null;
if(force ]| document -= null) {
try {
document - DOMParserBean.getDocument(file);
}
catch[Exception ex) (
throw new JspException(ex.getMessage());
}
pageContext.setAttribute(file, document,
PageContext.SESSION^SCOPE);

XPath

try {
setCollection(
collection(XPathBean.process(document,
}
catch(Exception ex) {
throw new JspException(ex.getMessage[));
}
return super.doStartTag();

359

expr}));

}
public void release!) (
file = expr = null;
force false;
)
private Collection collection(NodeList list) (
Vector vector = new Vector ();
int length - list.getLength();
for(int i=0; i < length;
vector.addElement(list.item(i));
}
return vector;

, 11.9,,
I t e r a t o r T a g ( I t e r a t o r T a g 2).
XPathTag . d o S t a r t T a g bean XPathBean,
XPath. XPath- NodeList, , . XPathTag. d o S t a r t T a g , I t e r a t o r T a g . s e t C o l l e c t i o n . XPathTag . d o S t a r t T a g
s u p e r . d o S t a r t T a g , I t e r a t o r T a g ,
, s e t C o l l e c t i o n .
XPathBean 11.13,.
11.13,. /WEB-INF/elasses/beans/Kml/acpatli/XFathBaan. Java
package beans,xml.xpath;
import
import
import
import

Java.io.InputStream;
Java.io.FileInputStream;
Java,io.FileNotFoundException;
javax.servlet.jsp.JspException;

import
import
import
import
import

org,apache.xerces.parsers.DOMParser;
org.w3c.dom.Node;
org.w3c.dom.NodeList;
org.xml.sax.InputSource;
org.xml.sax.SAXException;

import org.apache.xalan.xpath.XPathSupport;
import org.apache.xalan.xpath,XPath;

360 11. XML


import
import
import
import

org.apache.xalan.xpath.XPathFrocessorlmpl;
org.apache.xalan.xpath.xml.XMLParserLiaisonDefault;
org.apache.xalan.xpath.xml.PrefixResolverDefault;
org.apache.xalan.xpath.XObject;

public class XPathBean (


private XPathBean() ( } //
public static NodeList process(Node node, String expr)
throws SAXException {
XPathSupport s = new XMLParserLiaisonDefault();
PrefixResolverDefault pr - new PrefixResolverDefault(node);
XPathProcessorlmpl processor = new XPathProcessorlmpl(s);
XPath xpath = new XPath();
processor.initXPath[xpath, expr, pr);
XObject xo = xpath.execute(s, node, p r ) ;
return xo.nodeset();

SAXParserBean, DOMParserBean XSLT P r o c e s s o r Bean, , XPathBean , . ,


X P a t h B e a n . p r o c e s s , XPath-.
DOM (,
). NodeList, , XPath-.
DOMParserBean, XPathBean
. , ,
XPathBean p r i v a t e .

JSP
XML. , XML- , JSP.
JSP XML. JSP ,
XML, XML . , Web-
XML- JSP-.
XML- API: SAX DOM.
;
SAX- DOM-.
XSLT- XML- HTML. : . , .


JSP
...
.
- .
- "".
- .
-

Model 2.
- .
- : JSP- .
- : .
.
.
HTML-.
.
SSL.
1_00.

, ,
Web-: Model 2, .. Web-,
. .
,
,
.

MVC Model 2.

: , .

|5-.

XML DOM.

, .

,
, Web-,
, . , , ,
. ,
, , .
, , .
. , , , .

364 12. JSP


,
.

: > "">
> .
MVC: , .
: 8, , HTML-, , , SSL XML.

,
.


. 12.1, , , , 10 .
, .. JSP, . "", , .
. 12.1 ,
" , ". , "",
" " " ".
, . 12.1, .
1.
Go Shopping.
2. , "".
,
"", Web-.
3. Checkout,
Web-.
4. {
), , . ,
"".
5. Purchase the Items Listed Above
.
6. , , .

, , . 12.2.

Jh - , .

" i

Welcome to FmitStand.oom

Weteome to FruitStand.cam

MMil 2 JSP *
.

T-I

Mb
It |HI*I

:--.

^ :, i

"""^

M M

- i'.^JJ

'-

link F"3

fit-

FBI

an
FruilStancl.com

FrurtSlane.com

^.
r i , .. .. h -

BD

I 4 2 J 0 '

IBM

UP

. 12. . : , "",
( Web-
, )

365

366 12. JSP

(
- - i

case_studv -'
; graphics:

: flags
j fruit
j Web-inf ' '
B O classes
- action
:--] actions
fti i_J beans'
- tags ^ , ^ ' _
+

|sp

'


(
)

. ,
(beans ),
(JSP-]
( )

50 .

util
J JSP- ; \

- , V .
. 12.2.

, ,
g r a p h i c s , /WEB-INF.
. /WEB-INF , ,
.
, , Model 2, 6.
"--" (MVC) ,
. bean, JSP-, , , .
JSP-, ,
/WEB-INF/jsp, .
, , , /WEBINF/ jsp/homepage.
Resin 1.2.1 Tomcat 3.2 final.
.
JAR- ?_/
webapps ( Tomcat) $RESIN_HOME/webapps ( Resin).
$_ $RESIN_HOME , Tomcat Resin. -

367

, Tomcat Resin, ,
, Tomcal 3.2 final
$TOMCAT_HOME/conf/server. xml :
<Context path="/case-study"
docBase="f:/books/jsp/src/case_study"/>
Resin $RESIN_HOME/conf/resin.conf
.
<web-app id='case-study'
app-dir=' f:/books/jsp/src/case_study/final'/>
, , , " , ".


, ,
/ i n d e x , j s p . /WEB-INF/web.xml :
<?xml version="l.0" encoding="ISO-8859-l"?>
<!DOCTYPE web-app
PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.2//EN"
"http:Z/java.sun.com/j2ee/dtds/web-app_2.2.dtd">
<welcome-fi
<welcome-file>index.jsp</welcome</welcome-fi
</web-app>
Tomcat Resin /index, j s p
URL h t t p : / / l o c a l h o s t : 8080/case-study (
). /index, j s p 12.1,.
12.1,a. /index.jsp
page contentType='text/html; charset=UTF-8' %>
<%@ taglib uri='regions' prefix='region' %>
<%@ include file='/WEB-lNF/jsp/regionDefinitions.jsp' %>
<region:render region='HOMEPAGE_REGIOK'/>
, JSP-,
, UTF-8.
8.
/ i n d e x . j s p ,
. 4.

368

12. JSP

/WEB-INF/jsp/regionDefinitions.
jsp, /index* jsp. Web- , 12.3*
tltw

F/orlt

Welcome to FruitStand.com

A Model 2 JSP Application

_ s

? mockup of foil stand use? many of Ihe techniques discussed in Advanced JarvsEarver Pages,
published by Sun Microsystems Press and Frenike-Hall in. May 2001. That book dia?u&se$ a- simpleModel 2 Web application framework Ihefs Ihe basis for Ihis application. The purpose of this aplicallon is
lo illustrate using Ihe bunk's techniques lo develop noniriwal wsb application
This, web anpiicaiion is iniernanonaliTed in three languages. English, Gem-tan, and Chinese. By default.
this application utes The browser's language preferences te decide which language to use, but you can
also ejplicitly se" the language by clicking on one otiha flags in the sidebar Try n now, if you like.
Note, vow browser mvsi support Chinese farts to see the Chinese iranstst&rta. S yow browser's
wlt^sffe for mow information oonnemnq rfai support.
JSP templates are used extensively LhrdughQui tn-G web applicaimn ED consiruct web pages. Every web
page m th plieai was creaied with JSP template, which lets those share components;
for tjxafia . the text "Welcome tc Fruiiztand " and (he honzania] rule underneath ii are creaied by
a JSP file thai n reused by every wab page m Ihis application JSP template's, encapsulate page layout
and encourage the uee of reusable components.
This wab application uses programmatic authenticatjorv-meaning authintfcation implemanled from
scratch-to ensure poiabiiily. The auiheniicaiian farces usere to login aefora ttiay can check uut their
purchaae. Va user doesni have an account. Ihey are given Ihe opportunn ( create one and
subsequently login. Programmatic aulheniicalien, as Oflpcsed to BASIC or DIGEST atfhenlicalicn.
gives applications complete control over authentication because it takes the s-e-rvie] container uu| of the
authentication loop.
Many oiher techniques from Advanced JavsServer Pages are used m Ihis WBD application; for example,
^ framework is usefl ID handle HTML forms and custom tage are used lo delect Bens Hive form
resubimssinns. This qppliciiiun also uses- rrary of the book's other JSP custom tags
To g atlrtad. click l h i Go Shopping bulion in the sidebar

* Thanks for flapping by Todiy it Wtttnext*/, FeBtv*r/2i. 2001.

ej Otr

, 12.3.

JSP-, ,
, : ,
, . , ,
Go Shopping, "Welcome to F r u i t stand.com" . , , .
JSP-, . JSP ; -

369

. 4.
regionDef i n i t i o n s . j sp , . 12.1,6 (
regionDef i n i t i o n s . jsp ).
12.1,6. /WEB-IMF/jsp/regionDefinitions . jsp ()
<%@ t a g l i b uri='regions' prefix='region' %>
<region:define id='STOREFRONT_REGION'
template-'/WEB-INF/jsp/templates/hscf.jsp'>
<region:put s e c t i o n = ' t i t l e '
content^'FruitStand.com'
direct='true'/>
<region:put section='background'
content='graphics/blueAndWhiteBackground.gif'
direct^'true'/>
<region:put section='header'
content^'/WEB-INF/jsp/storefront/header.jsp'/>
<region:put

section-'sidebar'
content=' /WEB-INF/jsp/storefront/sidebar.jsp'/>

<region:put section='content'
content='/WEB-INF/jsp/storefront/content.jsp'/>
<region:put section='footer'
content'/WEB-iNF/jsp/storefront/footer.jsp'/>
</region:define>
<region:define id='HOMEPAGE_REGION' region='STOREFRONT_REGION'>
<region:put section='sidebar'
content='/WEB-INF/jsp/homepage/sidebar.jsp'/>
<region:put section='content'
contents/WEB-INF/j /homepage/content.j sp'/>
</region:define>

regionDef i n i t i o n s . j sp STOREFRONT_REGION, "" . HOMEPAGE_REGION STOREFRONT_REGION sidebar content.


t i t l e , background, header footer .
JSP-, header footer, 12.1, 12.1,.

370

12. JSP

12.1,. /WEB-INF/jsp/storefront/header. jap


<%9 page contentType=' text/html,- charset=UTF-8' %>
<%@ taglib uri='il8n' prefix='il8n' %>
<font size='6' color='blue'>
<il8n:message k e y = " s t o r e f r o n t . t i t l e " / >
</font>
<hr/>
<br/>

12.1,. /WEB-INF/jsp/storefront/footer. j s p
<%@ page contentType='text/html; charset=UTF-8' %>
<%S taglib uri='il8nf prefix='il8nf %>
<hrxp>
<table>
<tr>
<tdximg src-' graphics/duke, gif' /></td>
<td>
<il8n:message key='login.footer.message'/><i>
<il8n:format date='<%=new Java.util.Date ()%>'
dateStyle='<%=java.text.DateFormat.FULL%>'
</td>
</tr>
</table>

, ,
il8n:message i l 8 n : format, . , ,
. il8n:message i l 8 n : format
"".
il8n:message , . ,
/WEB-INF/classes/app_en.properties, ,
storefront.title=Welcome to FruitStand.com
storefront.form.title=Please select from our fresh fruts.
storefront.table.header.picture=Picture
storefront.table.header.item=Item
storefront.table.header.description=Description
storefront.table.header.price=Price
storefront.table.header.addToCart=Add To Cart

; .

371

JSP-, , 12.1, .
12.1,. /WB-INF/jep/homepa.ge/content.jsp
<%@ page contentType='text/html; charset=UTF-8' %>
taglib uri='il8n' prefix='il8n' %>
<font size='5'
<il8n:message key='homepage.title'/>
<7font>
<11:message key='homepage.text'/>

,
, , . ,
JSP- il8n:message, , homepage . text.


:
, , , Go Shopping. ,
Wcb-. , , 12.2,.
12.2,a. /WEB-IHF/jap/homepage/sidebar. jsp
<%@ page contentType='text/html; charset=UTF-8' %>
<jsp:include page^'../shared/flags.jsp' flush='true'/>
<form action='go-shopping-action.do'>
<input type='submit' value='Go Shopping'/>
</form>

sidebar, jap JSP-, . (/WEB-INF/jsp/shared/f lags, jsp) JSP, ; .


flags . j sp , .
. action go-shopping-action . do. URI,
".do", .
, Model 2,
go-shopping-action. do , 12.2,6,

372

12. JSP

12.2,6. /WEB-INF/cla3ses/actions/GoShoppingAction . Java


package actions;
import
import
import
import
import

javax.servlet.ServletException;
javax.servlet.http.HttpServlet;
javax.servlet.http.HttpServletRequest;
javax.servlet.http.HttpServletResponse;
javax.servlet.http.HttpSession;

import beans.app.ShoppingCart;
import action.ActionBase;
import action.ActionRouter;
import beans.app.Item;
public class GoShoppingAction extends ActionBase
implements beans.app.Constants i
public ActionRouter perform[HttpServlet servlet,
HttpServletRequest req,
HttpServletResponse res)
throws ServletException {
HttpSession session = req.getSession();
ShoppingCart
cart = (ShoppingCart)session,getAttribute(
SHOPPING_CART_KEY)
if(cart == null) (
cart - new ShoppingCart ;
synchronized(this) {
session,setAttribute(SHOPPING_CART_KEY,
)

cart);

)
return new ActionRouter("storefront-page");

GoShoppingAction . perform, , "" ( "" , ShoppingCart), ,


storefront-page.
act ions, proper t i e s , 12.2,.
12.2,. /WEB-lNF/ciasses/actions. properties
# ,
go-shopping-action
query-account-action
new-account-action
show-hint-action
update-locale-action

=actions.GoShoppingAction
-actions.QueryAccountAction
=actions.NewAccountAction
=actions.ShowHintAction
=actions.UpdateLocaleAction

373

add-selection-to-cart-action=actions.AddToCartAction
checkout-action
=actions.CheckoutAction
validate-account-action
=actions.ValidateAccount
Action
purchase-action
^actions.PurchaseAction
# JSP-,
storefront-page
=/WEB-INF/jsp/storefront/page.jsp
login-failed-page
=/WEB-INF/jsp/loginFailed/page.jsp
query-account-page
=/WEB-INF/jsp/createAccount/page.jsp
account-created-page=/WEB-INF/jsp/accountCreated/page.jsp
show-hint-page
=/WEB-INF/jsp/showHint/page.jsp
checkout-page
=/WEB-lNF/jsp/checkout/page.jsp
purchase-page
=/WEB-INF/jsp/purchase/page.jsp

actions . p r o p e r t i e s .
; go-shopping-action, do
a c t i o n s . GoShoppingAction, 12.2,. ; , storefront-page, go-shoppingaction.do.

""
, ""
. , URL h t t p : / / l o c a l host: 8080/case_study. , / index. j sp. Go Shopping, go-shopping-action.do. GoShoppingAction, "" * ,
"" . "" . 12.4.
JSP-, "", 12.3,.
12.3,a. /WEB-INF/jsp/storefront/page.jsp
<% taglib uri='regions' prefix^'region' %>
<region:render region-'STOREFRONT_REGION'/>

JSP- STQREFRONT_REGION, /WEB-INF/jsp/regionDefinitions.jsp.


12.1,6.

374

12. JSP
(
flit

Welcome to FruitStand.com
Please select from our fresh fruts and vegetables.
Plctun

Ham

Description

appla

Crunctiy and sweet

S 0 39 .

banana

there are more than ]QQQ kinds of bananas

..

( 19 .

: grapefruit

bit with sugar

(.

: grapes

i purple grapes are b&sl

JO 79.

kiwi

Roys (

i .9 .

peach

come ( a can

$ D.39 /It.

. /2.4. ""
STORE FRONT_REGION : h e a d e r , j s p , s i d e b a r , jsp,
c o n t e n t . j sp f o o t e r . j sp. , ( h e a d e r . j sp) { f o o t e r . j sp) ,
12.1, 12.1,. 12.3,6
, Web-.
12.3,6. /WEB-INF/jsp/storefront/sidebajr. j s p
<%@ page contentType=' text/html; charset=rjTF-8' %>
<jsp:include page='../shared/flags.jsp' flush='true'/><p>
<jsp:include page='../shared/cart.jsp' flush='true'/></p>

375

HOMEPAGE_REGION, STOREFRONT
REGION f l a g s . j s p , . , STOREFRONT_REGION
, "" .
/WEB-INF/j sp/ s h a r e d / c a r t , j s p ,
12.4,6.
STOREFRONT_REGION
/WEB-INF/ j s p / s t o r e f r o n t / c o n t e n t . j s p ,
12.3,.
12,3,. /WEB-XSF/jsp/storefront/content. j s p
<%@ page contentType='text/html; charset=UTF-8' !>
<%@
<%@
<$@
<%@

taglib
taglib
taglib
taglib

uri='database'
uri='html'
uri-'il8n'
uri='logic'

prefix='database'
prefix='html'
prefix^'il8n'
prefix^'logic'

%>
%>
%>
%>

<font s i z e = ' 4 ' color='blue'>


<il8n:message key='storefront.form.title'f>
</font><p>
<database:query id='inventory' scopes'session'>
SELECT * FROM Inventory
</database:query>
<% String currentltem = null, currentSku = null; %>
<table border='l' cellpadding='5'>
<tr><th><il8n:message key='storefront.table.header.picture'/>
</th>
<database:colmnnNames query^'inventory' id='name'>
<logic:stringsNotEqual compare^'SKU' to='<%= name %>'>
<% String hdrKey - "storefront.table.header." +
name.toLowerCase[); %>
<thxil8n:message key-'<%= hdrKey %>' /></th>
<logic:stringsEqual compare='NAME' to=r<%= name %>'>
<thxil an: message
key='storefront.table.header.description'/>
</th>
</logic:stringsEqual>
</logic:stringsNotEqual>
</database:
< t h x i l 8 n : m e s s a g e key=' s t o r e f r o n t . table.header.addToCart' />
</th>
</tr>

376

12. JSP

<tr>
<database:rows query='inventory'>
<database:columns query='inventory' columnKame='name'
columnvalue='value'>
<logic:stringsEqual compare='SKU' to='<%= name %>'>
<% currentsku = value; l>
<tdximg src='<%= "graphics/fruit/" + currentSku +
"
</logic:stringsEqual>
<logic:stringsEqual compare='NAME' to='<%= name %>'>
<% cucrentltem value; %>
<td><%= value %></td>
<tdxil8n:message key=' <%=value + ".description"%>' />
</td>
</logic:stringsEqual>
<logic:stringsEqual compare='PRICE' to='<%= name %>'>
<td><%= value %></td>
<td>
<form action- add-selection-to-cart-action.do
>
1
<html:link:s name='<%= currentSku + "-' +
1
currentltem + "-' +
value %>'>
<option valuer' 0.00 '>0.00</option>
coption value=' 1.00 '>1.00</option>
<option valuer' 1.50 '>1.50</option>
<option value=' 2.00 '>2.00</option>
<option value=' 2.50 '>2.50</option>
<option value=' 3.00 '>3.00</option>
<option value=' 3.50 '>3.50</option>
<option value-' 4.00 '>4.00</option>
<option value=' 4.50 '>4.50</option>
<option valuer' 5.00 '>5.00</option>
<option value=' 5.50 '>5.50</option>
</html:links>
</form>
</td>
</trxtr>
</logic:stringsEqual>
</database:columns>
</database:rows>
</table>
<database:release query='inventory'/>
, . , . 12.4.
c o n t e n t . j sp ^ h t m l : l i n k s ,
2,
; ,

377

add-selection-to-cart-action.do. add-selection-to-cart-action.do actions.AddToCartAction; actions.properties,


12.2,. AddToCartAction .

""
, . 12.4,, , actions.AddToCartAction.
AddToCartAction 12.4,.
12.4,a. /VreB-INF/classes/AddToCartAction.Java

package actions;
import Java.util.Enumeration;
import java.util.Iterator;
import java.util.StringTokenizer;
import javax.servlet.*;
import javax.servlet.http.*;
import beans.app.Item;
import beans.app.ShoppingCart;
import action.ActionBase;
import action.ActionRouter;
// , :
// --=; ,
II 1002-banana-0.69=0.75.
public class AddToCartAction extends ActionBase
implements beans.app.Constants {
public ActionRouter perform(HttpServlet servlet,
HttpServletRequest req,
HttpServletResponse res)
throws ServletException {
Enumeration
e req.getParameterNames();
String skuAndFruit (String)e.nextElement();
String
amount = req.getParameterValues(skuAndFruit)[0],
ShoppingCart cart = (ShoppingCart)req.getSession().
getAttribute(SHOPPING_CART_KEY);
if(cart null) {
throw new ServletException("No cart found.");
>
StringTokenizer tok = new StringTokenizer[skuAndFruit, " - " ) ,
String sku = (String)tok.nextElement[),
fruit = (String)tok.nextElement{),
price (String)tok.nextElement0;

378

12. JSP
Iterator it = cart.getItems().iterator();
boolean fruitWasInCart = false;
while(it.hasNext t)) (
Item item = (Item)it.next();
if(item.getName().equals(fruit)} {
fruitWasInCart = true;
item.setAmount(item.getAmount(} +
Float.parseFloat(amount))
if (!fruitWasInCart) {
cart.acidltern(new Item(Integer.parselnt(sku), fruit,
Float.parseFloat(price),
Float.parseFloat(amount))) ;
1
return new ActionRouter("storefront-page");

, , _-11-=. , -

$0,49,
1004-grapefruit-0.49=2.0. AddToCartAction

"" .
perform ,
Web- "". "" ,
"" . JSP-, "" , 12.4,6.
12.4,6. /WEB-INF/jsp/sharea/cart. jsp
<%@ taglib uri='application' prefix='app' %>
<img src='graphics/cart.gif/>
<table cellpadding='3'>
<app:iterateCart id='cartItem'>
<tr>
<td><%- cartltem.getName()
%></td>
<td><%= cartltem.getAmount() %></td>
</tr>
</app:iterateCart>
</table>
<form action^'checkout-action.do'>
<input type=' submit'value='checkout'/>
</form>

379

JSP-, 12.4,6, "" ,


. 12.4,.
12.4,. /WEB-lNF/classes/tags/app/CartltaratorTag. Java
package tags.app;
import
import
import

javax.servlet.jsp.PageContext;
javax.servlet.jsp,JspException;
javax.servlet.jsp.tagext.TagSupport;

import beans.app.User;
import beans,app.Users;
import beans.app.ShoppingCart;
public class CartlteratorTag extends tags.util.IteratorTag
implements beans.app.Constants {
public int doStartTag() throws JspException {
ShoppingCart cart = (ShoppingCart)pageContext.getAttribute(
SHOPPING_CART_KEY,
PageContext.SESSION_SCOPE) ;
if(cart null) {
throw new JspException("CartlteratorTag can't find " +
"cart");
}
setCollection(cart.getItems());
return super.doStartTag {);

, "" ;
, id .
12.4, , , IteratorTag, 2. C a r t l t e r a t o r Tag, doStartTag setCollection, ,
, , super .doStartTag.
"" Web- Checkout, checkout-action.do. a c t i o n s . p r o p e r t i e s , 12.2,, checkout-action.do a c t i o n s .
Checkout Act ion. Checkout Act ion 12.5,.
12.5,3. /WEB-INF/classes/CheckoutAction. Java
package actions;
import
import

javax,servlet,ServletException;
javax,servlet.http.HttpServlet;

380

12. JSP

import javax.servlet.http.HttpServletRequest;
import j avax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import beans.app.ShoppingCart;
import action.ActionBase;
import action.ActionRouter;
public class CheckoutAction extends ActionBase
implements beans.app.Constants (
public ActionRouter perform(HttpServlet servlet,
HttpServletRequest req,
HttpServletResponse res)
throws ServletException {
HttpSession session = req.getSessionO;
ShoppingCart
cart = (ShoppingCart)session.getAttribute(
SHOPPING_CART_KEY);
if(cart == null) (
throw new ServletException("Cart not found");
}
return new ActionRouter("checkout-page");
}

, , ""
, , C h e c k o u t A c t i o n . p e r f o r m
. "" , p e r f o r m
, ,
.


, . 12.5, , , "".
Purchase The Items Listed Above.
, , 12.5,6.
12.5,6. /WEB-INF/jap/checkout/page, j s p
<%@ taglib uri='security' prefix='security'%>
taglib uri='regions' prefix='region' %>
<security:enforceLogin
loginPage='/WEB-iNF/jsp/login/page.jsp'
errorPage='/WEB-INF/j sp/loginFailed/page.j sp'/>
<region:render region='CHECKOUT_REGION'/>

381

MWPSCH Inters Itti&a '

FruitStand.com
Here are the items you selected.

liuffl
apple

canla loupe
ors;ie1rj:r
.tilts

AmcunE

Prlca/Ib.

Tolal

20 lbs

39

tDSB

T 3 11)0

10.63

(1.77

ID lbs.

.19

10.19

I04S

11 23

25b3
3 0 lbs.

(079 .7

Tlwitems haeij abo** will tie biitedlo;


Jaoies Wikon
2J973 Roquert Lane
Khica.NewYoik
USA
Visa
Purehnse The hems listed Above

Thanks (or stopping bf Today is Wsdwarfsy, Feb>iwy21, 2001-

*|
. /2.5. Web-,
, "" { 12.3,), , CHECKOUT_REGION,
:
< r e g i o n : d e f i n e id='CHECKOUT_REGIONf region-'LOGIH_REGION'>
<region:put s e c t i o n = ' c o n t e n t '
c o n t e n t = ' /WEB-INF/jsp/checkout/content.jsp'/>
</region:define>
CHECKOUT_REGION LOGIM_REGIOW . , , , , Web-.
/WEB-INF/jsp/checkout/
c o n t e n t , jsp, 12.5,.

382

12. JSP

12.5,. /WEB-XNF/jsp/cheekout/content. jsp


<%@ page contentType='text/html; charset=UTF-8' %>
<%@ page import='beans.app.User' %>
<%@ taglib uri='application' prefix='app' %>
<%@ taglib uri='il8n'
prefix='il8n' %>
<font si2e='4' color='blue'>
<il8n:message base='app' key='checkout.title'/>
</fontxp>
<img src='graphics/cart.gif'/>
<table cellpadding=' 10'>
<thxil8n:message base='app'
key=' checkout.table.header.item'/></th>
<thxil8n:message base^'app'
key='checkout.table.header.amount'/></th>
<thxil8n: mess age base=' app'
key='checkout.table.header.pricePerLb'/></th>
<thxil8n:message base='app'
key=' checkout, table, header .price' /x/th>
<% double total = 0.0; %>
<app:iterateCart id='
<% String name = item.getName();
float
amt = item.getAraount(),
p r i c e = item.getPrice(} ;
%>
<tr>
<td><%= name %></td>
<td><%= amt %> lbs.</td>
< t d x i l 8 n : format currency='<%=new Double (price) %>'/></td>
< t d x i l 8 n : format currency='<%=new Double (price*amt) %>'/>
</td>
</tr>
<% total += price * amt; %>
</app:iterateCart>
<tr>
<td colspan='4'xhr/x/td>
</tr>
<td><bxilBn;message base=' app' key=' checkout, table.total' />
</bx/td>
<tdx/tdxtdx/td>
<tdxilSn: format currency=' <%= new Double f total) $>'/x/td>
</tr>
</table><p>
<% User user = (User)session.getAttribute(
tags.security.Constants,USER_KEY); %>
<font size=M' color='blue'>

383

<:message base='app' key=' checkout .billTo' /><p>


</font>
<%= user.getFirstName () %> <%= user .getLastName () l x b r / >
<%= user.getAddress() %><br/>
<%= user.getCity() %>, <%= u s e r . g e t S t a t e ( ) %><br/>
<%= user.getCountryO %><br/>
<%= user.getCreditCardTypeU %><br/>
<form action^'purchase-action.do'>
<input type='submit'
value='<il8n:message key="checkout.purchase.button"/>'/>
</form>
Web- ( 12.4,6), , , , "", C a r t l t e r a t o r ,
, , .
User,
. , User
, .
, ,
. purchase-action, do, a c t i o n s . PurchaseAction. PurchaseAction 12.5,.
12.5,. /WEB-INF/classes/actions/Purchas&Acfcion . Java
package actions;
import
import
import
import
import

javax.servlet,ServletException;
javax.servlet.http.HttpServlet;
javax.servlet.http.HttpServletRequest;
javax.servlet.http.HttpServletResponse;
javax,servlet.http.HttpSession;

import beans.app.ShoppingCart;
import beans.app.User;
import action.ActionBase;
import action.ActionRouter;
public class Purchaseftction extends ActionBase
implements beans.app.Constants,
tags.security,Constants (
public ActionRouter perform(HttpServlet servlet,
HttpServletRequest req,
HttpServletResponse res}
throws ServletException I
HttpSession session = req.getSession();
ShoppingCart
cart = [ShoppingCart)session.getAttribute(
5H0PPING_CART_KEY)
if(cart == null) {

384

12. JSP
throw new ServletException("Cart not found");
return new ActionRouter("purchase-page");

, 12.5,, PurchaseAction "" . ,


purchase-page.


JSP-,
. . 12.6.
ronft Irtsrat F*pla
fcjli )Mw fewtlie Tool!

Zi

FruitStand.com
Tfiank your piir:ha5e.
Veur OfiaervMill be shipped on 2/21/01
, * i Thanks for 9[opp?ng Jiy.

, 200t.

. 12.6. ,
purchase-page, ,
12.5,, /WEB-INF/jsp/purchase/content. jsp,
12.5..
12.5,. AJEB-INF/isp/purchase/page.jsp
<%@ taglib uri='regions' prefix='region' %>
<region:render region='PURCHASE_REGION'/>
, "" , page. j sp
, .
<region:define id='PURCHASE_REGION'
region='LOGIN_REGION'>
<region:put section= f content'
content='/WEB-INF/jsp/purchase/content.jsp'/>
</region:define>

Model 2 385
CHECKOUT_REGION, PURCHASE_REGION LOGIN_REGION
.
/WEB-INF/j s p / p u r c h a s e / c o n t e n t . j sp, 12.5,.
12.5,. /WEB-iNF/jsp/purchase/content. j s p
<%@ page contentType='text/html; charset=UTF-8' %>
taglib uri='il8:nr prefix=' il8n' l>
<font size-'4' color='blue' >
<il8n:message base='app' 5cey='purchase.title'/><p>
<il8n:massage base='app' key='purchase.willBeShippedOn'/>
<il8n:format date='<%= new java.util.Date() %>'
dateStyle='<%= Java.text.DateFormat.SHORT %>'/></p>
</font>
i 16n :message,
, i l 8 n : format.
.
MVC,
.

Model 2
, , ,
, , .
Model 2, 6, Web "--" (MVC).
; , .

bean, . 12.7. , WEB-INF/classes/beans/app, , , .

User: , .

Users: , .

Item: , .

Inventory: .

ShoppingCart: , .

386

12. JSP

bean
.
*"*"! case_study
i+ J graphics

Gj Web-inf
1
classes
" action
Cl

actions

-Gill beans

ShoppingCart
Item
[nventoiy
Constants

-1-1 app
{ fms
_J email

Ej html
: - j iiBn

:-i:a |dbc
Sj templates
- tags

util

- ( f 5 CreateDB

Java

. J2.7. : bean

,
. Java C r e a t e DB, /WEB- I N F / c l a s s e s / u t i l .


. 12.8 I n v e n t o r y . (),
, .
User, . 14 ,
.
User , , , ,
, .
CreateDB, ,
12.6.

. 12.8. inventory

JSKU
11001

NAME

PRICE j

apple

0.29

banana

0 69

cantaloupe

0.19

grapefruit

049

1005

grapes

a79

1006

fcnri

0.99

1007

peach

039

100

pear

0.89

1003

pineapple

0.29

1010

strawberry

0.B8

1011

watermelon

0.29

1002

J1003
-I004

Model 2 387

12.6. /WEB-INF/util/CreateDB.Java
import
import
import
import

java.sql.Connection;
Java.sql.DriverManager;
Java.sql.SQLException;
Java.sql.Statement;

public class CreateDB {


private Connection conn;
private Statement stmt;
public
new
}
public
try

static void main(String args []) {


CreateDB();
CreateDB() {
{
loadJDBCDriver;
conn = getConnection{"F:/databases/sunpress");
stmt conn.createStatement();

createTables(stmt);
populateTables(stmt) ;
stmt.close() ;
conn.close() ;
DriverManager.getConnection(
"jdbc:cloudscape:;shutdown=true")

}
catch(SQLException ex) I
ex.printStackTrace();
)

private void createTables(Statement stmt) {


try (
3tmt.execute!"CREATE TABLE Users {" +
"FIRST_NAME VARCHAR(IS), " +
"LAST_NAME VARCHAR[25), " +
"ADDRESS VARCHAR(35) f " +
"CITY VARCHARU5), " +
"STATE VARCHAR<15), " +
"COUNTRY VARCHAR(25), " +
"CREDIT_CARD_TYPE VARCHAR(IO), " +
"CREDIT_CARD_NUMBER VARCHAR(2D), " +
CREDITJ:ARD_EXPIRATION VARCHARUO) , " +

"USER_ID VARCHAR[15) f " +


"PASSWORD VARCHAR(15), " +
"PASSWORD_HINT VARCHAR(15), " +
"ROLES VARCHAR(99))");
stmt.execute("CREATE TABLE Inventory (" +
"SKU
INTEGER, " +
"NAME
VARCHAR[30), " +
"PRICE
FLOAT)");
}
catch(SQLException ex) (

388 12. JSP


ex.printStackTrace(};
private void populateTables(Statement stmt) {
try {
stmt.execute("INSERT INTO Users VALUES " +
"('James1, 'Wilson1, '24978 Roquert Lane', 'Ithica'," +
" 'New York', 'USA', 'Visa', '124-3393-62975', '01/05',"+
" 'jwilson', Ts2pdpl8', 'license', 'customer')"),stmt.execute("INSERT INTO Inventory VALUES " +
'apple', '0.29')," +
"(4001
'banana', '0.69'),"
" ( '1002
'cantaloupe', '0.19'J," +
"('1003
'grapefruit', '0.49')," +
" (4004
'grapes', '0.79')," +
"('1005
'kiwi', '0.99')," +
" ('1006
'peach', '0.39')," +
"('1007
pear1, '0.69')," +
"('1008
'pineapple', '0.29')," +
"('1009
'strawberry', '0.89')," +
"('1010
'watermelon', '0.29')");
"('1011
catch(SQLException ex) {
ex.printStackTrace() ;

private void loadJDBCDriver() {


try {
Class.forName("COM.cloudscape.core.JDBCDriver");
catch(ClassNotFoundException e) {
e.printStackTraceO ;
private Connection getConnection(String dbName) {
Connection con = null;
try (
con - DriverManager.getConnection(
11
jdbc: cloudscape: " + dbName + ";create=true") ;
1
catch(SQLException sqe) {
System.err.println("Couldn't access " + dbName);
)
return con;

I
, 12.6,
Cloudscape f: /databases/sunpress. , .

Model 2

389

.
loadJDBCDriver URL getConnection.

bean
bean, ,
, , , . User 12.7,.
12.7,a. /WEB-INF/classes/baans/app/User . Java
package beans.app;
// ,
//
// .
public class User implements Java.io.Serializable {
private final String firstName, lastName, address, city, state;
private final String country, creditCardType, creditCardNumber;
private final String creditCardExpiration;
private final String userName, password, pwdHint, roles;
public User(String firstName, String lastName, String address,
String city, String state, String country,
String creditCardType, String creditCardNumber,
String creditCardExpiration, String userName,
String password, String pwdHint, String roles) [
this.firstName
firstName;
this.lastName
lastName;
this.address
address;
this city
city;
this state
state;
this country
country;
this creditCardType
creditCardType;
this creditCardKumber
creditCardNumber;
this creditCardExpiration
creditCardExpiration;
this userName
= userName;
this password
= password;
this.pwdHint
= pwdHint;
this.roles
= roles;
}
public String getFirstName() { return firstName;
{ return lastName;
public String getLastNameO
{ return address;
public String getAddress()
{ return city;
public String getCityO
{ return state;
public String getStateO
{ return country;
public String getCountryO
public String getCreditCardType()
{ return creditCardType; )
public String getCreditCardNumber() { return creditCardNumber;}
public String getCreditCardExpirationO {
return creditCardExpiration;

390

12. JSP

I
public
public
public
public

String
String
String
String

getUserName()
getPassword()
getPwdHint()
getRoles{)

{
{
{
{

return
return
return
return

userName;
password;
pwdHint;
roles;

}
}
}
}

public boolean equals {String uname, String pwd)


return getUserName().equals(uname) ss
getPassword[).equals(pwd);
)

User ,
. . ,
User . , User ,
, , .
Users, , 12.7,6.
12.7,6. /WEB-INF/clasaes/beans/app/Uaers . Java
package beans.app;
import Java.sql.ResultSet;
import Java.sql.ResultSetMetaData;
import Java.sql.SQLException;
import java.util.Enumeration;
import java.util.Hashtable;
public class Users {
private final static int FIRST_NAME=1, LAST_NAME=2, ADDRESS=3,
CITY=4, STATE=5, COUNTRY-6,
CREDIT_TYPE=7, CREDIT_NUMBER=8,
CREDIT_EXPIRE=9, USER_NAME=10,
PASSWORDS1, PASSWORD_HINT=12,
ROLES=13;
private final Hashtable users = new Hashtable ;
public Users(ResultSet rs) 1
try (
ResultSetMetaData rsmd = rs.getMetaData();
if(rsmd.getColumnCount() > 0) {
boolean moreRows = rSitiextO; //
//
while(moreRows) (
addUser(new User(
t(String)rs.getObject(FIRST_NAME)),trim(),
{(String)rs.getObject(LAST_NAME)),trim(),

Model 2

391

( (String)rs.getObject(ADDRESS)). trim(),
([String)rs.getObject(CITY)),trim(),
((String)rs.getObject(STATE)).trim(),
((String)rs.getObject(COUNTRY)).trim(),
([String)rs.getObject(CREDIT_TYPE)),trim(),
((String)rs.getObject(CREDIT_NUMBER)}.trim,
( (String)rs.getObject(CREDIT_EXPIRE)) ,trim(),
((String)rs.getObject(USER_NAME)).trim(),
((String)rs.getObject(PASSWORD)).trira(),
((String)rs.getObject(PASSWORD_HINT)).trim(),
((String)rs.getObject(ROLES)).trim()));
moreRows rs.next(); //

catch(SQLException ex) (
//
public int getNumberOfUsers() {
return users.size();
)
public User addUser(User user) {
users.put(user.getUserName(), user);
return user;
)
public User getUser(String username, String password) {
User user = getUser(username);
boolean found = false;
iftuser != null) {
found = user.equals(username, password);
)
return found ? user : null;
}
public User getUser(String username) {
return (User)users.get(username);
)
public Hashtable getUsersf) (
return users;
}
public String getPasswordHint(String username) (
User user > getUser (username) ;
return user != null ? user.getPwdHint() : null;

,
Users ResultSet, User.
, Users ,
.

392

12. JSP

User, Users ,
.
12.7, Item, , .
12.7,. /WEB-INF/classes/beans/app/Item. J
package beans.app;
//
//
//
//
//

,
"". : sku, (
), name (), price () amount ().
,
.

public class Item implements Java.io.Serializable {


private final int sku;
private final float price;
private final String name;
private float amount;
public Item tint sku, String
this.sku
sku;
this.name
= name;
this.amount - amount;
this.price - price;
)
public int
getSkuf)
{
public String getNamef)
{
public float getPriceO {

name, float price, float amount) {

return sku;
return name;
return price;

}
)
)

public synchronized float getAmount() {


return amount;
}
public synchronized void setAmount(float amount) {
this.amount = amount;

Item , , . , , . Item
, set- get-, , .
, Item, .
Inventory, , 12.7,.

Mode! 2 393

12.7,. /WSB-INF/classes/beans/app/Inventorv. Java


package beans.app;
import
import

java.util.Iterator;
java.util.Vector;

public class Inventory implements Java.io.Serializable


final protected Vector items;
public Inventory() {
items = new Vector();
}
public void addltem(ltem item) {
items.add(item);
}
public void removeltem(ltem item)
items.remove(item);
}
public Vector getltems () {
return items;

Inventory fa9ade
, ( fa?ade 3). , Inventory
getltems, . , , .
ShoppingCart 12,7,.
12.7,. /WE-INF/classes/beans/app/ShoppingCart.java
package beans.app;
public class ShoppingCart extends Inventory {

"" Inventory, ""


ShoppingCart. , .
, ,
, Constants. Constants 12.7,.

394 12. JSP

12.7,. /WEB-INF/clas/beans/app/Constants.Java
package beans.app;
//
/7 (. /WEB-lNF/classes/actions).
public interface Constants (
//
// .
static final String prefix = "beans.app";
static final String
//
LOCALE_KEY
= prefix + ".locale",
SHOPPING_CART_KEY
- prefix + ".cart",
USERS_KEY
- prefix + ".users",
USERNAME_KEY
-> prefix + " . username",
PASSWORD__KEY
prefix + ".password",
CONFIRM_PA5SWORD_KEY - prefix + ".cnfrmpwd",
FASSWORD_HINT_KEY
= prefix + ".pwdhint",
//
DEFAULT_I18N_BftSE = "app";

, C o n s t a n t s , ,
. , P u r c h a s e A c t i o n C o n s t a n t s
SHOPPING_CART_KEY.

: JSP-
, . ; 4.
.
. 12.9 , JSP-,
. /WEB-INF/ j sp, shared t e m p l a t e s , JSP-, JSP. , /WEB-INF/jsp/accountCreated
page. j sp c o n t e n t . j sp JSP-, .
s h a r e d JSP-,
JSP-, t e m p l a t e s , .
JSP- , , , . , /WEB-INF/jsp/templates/
hscf. j sp. , Web, .

Model 2

case_study
graphics
Web-inf
classes
isP
,'
) accountCreated
checkout - '
createAccount homepage
j login ( 2 j loginFailed - " purchase -.,
shared ^
~" "* - ^
showHint - "~ ~* ^
storefront. *" ^ "* - ^
templates \
"" >.
tlds

395

sidebar
page
header
Form
content

~,

' inventory
sidebai
page
inventory-to-xml
header
footer
content

^ JSP ] XSLT
ftic. 1.9. : JSP-
/WEB-INF/jsp/regionDef i n i t i o n s . j sp, 12.7,.
12.7,./WEB-INF/jsp/regionDefinitions.jsp
taglib uri='regions' prefix='region' %>
<region:de fine i d - " 3 T 0 R E F R 0 N T _ R E G I 0 N '
template='/WEB-lKF/jsp/templates/hscf.jsp'>
<region:put section='title'
content-'FruitStand.com'
direct-'true'/>
<region:put section="background'
content-'graphics/blueAndWhiteBackground.gif'

396

12. JSP
direct='true'/>

<region:put section-'header'
content='/WEB-IMF/jsp/storefront/header.jsp'/>
<region:put section^'sidebar'
1
content^'/WEB-INF/jsp/storefront/sidebar.jsp />
<region:put section='content'
content='/WEB-INF/jsp/storefront/content.jsp'/>
<region:put section='footer1
content='/WEB-INF/jsp/storefront/footer.jsp'/>
</region:define>
<region:define id='LOGIN_REGION' region='STOREFRONT_REGION'>
<region:put section='header'
content='/WEB-INF/jsp/login/header.jsp'/>
<region:put section =1 sidebar 1
content='/WEB-INF/j sp/login/sidebar.j sp'/>
<region:put section='content'
content^1/WEB-INF/jsp/login/content.jsp'/>
</region:define>
<region:define id='HOMEPAGE_REGION' region='STOREFRONT_REGION'>
<region:put section='sidebar'
corvtent='/WEB-INF/jsp/homepage/sidebar.jsp'/>
<region:put section='content'
content='/WEB-INF/jsp/homepage/content.jsp*/>
</region:define>
<region:define id=CREATEJVCCOUNT_REGION' region='LOGIN_REGIOM'>
<region:put section^'content'
content-'/WEB-INF/j sp/createAccount/content.j sp'/>
</region:define>
<region:define id='L0GlN_FfllLED_REGION' region^'LOGIN_REGION'>
<region:put section='content'
content='/WEB-INF/jsp/loginFailed/content.jsp'/>
</region:define>
<region:define id='ACCOUNT_CREATED_REGIOM' region-'LOGIN_REGION'>
<region:put section='content'
content='/WEB-INF/j sp/accountCreated/content.jsp'/>
</region:define>
<region:define id='CHECKO0T_REGI0N' region-'LOGIN_REGIOH'>
<region:put section='content'
content='/WEB-INF/jsp/checkout/content.jsp'/>
</region:define>
<region:define id='PURCHASE_REGION' region='LOGIN_REGIQN'>
<region:put section^'content'

Model 2

397

content='/WEB-iNF/jsp/purchase/content.jsp'/>
</region:define>
<region:define id='SHOW_HINT_REGION' region='LOGIN_REGION'>
<region:put s e c t i o n ^ ' c o n t e n t '
content='/WEB-INF/j sp/showHint/content.jsp'/>
</region:define>
, 12.7,,
. , ,
HOMEPAGE_REGION ,
STOREFRONT_REGION. LOGIN_REGION
STOREFRONT_REGION.
.

.

12.7,.
12.7,3. /WEB-INF/;)ep/teniplat/h*cf . jep

<htmlxhead>
<
%
@ taglib uri-'regions' prefix-'region' %>
<titlexregion: render section='titleV></title>
</head>
<body baclcground-'<region:render section=tbackground1/>1>
<table>
<tr valign-'top'>
CtdXregion: render section1 sidebar'/x/td>
<td>
<table>
<tr><tdxregion: render section1 header'/x/tdx/tr>
<trxtdxregion: render section 'content' /x/tdx/tr>
<trxtdxregion: render section ' footer' /x/td></tr>
</table>
</td>

</tr>

</table>
</bodyx/html>
, 12.7,, HTML-. JSP-, . , LOGIN_REGION
, , , ,
.
, , JSP-,
JSP- page. j sp. -

398

12. JSP

. , 12.7,
p a g e . j sp . JSP-
LOGIN REGION.
12.7,. /WEB-lNF/jsp/login/page. jsp
<%@ t a g l i b u r i = ' r e g i o n s ' prefix='region' %>
<region:render region='LOGIN REGION'/>
, , p a g e . j sp
, . , p a g e , j s p , 12.7,,
.
12.7, . /WSB-INF/j / checkout /page. jsp

<%@ taglib uri='security' prefix^'security'$>


<%@ taglib uri='regions' prefix='region' %>
<security:enforceLogin
loginPage='/WEB-INF/jsp/login/page.jsp'
errorPage='/WEB-INF/jsp/loginFailed/page.jsp'/>
<region:render region^'CHECKOUT_REGION'/>
, 12.7,, s e c u r i t y : e n f o r c e L o g i n . , , , , .
s e c u r i t y : e n f o r c e L o g i n 9.
, , .
, ,
, , , . , , .
Web-,
. , , .
, .
JSP-. JSP-.
.
, ,
JSP-
.

Model 2 399
, , , JSP ,
.
Web-, .
, , .

:
, "--"
(MVC), . .
, .
, ,
; .

,
/WEB-INF/classes (. 12.10).
/ I

-jjjp case_study
Q graphics
13 CJ Web-infActionServlet
AppAuthenticateS ervlel
Authenticates etvlet
SetupS ervlel

Java

XML

. 12.10. w e b . x m l

ActionServlet Model 2 HTTP-, " . do". 6, .


AuthenticateServlet ,
AppAuthenticateServlet. , , .
SetupServlet
. 12.8,6.
, ,
web.xml, 12.8,.

400

12. JSP

12.6,.
<?xml version-"].. " encoding="ISO-8859-l"?>
<!DOCTYPE web-app
PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.2//EN"
"http://java.sun.com/j2ee/dtds/web-app_2.2.dtd">
<web-app>
<servlet>
<servlet-name>authenticate</servlet-name>
<servlet-clasa>AppAuthenticateServlet</servlet-class>
</servlet>
<servlet>
<servlet-naine>action</servlet-riaine>
<3ervlet-class>ActionServlet</3ervlet-cla3S>
<init-param>
<param-name>action-mappir>gs</param-name>
<param-value>actions</param-value>
</init-param>
</servlet>
<servlet>
<aervlet-name>setup</servlet-name>
<servlet-class>SetupServlet</servlet-claas>
<init-param>
<param-naine>jcibcDriver</param-naine>
<param-value>COM.cloudscape.core.JDBCDriver</param-value>
</init-param>
<init-param>
<param-name>jdbcURL</param-name>
<param-value>
jdbc:cloudscape:f:/databases/sunpresa;create=falae
</param-value>
</init-param>
<init-param>
<param-name>jdbcU3er</paraiti-name>
<param-value>roymartin</param-value>
</init-param>
<init-param>
<param-name>jdbcPassword</param-name>
<param-value>royboy</param-value>
</init-param>
<load-on-startup/>
</servlet>
<servlet-mapping>
<servlet-name>action</servlet-name>
<url-pattern>*.do</url-pattern>
</aervlet-mapping>

Model 2 401

<servlet-mapping>
<servlet-name>authenticate</servlet-name>
<url-pattern>/authenticate</url-patte]:n>
</servlet-mapping>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-

<taglib>
<taglib-uri>application</taglib-uri>
<taglib-location>/WEB-INF/tlds/utilities.tld</taglib-location>
</taglib>
. . . ..
</web-app>
web. xml
. , , SetupServlet , JDBC-, JDBC URL, .
, web. xml , . , web.xml 12.8, .
a p p l i c a t i o n :

database

dorn

html

il8n

template

tokens

, .
SetupServlet, ,
12.8,6.
12.8,6. /WEB-INF/classes/SetupServlet.Java
import
import
import
import
import

Java.sql,Connection;
Java.sql.ResultSet;
Java.sql.ResultSetMetaData;
Java.sql.Statement;
Java.sql.SQLException;

import j avax.servlet.ServletConfig;
import javax.servlet.ServletContext;

402

12. JSP

import j avax.servlet.ServletException;
import j avax.servlet.http.HttpServlet;
import beans.app.User;
import beans.app.Users;
import beans.jdbc.DbConnectionPool;
public class SetupServlet extends HttpServlet
implements beans.app.Constants,
tags.jdbc.Constants {
private DbConnectionPool pool;
public void init(ServletConfig config) throws ServletException)
super.init(config);
ServletContext ctx = config.getServletContextf);
createDbConnectionPool(config, ctx);
try (
ctx.setAttribute(USERS_KEY, loadUsers(ctx)};

catch(SQLException ex) {
throw new ServletException(ex);
public void destroy() (
ServletContext ctx = getServletConfig().getServletContext();
ctx.removeAttribute(DBPOOL_KEY);
ctx.removeAttribute(USERS_KEY);
pool.shutdown();
pool = null;
super.destroy();
}
private void createDbConnectionPool(ServletConfig config,
ServletContext ctx) (
pool = new DbConnectionPool(
config.getInitParameter("jdbcDriver"),
config.getInitParameter("jdbcORL") ,
config.getInitParameter("jdbcUser"),
config.getInitParameter("jdbcPwd"});
ctx.setAttribute(DBPOOL_KEY, pool);
}
private Users loadUsers(ServletContext ctx)
throws SQLException {
Connection conn = null;
if(pool != null) {
try (
// ,
// 10 .
conn = (Connection)pool.getConnection(10000);
>
catch(Exception ex) {
throw new SQLExceptionlex.getMessageO);

403

Statement stmt = conn.createStatement(};


ResultSet rs - Stmt.executeQuery("SELECT * FROM USERS")
Users users - new Users(rs};

pool.recycleConnection(conn);
return users;

return null;

, 12.8,6, ,
, web. xml. 10.
SetupServlet .
SetupServlet ; load-on-startup web .xml.
, ,
. .

HTTP-, ".do",
. 6,
. Web-, Model 2; , (. 12.11).
/WEB-INF/classes/action /WEB-INF/classes/action/events
, Model 2.
7.
/WEB-INF/classes/actions ,
. , ,
.
,
. , , ""
AddToCartAction, CheckoutAction.

, , ,
, . .

404

12. JSP

Model 2

rtJLJ graphics
Web-inf
classes
action ' '
events-

--51 actions- _
-EJ beans
tags

-CJ
tlds

Action
ActionBase
ActionFactotii
ActionR outer
S en sitiveActionLis tenet

SJAddToCartAction
CheckoutAction
GoShoppingAction
NewAccountAction
PuichasaAction
Q ueryAccountAction
ShowHintAction
UpdateLocaleAction
ValidateAc

^,

. 12.11. Mode! 2

. 12.12 . ,
, Web. .
" " .
1. Web-.
2. .
3. Web-.
. 12.13 , .

SO 1*

la*

Bitle Ausstellung(Bnrichtung) der


Vertiindung

. 12. ?2. Web- ,

405

406 12. JSP


case_study
graphics
Web-inf
classes
action
Qg events
actions -
beans
S O tags

B-C3
-Si accountCreated
CJ checkout

UpdateLocateAction

-Iv- createAcctKint
!"~1 homepage
["~1 login

CJ loginF ailed
-""1 purchase
-23 shared
showHint
ffJl storefront
templates
C j tlds
_J util
Java

JSP

fttc. 12.13. ,
" "

, ,
, ,
. . ,
, 12.9,.
12.9,a. /WEB-INF/classes/app en.properties
click=click
here=here
messages.login-header-title=FruitStand.com
messages.today=Toda is (0, date}
homepage.title=A Model 2 JSP Application
homepage.text=<p>This mockup of a fruit stand uses many of the
techniques discussed in Advanced JavaServer Pages ( published by Sun
Microsystems Press and Prentice-Hall in May 2001.
... homepage.title

407

login.title=FruitStand.com
login,form.title=Please Login
login.button.submit^login
login.textfield.name=Name
login.textfield.pwd=Password
login.footer.message=Thanks for stopping by. Today is
login.failed.title=Login Failed
login.failed.message=Please enter a valid username and password, or
create a new account
... ...
12.9,6 ,
.
12.9,6. /WEB-INF/clae3ea/app_de. properties
click=Klick
here=Hier
messages.login-header-title^FruitStand.com
messages.today=Huite i s t (0, date}
homepage.title=Eine Model 2 JSP Anwendung

, , , Unicode ( 12.9,). Unicode S.


!

-;:;:

. ; : : .

'.

s ; , . a s

: > . , . . . ; , - , . .

..

.-.-

12.9,. /WEB-IKF/classea/app^zh .properties


click=\u70b9\u51fb
here=\u8fd9\u91cc
messages.Iogin-header-title=\u6b22\u8fce\u514 9\u4e34
messages.today=\u<leca\u5929\u662f fO, date}
homepage.title=\u4e00\u4e2a\u6a21\u5fOf\u4e8cJSP\u8303\u4f8b

12.9, flags . j sp

408

12. J5P

12.9,. /WEB-INF/jsp/shared/flaga. J3p


<% String thisPage request.getServletPath() ;
String updateLocaleAction "update-locale-aetion..do?page=" +
thisPage + "Scountry="; %>
<table widths'160'>
<trxtd>
<a href='<%= updateLocaleAction + "EN" %>'>
<img
src=' graphics/flags/britain_flag.gif/></a>
<a href='<%= updateLocaleAction + "DE" %>'>
<img
src='graphics/flags/german_flag.gif'/></a>
<a href='<%= updateLocaleAction + "ZH" %>'>
<img src=' graphics/f lags/ chine se__f lag . g i f /></ax/tr>
< / t d x t d height='25'></td>
</table>

JSP-, 12.9,,
Web- , .
, flags, jsp /WEB-INF/ j sp/storefront/
sidebar, , , :
http://localhost:80BQ/case-study/update-locale-action.do?page=/WEBINF/jsp/storefront/page,jsp&country=ZH
, flags.jsp,
UpdateLocaleAction, 12.9, .
12.9,. /WEB-INP/claaeee/actione/UpdateLocalaAction. java
package actions;
import java.util.Locale;
import
import
import
import

javax.servlet.ServletException;
javax.servlet.http.HttpServlet;
javax.servlet.http.HttpServletRequest;
javax.servlet.http.HttpServletResponse;

import action.ActionBase;
import action.ActionRouter;
public class UpdateLocaleAction extends ActionBase
implements beans.app.Constants (
public ActionRouter perform(HttpServlet servlet,
HttpServletRequest req,
HttpServletResponse res)
throws ServletException {
Locale locale = new Locale(req.getParameter("country"),"")
String forwardTo - req.getParameter("page");


req.getSession(true).setAttribute(LOCALE_KEY,
res.setLocale(locale);

409

locale);

return new ActionRouter(forwardTo, true, false);

U p d a t e L o c a l e A c t i o n , , ( JSP, 12.9,). , , , .
, i l 8 n . , .

, . , ,
" ", .
1. , , .
2. , .
3. , .
4. ,
.
5. .
6. , .
, " ", . 12.14.
Checkout "" . 12.10,.

410 12. JSP

H l l case_study
- Cj graphics
CJ Web-inf
3 i" 1 classes
3 - 3 action
_J events
j" I actions

H Cj beans
CJ tags

validate-account

NewAccountAction
ValidateAccountAction
QueryAccountAction

] app

- email
Cj html

CJ idbc
:

- -i:"'"} logic
1 regions
I secuiity
' 1 tokens
LJ util
-CJ ml
j jsp
- accountCreated- - "
checkout
Ci createAccount - - - homepage
- C J login
- loginFailed
{? purchase

-Q shared
-^"1 showHint
C3 storefront
C3 templates
J lids
jutii
Java

$ JSP

. 72. /4. , "


"
12.10,a. /WEB-INF/jsp/checkout/page.j
<%@ taglib uri='security' prefix='security'%>
<%@ taglib uri='regions' prefix='region' %>
<security:enforceLogin

411

loginPage=' /WEB-INF/jsp/login/page.jsp'
errorPage='/WEB-INF/jsp/loginFailed/page.jsp'/>
<region:render region='CHECKOUT_REGION'/>

s e c u r i t y : enforceLogin, 12.10,, 12.10,6.


12.10,6. /WEB-INF/jsp/classes/tags/security/
EnforcaLoginTag. java ()
package tags.security;
public class EnforceLoginTag extends TagSupport
implements Constants {
private String loginPage, errorPage;
public int doEndTag() throws JspException {
HttpSession session = pageContext.getSessionf);
HttpServletRequest req = (HttpServletRequest)pageContext.
getRequest();
String protectedPage - req.getServletPath();
if(session.getAttribute(USER_KEY} = null} (
session.setAttribute(LOGIN_FAGE_KEY,
loginPage);
session.setAttribute(ERROR_PAGE_KEY,
errorPage);
session.setAttribute(PROTECTED_PAGE_KEY, protectedPage);

try {
pageContext.forward(loginPage);
return SKIP_PAGE;
)
catch(Exception ex) (
throw new JspException(ex.getMessage());
}

return EVAL_PAGE;

s e c u r i t y : enforceLogin , User
; , . 12.10,.
12.10.. /WEB-INF/jsp/login/content.jsp
<%@ page contentType-'text/html; charset=UTF-8' %>
taglib uri-'il8n' prefix='il8n' %>

412

12. JSP

<font size='5' colr='blue' >


<il8n:message
key='login.form.title'/>
</fontxhr>
f

<jsp:include page=' form.jsp' flush= true'/>


<jsp:include page='../shared/createAccountLink.jsp'

flush-'true'/>

JSP- JSP-. , form, jsp,


JSP-. form, jsp 12.10,.
form, jsp content. j sp JSP- createAccountLink. j sp, 12.10,.
12.10,, /WEB-INF/ jep/shared/createAccountLmk. jsp
taglib u r i = ' i l 8 n ' prefix='U8n' %>
<%@ taglib u r i = ' u t i l i t i e s ' p r e f i x = ' u t i l ' %>
<i!8n:message base^'app' key='click'/>
<a href='<util:encodeURL url="query-account-action.do"/>' >
<il8nmessage base='app' key='here'/></a>
<il8n:message base='app' key=' password.hint.toOpenAccount'/>

createAccountLink. jsp query-accountaction . do. . 12.15.


] FnjtSlmd.com - Internet E xpltmt
file

dit

ilgw
hllp.//loealhml:8080/case-study/ched(Oi-*c<en*7

FruitStand.com
Piease Login
Name
Password |~
login |
click d e l i open a new account.

Thanks for slopping by Today is Monday, Match 12, 2001.

Done

. 12.15. Web-

413

, createAccountLink. j ,
query-account-action.do, QueryAccountAction. Que r yAccount Act ion 12.10..
12.10,. AJEB-INF/claaees/QueryAccountAction.java
package actions;
import
import
import
import

javax.servlet.ServletException;
javax.servlet.http.HttpServlet;
javax. servlet .http.HttpServletRequ.est;
javax.servlet.http.HttpServletResponse;

import action.ActionBase;
import action.ActionRouter;
public class QueryAccountAction extends ActionBase ^
public QueryAccountAction() {
// J5P-
//
hasSensitiveForms = true;
}
public ActionRouter perform (HttpServlet servlet,
HttpServletRequest req,
HttpServletRe spoils e res)
throws ServletException (
return new ActionRouter("query-account-page");
)
\

QueryAccountAction.perform
.
query-account-page. , JSP- , . , t r u e hasSensitiveForms
{ ). .
query-account-page /WEB-INF/ j sp/
createAccount/page.jsp. / WEBINF/ jsp/createAccount/content. j sp, 12.10,.
12.10,. /-lNF/jsp/createAccount/content. jap
page contentType='text/html; eharset=UTF-8' %>
<form aotion='validate-account.jsp' method='post' >
<table width='450'><tr>

414

12. JSP

</table>
<br>
<input type='submit' value='create account'>
</form>
JSP- ,
( 12.11,). ^-, 12.10,,
. 12.16.
-Maud) Eislrr
tlp

&
Slop

**

4
Hen

n
Sts*

fo*

FruitStand.com
Open a New Account
Personal Information
First Name

[Jneseph

Las) Name

JLacaite

Street Ad die s 5

|S9113W OekLane

City

tWestctiesler

Slate
Counlry
Phone Number
Credit Card Information
Credit Card Type

| Discovery

Card Numb
Erpirarron Dste
Userrsarrie And Password
User Name

Confirm sword
Password Him |rrry dog's name
treeie

Thanks (or stopping by. Tndy is *tomftc, Msrcft 5, 2001.

. 12.16.

415

, . 12.16, . a c t i o n
v a l i d a t e - a c c o u n t , jsp,
create account . JSP 12.10,.
12.10,. /validate-sccount.jep
<jsp:useBean id='form' scopes'request'
class=' beans.app.forms.CreateAccountForm'/>
<jsp:setFroperty name='form' property^'*'/>
<jsp:forward page='/validate-account-action.do'/>

JSP- bean CreateAccountForm , . 12.16.


; . JSP-, 12.10,,
v a l i d a t e - a c c o u n t - a c t i o n . d o , , 12.10,.
12.10,3. /WEB-INF/claaaes/actions/ValidateAccountAction. Java

{)
package actions;
public class ValidateAccountAction extends ActionBase
implements beans.app,Constants {
public ActionRouter perform(HttpServlet servlet,
HttpServletRequest req,
HttpServletResponse res)
throws ServletException {
CreateAccountForm form = (CreateAccountForm)
req.getAttribute("form");
boolean errorDetected - false;

return ercorDetected ?
new ActionRouter("query-account-page") :
new ActionRoutert"/new-account-aetion,do",

true,

false);

ValidateAccountAction , ;
query-account-page, , . 12.16,
. , new-account-action.do, ,
12.10,.

416

12. JSP

12.10,. /-rNF/clasaes/actions/HewAeaountAetion. j
package actions;
import
import
import
import
import

javax.servlet.ServletException;
javax.servlet.http.HttpServlet;
javax.servlet.http.HttpSession;
javax.servlet.http.HttpServletRequest;
javax.servlet.http.HttpServletResponse;

import beans.app.User;
import beans.app.Users;
import action.ActionBase;
import action.ActionRouter;
public class NewAccountAction extends ActionBase
implements beans.app.Constants (
public NewAcccuntAction[) {
isSensitive = true; //
}
public ActionRouter perform(HttpServlet servlet,
HttpServletRequest req,
HttpServletResponse res)
throws ServletException {
Users users - (Users)servlet.getservletcontext().
getAttribute(USERS_KEY);
if(users == null) {
throw new ServletException("Users not found " +
"in application scope");

J
HttpSession session = req.getSession();
String
String
String
String
String
String

firstName =
lastMame =
address

city
state
=
country
=

String
String

creditCardType - req.getParameter("creditCardType");
creditCardNumber =
req.getParameter("creditCardMumber");
creditCardExpiration =
req.getParameter("creditCardExpiration");

String

req.getParameter("firstName");
req.getParameter("lastName");
req.getParameter("address");
req.getParameter("city");
req.getParameter("state");
req.getParameter("country");

String
String

uname = req.getParameter("userKame");
pwd
= req.getParameter("password");

String
String

pwdConfirm = req.getParameter("pwdConfirm");
pwdHint
= req.getParameter("pwdHint"};

session.setAttribute{USERNAME_KEY, uname);
session.setAttribute(PASSWORD_KEY, pwd);

417

users.addUser(
new User{firstName, lastKame, address, city, state,
country, creditCardType, creditCardNumber,
creditCardExpiration, uname, pwd, pwdHint,
"customer")); // customer
req.setAttribute(USERNAME_KEY, uname);
return new ActionRouter("account-created-page");

NewAccountAction, 12.10,, ,
;
, .
,
, , . , , 12.10,. account-created-page. JSP- 12,10,.
12.10,. /WEB-iNF/jep/aceraviritcrested/content, jsp
<%@ page contentType='text/html; charset=UTF-8' %>
<%@ taglib uri='il8n' prefix='il8n' %>

<font size='4' color='blue'>


<il8n:message base='app' key='accountCreated.text'/>
</font>
<pxjsp:include page='../login/form.jsp'

flush' t r u e ' /></p>

JSP-, 12.10,, ,
, JSP-, . 12.10,.
12.10,. /WEB-INF/jsp/login/form, jsp
<%8 page contentType='text/html; charset=UTF-8' %>
taglib uri='il8n' prefix='
<4@ taglib uri='utilities' prefix='util' %>
<form action='<%= response.encodeORL("authenticate") %>'
method='post'>
<table>
<tr>
<tdxil8n: message base=' app' key=' login, text field, name' />

418

12. JSP
</td>

<tdxinput type=' text' name=' userName'


value='<util:sessionAttribute property=
"<%= beans.app.Constants.USERNAME_KEY %>"/>'/>
</td>
</tr><tr>
<tdxil8n:message base='app' key='login.textfield.pwd'/>
</td>
<tdxinput type='password' name='password' size='8'
value='<util:sessionAttribute property=
<%= beans.app.Constants.PASSWORD_KEY %>"/>'/>
</td>
</tr>
</table>
<br>
<input type='submit' valuer
'<ilBn:message key="login.button.submit"/>'/>
</form>
, 12.10., . , , , ,
, , ,
. NewAccountAction, 12.10,,
.
a c t i o n a u t h e n t i c a t e ;
web.xml A p p A u t h e n t i c a t e S e r v l e t . A p p A u t h e n t i c a t e S e r v l e t 12.10,.
12.10,-/WEB-lNF/claases/AppAuthenticafceServlet.Java
import javax.servlet.ServletContext;
import beans.app.Users;
import beans.app.User;
public class AppAuthenticateServlet extends AuthenticateServlet
implements beans.app.Constants,
tags.jdbc.Constants {
public Object getUser(String username, String password) [
ServletContext ctx = getServletContext();
Users users = (Users)ctx.getAttribute(USERS_ECEY);
return users.getUser(username, password};

A p p A u t h e n t i c a t e S e r v l e t
A u t h e n t i c a t e S e r v l e t g e t U s e r . , , , g e t U s e r
User, n u l l . A u t h e n t i c a t e S e r v l e t 12.10,.

12.10,, /WEB-lNF/claases/AuthenticateServlet.Java
import
import
import
import
import
import

javax.servlet.ServletException;
javax.servlet.http.HttpServlet;
javax.servlet.http.HttpServletRequest;
javax.servlet.http.HttpServletResponse;
j avax.servlet.http.HttpSession;
Java.io.lOException;

public abstract class AuthenticateServlet extends HttpServlet


implements beans.app.Constants,
tags.security.Constants (
abstract Object getUser(String username, String pwd);
public void service(HttpServletRequest req,
HttpServletResponse res)
throws lOException, ServletException {
HttpSession session = req.getSession();
String
uname
= req.getParameter("userNarae");
String
pwd
= req.getParameter("password");
Object
user
= getUser(uname, pwd) ;
session.setAttribute(USERNAME_KEY, uname);
session.setAttribute(PASSWORD_KEY, pwd);
if(user -= null) { //
String loginPage = (String)session.
getAttribute(LOGIN_PAGE_KEY);
String errorPage = (String)session.
getAttribute(ERROR_PAGE_KEY);
String forwardTo = errorPage != null ? errorPage :
loginPage;
session.setAttribute(LOGIN_ERROR_KEY,
"Username: " + uname + " and " +
"Password: " + pwd + " are not valid.");

getServletContext(}.getRequestDispatcher(
res.encodeURMforwardTo)).forward(req,res);

else ( //
String protectedPage = (String)session.
getAttribute(FROTECTED_PAGE_KEY);
session.removeAttribute(LOGIN_PAGE_KEY);
session.removeAttribute(ERROR_PAGE_KEY);
session.removeAttribute(PROTECTED_PAGE_KEY);
session.removeAttribute(LOGIN_ERROR_KEY);
session.setAttribute(USER_KEY, user);
getServletContext().getRequestDispatcher(
res.encodeURL(protectedPage)).forward(req,res);

419

420 12. JSP


A u t h e n t i c a t e S e r v l e t ,
6, , , 12.10,, , . s e r v i c e
, ,
^' , /WEB-INF/jsp/
checkout/page, jsp, 12.10,. , User ,
.

HTML-
Web-
, HTML-. , .
3. ,
, .
. 12.16,
, , 12.11,.
12.11,a. /WBB-INF/jsp/createAccount/contenfc.jap
<%@ page contentType='text/html; charset=UTF-8' %>
<%@
<%@
<%@
<%@

taglib
taglib
taglib
taglib

uri='application'
uri='il8n'
uri='tokens'
urA='utilities'

<jsp:useBean id='form'

prefix='app'
prefix='ilBn'
prefix='tokens'
prefix=futil'

%>
%>
%>
%>

scope='request'
class-'beans.app.forms.CreateAccountForm'/>

<font s i z e - ' 5 ' color-'blue'><u>


<il8n:message key-'createAccount.header.title'/></u>
</fontXp>
<% String error = (String)request.getAttribute[
"createAccount-form-error");
i f ( e r r o r !- null) { %>
<font size='5' colors'red'>
<il8n:message key-'createAccount.error.fix'/>
</fontxfont size='4' color='red'>
<%= error %></p></font>
<%
request.removeAttribute["createAccount-form-error");
} %>

<form action='validate-account.jsp' method='post' >


<table width='450'><tr>
<td colspan='2'xfont size='4' colors'blue'>
<il8n:message key='createAccount.header.personal'/>
< / f o n t x / t d x / t r x t r height=' 10' ></t>

HTML-

<trxtd>
<il8n:message key=' createAccount.field.firstNaroe'/></td>
<tdxinput type=' text' name=' firstName'
value='<%= form.getFirstNameU %>'/>
</tdx/tr>
<trxtd>
<il8n:message key=' createAccount.field.lastName'/></td>
ctdxinput type-' text' name=' lastName'
valuer'<%= form.getLastNameO %>' />
</tdx/tr>
<trxtd>
<il8n:message key=' createAccount.field.address' /></td>
<tdxinput type='text' name='address' size='39'
value='<%- form.getAddress() %>'/>
</td></tr>
<trxtd>
<i!8n:message key=' createAccount.field.city'/></td>
<td><input type='text' name=' city'
value='<*= form.getCity () !>'/>
</tdx/tr>
<trxtd>
<il8n:message key='cteateAccount.field.state'/></td>
<tdxinput type='text' name=' state'
value='<%= form.getstatet) %>'/>
</tdx/tr>
<tr><td>
<il8n:message key=' createAccount. field, country' /x/td>
<tdxselect name='country'>
<il8n;bean id='germany'
createAccount.option.germany'/>
<option <%=form.getCountrySelectionAttr(germany)%>/>
<l= germany %>
<il8n:bean id='uk'
key='createAccount.option.unitedKingdom'/>
<option <%=form.getCountrySelectionAttr(uk)%>/>
<%= uk %>
<il8n:bean id='china' key='createAccount.option.china'/>
<option <%=forra.getCountrySelectionAttr(china)%>/>
<%= china %>
</selectx/tdx/tr>
<trxtd>
<il8n:message key=' createAccount. field, phone' /x/td>

421

422 12. JSP


<td><input type='text' name=' phone'
value='<%= form.getState() %>'/></td>
</trXtr height='20'x/tr>
<trxtd colspan='2'xfont size='1' color='blue'>
<ilBn:message key='createAccount.header.credit'/x/td>
</fontx/tdx/tr><tr height=' 10' ></tr>
<trxtd>
<il8n:message
key=' createAccount. field.creditCardType' /x/td>
<td><select name=' creditCardType' >
<option <%= form.getCreditCardTypeSelectionAttr(
"Discover") %
Discovery
<option <%= form.getCreditCardTypeSelectionAttr(
"Master Card") %
Master Card
<option <%= form.getCreditCardTypeSelectionAttr(
"Visa") %
Visa
</selectx/tdx/tr>
<trxtd>
<il8n:message
key=' createAccount. field. creditCardNumber' /x/td>
<tdxinput type=' text' name=f creditCardNumber'
value='<%= form.getCreditCardNumber() %>'/>
</td>
</tr></tr>
<trxtd>
<il8n:message
key='createAccount.field.creditCardExpiration'/></td>
ctdxinput type=' text' name=' creditCardExpiration'
value='<%= form.getCreditCardExpirationO %>'/>
</td>
</trxtr height='2O'x/tr>
<trxtd colspan='2'xfont size=M' color='blue'>
<il6n:message
key='createAccount.header.unameAndPwd'/></td>
f
</font></tdx/trxtr height=' 10 x/tr>
<tr><td>
<il8n:message
key=' createAccount. field.username' /x/td>
<td><input type=f text' name='userHame'
value='<%= form.getUserNameO %>'/></td>
</tdx/tr>
<trxtd>
<ilSn:message
key=' createAccount. field, pas sword' /x/td>
<tdxinput type='password' name='password' size=' 8'
value='<S= forro.getPasswordO %>' /></td>

HTML-

423

</tdx/tr>
<trxtd>
<il8n:message
key='createAccount.field.pwdConfirm' /></td>
f
<td><inpirt type='password' name= pwdConfirm' size='8'
value='<%= form.getPwdConfirm() %>'/></td>
<tr><td>
<il8n:message
key='createAceount.field.pwdHint'/></td>
<td><input type='text' name='pwdHint'
value='<%= form.getPwdHint() %>'/></td>
</td>
</tr>
<7table>
<br>
<input type='submit' value='create account'>
<tokens:token/>
</form>

JSP-, 12.11,, bean


CreateAceount Form . , JSP- , .
, 12.11,, createAceount-form-error,
. , Web- .
a c t i o n JSP-,
bean CreateAccountForm,
, . 12,,. 12.11,6.
12.11,6. /validate-aecount.j ep
<jsp:useBean id='form' scope='request'
class=' beans.app.forms.CreateAccountForm'/>
<jsp:setProperty name='form' property^'*'/>
<j sp:forward page='/validate-account-action.do'/>

JSP- /validate-account.jsp validateaccount-action. do, , 12.11,.


12.11,. /WEB-lNF/classes/aetions/ValidateAccountAetion
package actions;
import Java,io.lOException;
import
import

javax.servlet.ServletException;
javax,servlet.http.HttpServlet;

424

12. JSP

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import action.ActionBase;
import action.ActionRouter;
import beans.app.forms.CreateAccountForm;
public class ValidateAccountAction extends ActionBase
implements beans.app.Constants {
public ActionRouter perform(HttpServlet servlet,
HttpServletRequest req,
HttpServletResponse res)
throws ServletException {
CreateAccountForm form = (CreateAccountForm)
req.getAttribute("form");
if(form null) {
throw new ServletException("Can't find form"};
;

String errMsg;
boolean errorDetected = false;
if(!form.validate!)) [
errMsg - form.getValidationError();
errorDetected = true;
req.setAttributef'createAccount-form-error", errMsg);
}
return errorDetected ?
new ActionRouter("query-account-page") :
new ActionRouter("/new-account-action.do", true, false);

, 12.11,,
v a l i d a t e . false, .. , query-account-page, 12.11,.
bean CreateAccountForm 12.11,.
12.11,. /WEB-INF/classes/beans/app/forms/
Great Account Form.
package beans.app.forms;
import
import
import
import

beans.html.NameElement;
beans.html.OptionsElement;
beans.html.TextElement;
beans.html. ValidatedElement,-

public class CreateAccountForm implements ValidatedElement {


private NameElement firstName = new NameElement("First Name");
private NameElement lastName = new NameElement("Last Name");
private TextElement
address = new TextElement (),-

HTML-
private
private
private
private
private
private
private
private
private

TextElement
TextElement
TextElement
TextElement
TextElement
TextElement
TextElement
TextElement
TextElement

city
state
phone
creditCardNumber
creditCardExpiration
userName
password
pwdConfirm
pwdHint

private OptionsElement
private OptionsElement

=
=
=
=
=
=
=
=
=

new
new
new
new
new
new
new
new
new

TextElement()
TextElement()
TextElement()
TextElement()
TextElement()
TextElement()
TextElement()
TextElement()
TextElement()

creditCardType = new OptionsElement ()


country = new OptionsElement(]

private String error "";


public
public
public
public
public
public
public
public

String getFirstName()
( return firstHame.getValue();}
String getLastName()
return lastName.getValue(); }
return address.getValue(); }
String getAddressO
return city.getValue();
}
String getCity()
return state.getValue();
}
String getState ()
return country.getValue(); )
String[] getCountry()
return phone.getValue{);
}
String getPhoneI
{ return creditCardType.
String!] getCreditCardType
getValue (); )
public String getCreditCardNumber() { return creditCardNumber.
getValue(}; }
public String getCreditCardExpiration() (
return creditCardExpiration.getValue();
public
public
public
public

String
String
String
String

getUserName()
getPassword()
getPwdConfirmf)
getPwdHintf)

{
{
{
{

return
return
return
return

userName.getValue(); }
password.getValue(); }
pwdConfirm.getValue();,
pwdHint.getValue();}

public String getCountrySelectionAttr(String s) {


return country.selectionAttr(s);
}
public String getCreditCardTypeSelectionAttr(String s)
return creditCardType.selectionAttr(s);
public
public
public
public
public
public
public
public

void
void
void
void
void
void
void
void

setFirstName(String s) { firstName.setValue (s);


setLastName[String s] { lastName.setValue(s);
set&ddress(String s)
i address.setValue(s);
setCity(String s)
{ city.setValue(s);
setState(String s)
I state.setValue(s);
setCountry(String ] s) ( country.setValue(s);
setPhone(String s
\ phone.setValue(s);
setCreditCardType(StringT] s) [ creditCardType.
setValue(s)i ]
public void setCreditCardNumber(String s) ( creditCardNumber,
setvalue(s); }
public void setCreditCardExpiration(String s) (
creditCardExpiration.setValue (s);
1

425

426

12. JSP

public
public
public
public

void
void
void
void

setUserName(String s)
setPasswordiString s)
setPwdConfirm{String s)
setPwdHint(String s)

(
(
{
(

userName.setvalue(s);
)
password.setvalue(s);
)
pwdConfirm.setValue(s); )
pwdHint.setvalue(s);
}

public boolean validate() {


error = "";
if(!firstName.validate()) (
error += firstName.getValidationError();

iff ilastName.validate()) f
if {error.length!) > 0)
error += "<br>";
error += lastName.getValidationError();
}
return error == "";
}
public String getValidationError() {
return error;
}
}
bean ,
. .
bean . ,
v a l i d a t e , , .
.
, 12.11,, , , NameElement.
NameElement 3.
12.11,.
12.11,. /WEB-INF/classes/beans/html/NameElement.Java

package beans.html;
public class NameElement extends TextElement {
String error, fieldName;
public NameElement(String fieldName) {
this.fieldName = fieldName;
}

public boolean validate() {


boolean valid = true;
String value = getValuef);
error = " " ;
if{value.length() == 0) {
valid = false;

427

error = fieldName + " must be filled in";


)
else {
for(int i=0; i < value.length(); ++i) (
char - value.charAt(i);

)
I

if(c == ' ' || (c > '0' & < "9')) {


valid = false;
if <c == l M
error = fieldKame + " cannot contain spaces";
else
error = fieldName + " cannot contain digits";
}

return valid;

public String getValidationErrorO {


return error;
t

NameElement TextElement
v a l i d a t e .
. NameElement TextElement
3.


Web- , . 7. , 12.11,.
, , QueryAccountAction
, JSP-, .
package actions;
public class QueryAccountAction extends ActionBase {
public QueryAccountAction() {
// JSP
// ,
hasSensitiveForros = true;

(
QueryAccountAction) Model 2
( ). , . -

428

12. JSP

Model 2 ,
. , , .
Back.
NewAccountAction, ,
, , .
package actions;
public class NewAccountAction extends ActionBase
implements beans.app.Constants {
public NewAccountAction() {
isSensitive - true; II
\

I
, 12.11,, tokens:token, , , , .
12.11 ,. /WEB-INF/jap/creat*Account/content. jep ()
<%@ page contentType-'text/html; charset=UTF-8' %>
...
<%@ taglib uri= f tokens' prefix='tokens' %>
<form action='validate-account.jsp' method='post' >
<tokens:token/>
</form>

SSL
, Web (SSL) {, ).
SSL , -, ,
SSL. ,
SSL . Tomcat 3.2 final SSL $TOMCAT_HOME/doc/tomcat-ssl-howto.html.
-, , SSL { , JSP). web.xml. , web.xml, , , :

XML DOM 429


<security-constraint>
<web-resource-collection>
<web-reaource-name>Credit Card Page</web-resource-naine>
<url-pattern>
/WEB-INF/jsp/createAccount/content.jsp
</url-pattern>
</web-resource-collection>
<user-data-constraint>
<transport-guarantee>CONFIDENTIAL</transpoi:t-guarantee>
</user-data-constraint>
</security-constraint>
, SSL /WEB-INF/jsp/
c r e a t e A c c o u n t / c o n t e n t . j sp. , , 9.
, Tomcat S.2 final, Tomcat
4.0 . , , , Tomcat 4.0 .

XMLMDOM
, Web-, XML. -, Document Object Model (DOM) ,
. -, XML de facto -.
XML JSP 11.
XML , ,
, "",
; .
12.12, ,
DOM XML-,
12.12,a. /WEB-INF/ jep/atoref r on t/con ten t . jep (DOM-)
page contentType='text/html; charset-UTF-8' *>
r

taglib uri- il8n' prefix='il8n' %>


taglib uri='dom' prefix='dom' *>
<%@ taglib uri-'html' preCix='html' %>
<font size-M' color-'blue'>
<il8n:message base-'app' key='storefront.form.title'/>
</fontxp>
<dom:parse id='inventory' scope='application'>

430

12. JSP

<%@ include file='inventory-to-xml.j sp' %>


</dom:parse>
<table border='l' cellPadding='3'>
<th><il8n:message base='app'
key-'storefront.table.header-picture' /></th>
<thxil8n:message base-'app'
key-'storefront.table.header.item'/></th>
<th><il8n:megsage base='app'
key=' storefront.table.header.description'/></th>
<thxil8n:message base=' app'
key='storefront.table.header.price'/></th>
<thxil8n:message base=' app'
key='storefront.table.header.addToCart'/></th>
<% String currentltem = null, currentSku = null; %>
<dom:iterate node='<%=inventory.getDocumentElement()&>' id='item' >
<dom:iterate node='<%= item %>' id='itemField'>
<dom:ifNodeNameEquals node='<%= itemField !>' names='SKU'>
<dom:elementValue id='name' element='<%= itemField %>'/>
<% currentSku name; l>
<trxtd>
<img src=
'<%= "graphics/fruit/" + name.trim() + ".jpg" %>'/>
</td>
</dom:ifNodeNameEquals>
<dom:ifWodeNameEquals node='<%= itemField %>' names='NAME'>
<dom:elementValue id='name' element='<%= itemField %>'/>
<% currentltem = name; %>
<td><%= name %></td>
<td>
<il8n:message key='<%=name + ",description"%>'/>
</td>
</dom:ifNodeMameEquals>
<dom:ifNodeHameEquals node='<%= itemField %>' names='PRICE'>
<dom:elementValue id='price' element-'<%= itemField %>'/>
<td>$Snbsp;<%= price %>bnbsp;/lb.</td>
<td>
<form action='add-selection-to-cart-action.do'>
<html:links name='<= currentSku + "-" +
currentltem + "-" + price %>'>
<option value- 0.00'>0.00</option>
<option value= 1.00'>l.00</option>
<option value= 1.50'>1.50</option>
<option value= 2.00'>2.00</option>
<option value= 2.50'>2.50</option>
<option value= 3.00'>3.00</option>
<option value= 3.50'>3.50</option>
<option value= 4 . 0 0 4 .00</option>
<option value= 4.50'>4.50</option>
<option value= 5.00'>5.00</option>

XML DOM 431


<option valuer's.50'>5.50</option>
</html:links>
</form>
</td>
</dom:ifNodeNameEquals>
</dom:iterate>
</dom:iterate>
</table>
JSP-, 12.12,, DOM-,
, .
dom:parse, 12.12, XML-.
inventory-to-xml. j sp, 12.12,6.
12.12,6. /WEB-lHP/jsp/storefront/invantory-to-xml.jsp
<%@ taglib url='database' prefix='database' %>
<database:query id='inventory'
SELECT * FROM Inventory
</database:query>

scope='session'>

<?xml version="1.0" encoding="ISO-8859-l"?>


<FRUITS>
<database:rows quecy='inventory'>
<ITEM>
<database:columns query='inventory' columnName='name'
columnValue=' value' >
<%= "<" + name + ">" %>
<%= value %>
<%= </ + n a m e + >- fc>
</database:columns>
</ITEM>
</database:rows>
</FRUITS>
<database:release query='inventory'/>
JSP-, 12.12,6,
, .
10. JSP- XML-,
dom: p a r s e ( 12.12,).
JSP- , XML- .
.

432

12. JSP

, , . ,
, , , www.phptr.com/advjsp, .

Servlet 2.3. Servlet 2.3 , , , ,


, . , , Resinl.3;
Resin www. c a u c h o . com.
, Servlet 2.3,
JSP . , , , XSLT- ..
Septet 2.3
JSP. , ,
,
. ( enf o r c e L o g i n 9.)
< % JSP- % >
<%@ taglib uri-'/WEB-lNF/tlds/seeurity.tld'
prefix='authenticate' >
<authenticate:enforceLogin loginPage='login.j sp'/>
, e n f o r c e L o g i n
JSP- . .
,
JSP-.
,
; .
, , , URL. , .

436

*- doRtterfServletReqjest, ServerResponce, FilterChain)


* service (ServletRequest, ServerResponce)
. . 1.

,
s e r v i c e . ,
, ,
. , . . , , , s e r v i c e .
;
,
. , .
.
1. .
2. .


, ,
. , JSP- . , . . .2 , , .

fill

ellt

lw

Fffforltes

Toots

tttt>

http: //localhatt: SOSO/Fiher*/


-

You ace not authorized to access this resource.

. .2.

437


. .
.1.
<?xml version="1.0" encoding-"ISO-8859-l"?>
<!DOCTYPE web-app
PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://Java.sun.com/j2ee/dtds/web-app_2_3.dtd">
<web-app>
<filter>
<filter-name>Authenticate Filter</filter-name>
<filter-class>filters.AuthenticateFilter</filter-class>
</filter>
<filter-mapping>
<fiIter-name>Authenticate Filter</filter-name>
<url-pattern>*.jsp</url-pattern>
</filter-mapping>
<welcome<welcome-file>tndex.jsp</welcome</welcome-file-list>
</web-app>
, , . , JSP-.
, ,
.2.
.2. /WEB-INF/clas/filters/AuthenticateFilter.Java
package filters;
import
import
import
import
import
import

Java.io.PrintWriter;
javax.servlet.ServletRequest;
javax.servlet.ServletResponse;
javax.servlet.Filter;
javax.servlet.FilterConfig;
javax.servlet.FilterChain;

import javax.servlet.http.HttpServletRequest;
public class AuthenticateFilter implements Filter {
private FilterConfig config;
public void setFilterConfig(FilterConfig config) {

438

this.config = config;
}
public FilterConfig getFilterConfig() {
return config;
public void doFilter(ServletRequest request,
ServletResponse response,
FilterChain chain)
throws java.io.IOException,
javax.servlet.ServletException {
if(((HttpServletRequest)request).isUserlnRole("resin")) {
chain.doFilter(request, response);
}
else {
response.getWriter().write("You are not authorized " +
"to access this resource.");

, .2, , javax . s e r v l e t . F i l t e r . d o F i l t e r , F i l t e r C h a i n . d o F i l t e r . , r e s i n . d o F i l t e r .
. ,
. s e t F i l t e r C o n f i g ,
F i l t e r , i n i t , , destroy getFilterConfig.

, Servlet API.
, URL,
, JSP-, HTML- XML-.
.
, ,
.
.

-
.

Java Server Pages.


,
.,
..
JI.A. , .. Mutuyi
..

"",
101509, , . , . 43, . 1.
, . N 090230 23.06.99
.

26.04.2002. 70x100/16.
NewBaskerville. .
. . . 33,6. .-. . 20,00.
3000 . 424.
" "
,
.
197110, -, ., 15.


http://www.natahaus.ru/

!
,

.


,
.

.


.


,

,
,
e-mail -

Вам также может понравиться