JSPBasics
JSPBasics
Even though Sang Shin and Sameer Tyagi are full-time employees of Sun Microsystems, the contents here are created as their own personal endeavor and thus does not reflect any official stance of Sun Microsystems. Sun Microsystems is not responsible for any inaccuracies in the contents. Acknowledgments
arge portion of slides, speaker notes, and e!ample code of this presentation are created from "#S$% section of #ava &S'$ tutorial written by Stephanie (odoff of Sun Microsystems Many slides are borrowed from "Servlet)#S$% codecamp material authored by 'oris *hen of Sun Microsystems Some e!ample codes and contents are borrowed from "*ore Servlets and #avaServer $ages% book written by Marty +all
2
Revision History
,-)-.)-//-0 version , created by Sameer Tyagi /,),-)-//10 version - revised by Sang Shin with speaker notes /2),1)-//10 version 1 revised 3Sang Shin4
Sub-topics of JSP
Sub-topics of #S$
#S$ (asic #ava(eans for #S$ *ustom tags #S$ Standard Tag ibrary 3#ST 4
&e will deal with only the first two topics in this session
M5* 3Model-5iew-*ontroller4 $attern Model - 6ramework Apache Struts #ava Server 6aces 3#S64 7ther frameworks
Agenda
#S$ in big picture of #ava EE 8ntroduction to #S$ ife-cycle of #S$ page Steps for developing #S$-based &eb application 'ynamic contents generation techni9ues in #S$ 8nvoking #ava code using #S$ scripting elements #ava(eans for #S$ Error handling 7
Static contents
Typically static +TM page Same display for everyone *ontents is dynamically generated based on conditions *onditions could be
'ynamic contents
>ser identity Time of the day >ser entered values through forms and selections Etrade webpage customi?ed ;ust for you, my @ahoo
10
E!amples
11
A te!t-based document capable of returning both static and dynamic content to a client browser Static content and dynamic content can be intermi!ed Static content
+TM , <M , Te!t #ava code 'isplaying properties of #ava(eans 8nvoking business logic defined in *ustom tags
'ynamic content
12
13
"utput
14
#S$ Serv!ets
HTML code in Java B Not easy to aut or
B B
JSP
Java-!i"e code in HTML B #ery easy to aut or B $ode is co%pi!ed into a serv!et
15
#S$ (enefits
*ontent and display logic are separated Simplify web application development with #S$, #ava(eans and custom tags Supports software reuse through the use of components 3#ava(eans, *ustom tags4 Automatic deployment
17
Co, you want to use both leveraging the strengths of each technology
8n a typically production environment, both servlet and #S$ are used in a so-called M5* 3Model-5iew-*ontroller4 pattern
JS Arc#itecture
19
20
JSP
presentation <html <bod" <ora$ loop name %order! .. <&ora$loop <bod" <&html
JavaBeans
isOrderValid( )
$usiness logic
saveOrder( )
21
JS Arc#itecture
22
Execute Servlet
24
JS
25
(ranslation)!ompilation #ase
#S$ files get translated into servlet source code, which is then compiled 'one by the container automatically The first time #S$ page is accessed after it is deployed 3or modified and redeployed4 6or #S$ page "pageCame%, the source code resides
26
(ranslation)!ompilation #ase
Static Template data is transformed into code that will emit data into the stream #S$ elements are treated differently
'irectives are used to control how &eb container translates and e!ecutes #S$ page Scripting elements are inserted into #S$ pageDs servlet class Elements of the form E;sp0!!! ...)G are converted into method calls to #ava(eans components
27
28
-nitiali.ation o& a JS
age
'eclare methods for performing the following tasks using #S$ declaration mechanism
Aead persistent configuration data 8nitiali?e resources $erform any other one-time activities by overriding ;sp8nit34 method of #sp$age interface
29
/inali.ation o& a JS
age
'eclare methods for performing the following tasks using #S$ declaration mechanism
Aead persistent configuration data Aelease resources $erform any other one-time cleanup activities by overriding ;sp'estroy34 method of #sp$age interface
30
+,ample0 initdestroy12sp
&'( page i%port)*database+,* '&'( page errorPage)*errorpage+.sp* '&'-- /ec!are initia!i0ation and fina!i0ation %et ods using JSP dec!aration -'&'1 private Boo"/B23 boo"/B234 pub!ic void .sp5nit() 6 77 retrieve database access ob.ect8 9 ic 9as set once per 9eb app!ication boo"/B23 ) (Boo"/B23)getServ!et$onte:t()+get2ttribute(*boo"/B*)4 if (boo"/B23 )) nu!!) Syste%+out+print!n(*$ou!dn;t get database+*)4 < pub!ic void .sp/estroy() 6 boo"/B23 ) nu!!4 <
31
33
*reate development tree structure &rite either servlet code and)or #S$ pages along with related helper code *reate build.!ml for Ant-based build 3and other application life-cycle management4 process
34
facilitate iterative development build.!ml0 Ant build file conte!t.!ml0 7ptional application configuration file src0 #ava source of servlets and #ava(eans components web0 #S$ pages and +TM pages, images
35
Aoot directory
hello, directory 3from #ava EE ,.. tutorial4 web directory duke.waving.gif inde!.;sp response.;sp &E(-8C6 directory web.!ml build.!ml 3it does not have src directory since this does not use any #ava classes as utility classes4
36
+TM pages
E!ample0 duke.waving.gif
37
'eployment descriptor contains deployment time runtime instructions to the &eb container
38
Either I.&AA file or unpacked form of I.&AA file (uild process is made of
create build directory 3if it is not present4 and its subdirectories copy I.;sp files under build directory compile #ava code into build)&E(-8C6)classes directory copy web.!ml file into build)&E(-8C6 directory copy image files into build directory
40
+ello web directory build.!ml build directory &E(-8C6 directory classes directory web.!ml duke.waving.gif greeting.;sp response.;sp
41
(y asking Tomcat Manager via sending a command to it 3Tomcat Manager is ;ust another Servlet app that is always running4 ant install ant deploy (y manually copying files to TomcatDs webapps directory and then restarting Tomcat
42
@ou need proper credential to perform this This is why you need build.properties file with proper userid and password, otherwise you will e!perience +TT$ ./, error ant install for temporary deployment ant deploy for permanent deployment *opying I.war file or unpacked directory to EtomcatinstallG)webapps) directory manually and then restart Tomcat
43
Manual Method
http0))localhost0K/K/)hello-)greeting
44
#ttp0))local#ost0=>=>)#ello8)greeting
45
response12sp
46
?reetingServlet12ava 437
im3ort im3ort im3ort im3ort im3ort java.io.BC java.util.BC java.sDl.BC java".servlet.BC java".servlet.htt3.BC
BB B /his is a sim3le e"am3le o@ an H//1 )ervlet. (t res3onds to the E2/ B method o@ the H//1 3roto&ol. B 3ubli& &lass Ereetin')ervlet e"tends Htt3)ervlet F 3ubli& void doEet (Htt3)ervletAeDuest reDuest9 Htt3)ervletAes3onse res3onse) throws )ervlet2"&e3tion9 (*2"&e3tion res3onse.setContent/y3e(#te"t html#)C res3onse.set5u@@er)iGe(,$.;)C 1rintWriter out = res3onse.'etWriter()C then write the data o@ the res3onse out.3rintln(#<html># H #<head><title>Hello< title>< head>#)C
48
?reetingServlet12ava 487
then write the data o@ the res3onse out.3rintln(#<body b'&olor=I#J@@@@@@I#># H #<im' sr&=I#duKe.wavin'.'i@I#># H #<h;>Hello9 my name is DuKe. What7s yours!< h;># H #<@orm method=I#'etI#># H #<in3ut ty3e=I#te"tI# name=I#usernameI# siGe=I#;-I#># H #<3>< 3># H #<in3ut ty3e=I#submitI# value=I#)ubmitI#># H #<in3ut ty3e=I#resetI# value=I#AesetI#># H #< @orm>#)C )trin' username = reDuest.'et1arameter(#username#)C dis3at&h to another web resour&e i@ ( username != null LL username.len'th() > % ) F AeDuestDis3at&her dis3at&her = 'et)ervletConte"t().'etAeDuestDis3at&her(# res3onse#)C i@ (dis3at&her != null) dis3at&her.in&lude(reDuest9 res3onse)C M out.3rintln(#< body>< html>#)C out.&lose()C
49
?reetingServlet12ava 497
3ubli& )trin' 'et)ervlet(n@o() F return #/he Hello servlet says hello.#C M M
50
greeting12sp
<html> <head><title>Hello< title>< head> <body b'&olor=#white#> <im' sr&=#duKe.wavin'.'i@#> <h;>8y name is DuKe. What is yours!< h;> <@orm method=#'et#> <in3ut ty3e=#te"t# name=#username# siGe=#;-#> <3>< 3> <in3ut ty3e=#submit# value=#)ubmit#> <in3ut ty3e=#reset# value=#Aeset#> < @orm> <% %> <% )trin' username = reDuest.'et1arameter(#username#)C i@ ( username != null LL username.len'th() > % ) F <%Nin&lude @ile=#res3onse.js3# %> M
51
ResponseServlet12ava
im3ort im3ort im3ort im3ort im3ort java.io.BC java.util.BC java.sDl.BC java".servlet.BC java".servlet.htt3.BC
/his is a sim3le e"am3le o@ an H//1 )ervlet. (t res3onds to the E2/ method o@ the H//1 3roto&ol. 3ubli& &lass Aes3onse)ervlet e"tends Htt3)ervlet F 3ubli& void doEet (Htt3)ervletAeDuest reDuest9 Htt3)ervletAes3onse res3onse) throws )ervlet2"&e3tion9 (*2"&e3tionF 1rintWriter out = res3onse.'etWriter()C then write the data o@ the res3onse )trin' username = reDuest.'et1arameter(#username#)C i@ ( username != null LL username.len'th() > % ) out.3rintln(#<h;>Hello9 # H username H #!< h;>#)C
52
response12sp
<h;><@ont &olor=#bla&K#>Hello9 <%=username%>!< @ont>< h;>
53
JS 5is6 Servlet@
54
JS is 5Servlet6
Scriptlet 3#ava code4 within #S$ page ends up being inserted into ;spService34 method of resulting servlet 8mplicit ob;ects for servlet are also available to #S$ page designers, #ava(eans developers, custom tag designers
55
greetingA2sp12ava 437
3a&Ka'e or'.a3a&he.js3C im3ort im3ort im3ort im3ort java".servlet.BC java".servlet.htt3.BC java".servlet.js3.BC or'.a3a&he.jas3er.runtime.BC
3ubli& &lass 'reetin'Ojs3 e"tends Htt3Ps35ase F stati& F M 3ubli& 'reetin'Ojs3( ) F M 3rivate stati& boolean ?js3"?inited = @alseC 3ubli& @inal void ?js3"?init() throws or'.a3a&he.jas3er.runtime.Ps32"&e3tion F M
56
greetingA2sp12ava 487
3ubli& void ?js3)ervi&e(Htt3)ervletAeDuest reDuest9 Htt3)ervletAes3onse res3onse) throws java.io.(*2"&e3tion9 )ervlet2"&e3tion F Ps3Qa&tory ?js3"Qa&tory = nullC 1a'eConte"t 3a'eConte"t = nullC Htt3)ession session = nullC )ervletConte"t a33li&ation = nullC )ervletCon@i' &on@i' = nullC Ps3Writer out = nullC *bje&t 3a'e = thisC )trin' ?value = nullC
57
greetingA2sp12ava 497
try F i@ (?js3"?inited == @alse) F syn&hroniGed (this) F i@ (?js3"?inited == @alse) F ?js3"?init()C ?js3"?inited = trueC M M M ?js3"Qa&tory = Ps3Qa&tory.'etDe@aultQa&tory()C res3onse.setContent/y3e(#te"t htmlC&harset=()*+,,-.+$#)C 3a'eConte"t = ?js3"Qa&tory.'et1a'eConte"t(this9 reDuest9 res3onse9##9 true9 ,$.;9 true)C a33li&ation = 3a'eConte"t.'et)ervletConte"t()C &on@i' = 3a'eConte"t.'et)ervletCon@i'()C session = 3a'eConte"t.'et)ession()C out = 3a'eConte"t.'et*ut()C
58
greetingA2sp12ava 4:7
H/86 be'in R@ile=# 'reetin'.js3#C@rom=(<,9S)Cto=(-<9%)T
out.write(#InIn<html>In<head><title>Hello< title>< head>In<body b'&olor=I#whiteI#>In<im' sr&=I#duKe.wavin'.'i@I#> In<h;>8y name is DuKe. What is yours!< h;>InIn<@orm method=I#'etI#>In<in3ut ty3e=I#te"tI# name=I#usernameI# siGe=I#;-I#>In<3>< 3>In<in3ut ty3e=I#submitI# value=I#)ubmitI#>In<in3ut ty3e=I#resetI# value=I#AesetI#>In< @orm>InIn#)C end be'in R@ile=# 'reetin'.js3#C@rom=(-<9;)Cto=(-U9%)T )trin' username = reDuest.'et1arameter(#username#)C i@ ( username != null LL username.len'th() > % ) F end H/86 be'in R@ile=# 'reetin'.js3#C@rom=(-U9;)Cto=(-V9S)T out.write(#In #)C end H/86 be'in R@ile=# res3onse.js3#C@rom=(<,9S)Cto=(S%9<$)T out.write(#InIn<h;><@ont &olor=I#bla&KI#>Hello9 #)C end be'in R@ile=# res3onse.js3#C@rom=(S%9<S)Cto=(S%9S;)T out.3rint(username)C 59
greetingA2sp12ava 4;7
H/86 be'in R@ile=# res3onse.js3#C@rom=(S%9SS)Cto=(--9%)T out.write(#!< @ont>< h;>InInInInInInInInInInInInInInIn#)C end H/86 be'in R@ile=# 'reetin'.js3#C@rom=(-V9<V)Cto=(-,9%)T out.write(#In#)C end be'in R@ile=# 'reetin'.js3#C@rom=(-,9;)Cto=(U%9%)T M end H/86 be'in R@ile=# 'reetin'.js3#C@rom=(U%9;)Cto=(U<9%)T out.write(#In< body>In< html>In#)C end M &at&h (/hrowable t) F i@ (out != null LL out.'et5u@@er)iGe() != %) out.&lear5u@@er()C i@ (3a'eConte"t != null) 3a'eConte"t.handle1a'e2"&e3tion(t)C M @inally F i@ (?js3"Qa&tory != null) ?js3"Qa&tory.release1a'eConte"t(3a'eConte"t)C M 60
61
si?e and comple!ity of the pro;ect Ae9uirements on re usability of code, maintainability, degree of robustness
62
$lace all #ava code in #S$ page Suitable only for a very simple &eb application
hard to maintain hard to reuse code hard to understand for web page authors
64
'evelop separate utility classes 8nsert into #S$ page only the #ava code needed to invoke the utility classes (etter separation of contents generation from presentation logic than the previous method (etter re usability and maintainability than the previous method Still weak separation between contents and presentation, however
65
'evelop utility classes in the form of #ava(eans everage built-in #S$ facility of creating #ava(eans instances, getting and setting #ava(eans properties
Easier to use for web page authors (etter re usability and maintainability than the previous method
66
*ustom tags are specifically designed for #S$ More than ;ust getter and setter methods
re usability, maintainability, robustness 'evelopment of custom tags are more difficult than creating #ava(eans, however
67
There are many open source and commercial custom tags available
Apache Struts
#ST 3#S$ Standard Tag ibrary4 standardi?e the set of custom tags that should be available over #ava EE platform at a minimum
As a developer or deployer, you can be assured that a standard set of custom tags are already present in #ava EE compliant platform 3#-EE ,.1 and after4
68
Model using some model technologies 5iew using #S$ *ontroller using Servlet
*reating and maintaining your own M5* framework is highly discourage, however
69
Apache Struts #avaServer 6aces 3#S64 7ther frameworks0 Echo, Tapestry, &eb&orks, &icket
70
JS Scripting +lements
ets you insert #ava code into the servlet that will be generated from #S$ page Minimi?e the usage of #S$ scripting elements in your #S$ pages if possible There are three forms
72
+,pressions
E!pression is evaluated and converted into a String The String is then 8nserted into the servletDs output stream directly Aesults in something like out.println3e!pression4 *an use predefined variables 3implicit ob;ects4 within e!pression
6ormat
ELM E!pression LG or E;sp0e!pressionGE!pressionE);sp0e!pressionG Semi-colons are not allowed for e!pressions
73
+,ample0 +,pressions
*urrent time0 ELM new ;ava.util.'ate34 LG Aandom number0 ELM Math.random34 LG @our hostname0 ELM re9uest.getAemote+ost34 LG @our parameter0 ELM re9uest. get$arameter3"your$arameter%4 LG Server0 ELM application.getServer8nfo34 LG Session 8'0 ELM session.get8d34 LG
74
Scriptlets
>sed to insert arbitrary #ava code into servletDs ;spService34 method *an do things e!pressions alone cannot do
setting response headers and status codes writing to a server log updating database e!ecuting code that contains loops, conditionals
75
+,ample0 Scriptlets
76
77
78
79
80
Declarations
>sed to define variables or methods that get inserted into the main body of servlet class
>sually used with E!pressions or Scriptlets 6or initiali?ation and cleanup in #S$ pages, use declarations to override ;sp8nit34 and ;sp'estroy34 methods 6ormat0
ELN method or variable declaration code LG E;sp0declarationG method or variable declaration code E);sp0declarationG
81
+,ample0 JS
E+,GSome headingE)+,G ELN
age &ragment
82
+,ample0 Declaration
ELN private (ook'(A7 book'(A7P public void ;sp8nit34 S ... T public void ;sp'estroy34 S ... T LG
84
E;sp0e!pressionGE!pressionE);sp0e!pressionG E;sp0scriptletG #ava codeE);sp0scriptletG E;sp0declarationG declaration code E);sp0declarationG <M validation 3via <M schema4 Many other <M tools editor transformer #ava A$8s
85
-ncluding !ontents in a JS
age
87
-nclude Directive
8s processed when the #S$ page is translated into a servlet class Effect of the directive is to insert the te!t contained in another file-- either static content or another #S$ page--in the including #S$ page >sed to include banner content, copyright information, or any chunk of content that you might want to reuse in another page Synta! and E!ample
88
2sp0include +lement
8s processed when a #S$ page is e!ecuted Allows you to include either a static or dynamic resource in a #S$ file
static0 its content is inserted into the calling #S$ file dynamic0 the re9uest is sent to the included resource, the included page is e!ecuted, and then the result is included in the response from the calling #S$ page E;sp0include pageMVincluded$ageV )G E;sp0include pageMVdate.;spV)G
89
>se include directive if the file changes rarely 8t is faster than ;sp0include >se ;sp0include for content that changes often >se ;sp0include if which page to include cannot be decided until the main page is re9uested
90
E;sp0forward pageMV)main.;spV )G
7riginal re9uest ob;ect is provided to the target page via ;sp0parameter element
E;sp0forward pageMV...V G E;sp0param nameMVparam,V valueMVvalue,V)G E);sp0forwardG
91
Directives
92
Directives
'irectives are messages to the #S$ container in order to affect overall structure of the servlet 'o not produce output into the current output stream Synta!
ELU directive SattrMvalueTI LG
93
page0 *ommunicate page dependent attributes and communicate these to the #S$ container
ELU page importMV;ava.util.I LG
Taglib0 8ndicates a tag library that the #S$ container should interpret
ELU taglib uriMVmytagsV prefi!MVcodecampV LG
94
age Directives
Qive high-level information about the servlet that results from the #S$ page. *ontrol
&hich classes are imported ELU page importMV;ava.util.I LG &hat M8ME type is generated ELU page contentTypeMVM8ME-TypeV LG +ow multithreading is handled ELU page isThreadSafeMVtrueV LG ELN--'efault -LG ELU page isThreadSafeMVfalseV LG &hat page handles une!pected errors ELU page error$ageMVerrorpage.;spV LG
95
-mplicit "b2ects
A #S$ page has access to certain implicit ob;ects that are always available, without being declared first *reated by container *orresponds to classes defined in Servlet
96
-mplicit "b2ects
re9uest 3+ttpServletAe9uest4 response 3+ttpServletAepsonse4 session 3+ttpSession4 application3Servlet*onte!t4 out 3of type #sp&riter4 config 3Servlet*onfig4 page*onte!t
97
Scope "b2ects
98
'ifferent Scope
99
Session 3
!lient 8
)ession *+ -
Session 8
!lient 3
server
application
!lient 8
100
request
response
request
response
age 3
&orward
age 8
age 9
&orward
age :
Page scope
Page scope
Page scope
request scope
Session scope
101
102
#ava classes that can be easily reused and composed together into an application Any #ava class that follows certain design conventions can be a #ava(eans component
&ithin a #S$ page, you can create and initiali?e beans and get and set the values of their properties #ava(eans can contain business logic or data base access logic
103
$roperties should be accessed and set via get<!! and set<!! methods
+,ample0 Java$eans
public class !urrency I private %ocale localeG private double amountG public !urrency47 I locale F nullG amount F >1>G N public void set%ocale4%ocale l7 I locale F lG N public void setAmount4double a7 I amount F aG N public String get/ormat47 I Humber/ormat n& F Humber/ormat1get!urrency-nstance4locale7G return n&1&ormat4amount7G N N
105
A #S$ page can create and use any type of #ava programming language ob;ect within a declaration or scriptlet like following0
DE S#opping!art cart F 4S#opping!art7session1getAttribute4KcartK7G )) -& t#e user #as no cartQ create a new one i& 4cart FF null7 I cart F new S#opping!art47G session1setAttribute4KcartKQ cart7G N EJ
106
#S$ pages can use #S$ elements to create and access the ob;ect that conforms to #ava(eans conventions
E;sp0use(ean idMVcartV classMVcart.Shopping*artV scopeMVsessionV)G *reate an instance of "Shopping*art% if none e!ists, stores it as an attribute of the session scope ob;ect, and makes the bean available throughout the session by the identifier "cart%
107
108
Co need to learn #ava programming language for page designers Stronger separation between content and presentation +igher re usability of code Simpler ob;ect sharing through built-in sharing mechanism *onvenient matching between re9uest parameters and ob;ect properties
109
!reating a Java$eans
'eclare that the page will use a bean that is stored within and accessible from the specified scope by ;sp0use(ean element
E;sp0use(ean idMVbeanCameV classMVfullyF9ualifiedFclassnameV scopeMVscopeV)G or E;sp0use(ean idMVbeanCameV classMVfullyF9ualifiedFclassnameV scopeMVscopeVG E;sp0set$roperty ...)G E);sp0use(eanG
110
EL beanCame.set$ropCame3value4P LG E;sp0set$roperty nameMVbeanCameV propertyMVpropCameV valueMVstring constantV)G "beanCame% must be the same as that specified for the id attribute in a use(ean element There must be a set$ropCame method in the bean
111
5ia #S$0set$roperty
E;sp0set$roperty nameMVbeanCameV propertyMVpropCameV valueMVstring constantV)G E;sp0set$roperty nameMVbeanCameV propertyMVpropCameV paramMVparamCameV)G E;sp0set$roperty nameMVbeanCameV propertyMVpropCameV)G E;sp0set$roperty nameMVbeanCameV propertyMVIV)G E;sp0set$roperty nameMVbeanCameV propertyMVpropCameV valueMVELM e!pression LGV)G 112
114
*onvert the value of the property into a String and insert the value into the current implicit "out% ob;ect Aetrieve the value of a property without converting it to a String and inserting it into the "out% ob;ect
115
Qetting #ava(eans $roperties : and *onvert into String and insert into out
via #S$0set$roperty
Ae9uirements
"beanCame% must be the same as that specified for the id attribute in a use(ean element There must be a "get$ropCame34% method in a bean
116
E!ample
EL )) $rint a summary of the shopping cart int num M cart.getCumber7f8tems34P if 3num G /4 S LG
117
118
+rror Handling
119
'etermine the e!ception thrown 8n each of your #S$, include the name of the error page
<LU page error$ageMVerrorpage.;spV LG
the error page, use the e!ception reference to display e!ception information
ELM e!ception.toString34 LG
120
+,ample0 initdestroy12sp
&'( page i%port)*database+,* '&'( page errorPage)*errorpage+.sp* '&'1 private Boo"/B23 boo"/B234 pub!ic void .sp5nit() 6 77 retrieve database access ob.ect8 9 ic 9as set once per 9eb app!ication boo"/B23 ) (Boo"/B23)getServ!et$onte:t()+get2ttribute(*boo"/B*)4 if (boo"/B23 )) nu!!) Syste%+out+print!n(*$ou!dn;t get database+*)4 < pub!ic void .sp/estroy() 6 boo"/B23 ) nu!!4 < '-
121
+,ample0 errorpage12sp
&'( page isErrorPage)*true* '&'( page i%port)*.ava+uti!+,* '&' =esourceBund!e %essages ) (=esourceBund!e)session+get2ttribute(*%essages*)4 if (%essages )) nu!!) 6 Loca!e !oca!e)nu!!4 String !anguage ) re>uest+getPara%eter(*!anguage*)4 if (!anguage 1) nu!!) 6 if (!anguage+e>ua!s(*Eng!is *)) 6 !oca!e)ne9 Loca!e(*en*8 **)4 < e!se 6 !oca!e)ne9 Loca!e(*es*8 **)4 < < e!se !oca!e)ne9 Loca!e(*en*8 **)4 %essages ) =esourceBund!e+getBund!e(*Boo"StoreMessages*8 !oca!e)4 session+set2ttribute(*%essages*8 %essages)4 <
122
+,ample0 errorpage12sp
+++ (continued) & t%!& ead&tit!e-&')%essages+getString(*ServerError*)'-&7tit!e&7 ead&body bgco!or)*9 ite*& ?&')%essages+getString(*ServerError*)'&7 ?&p&') e:ception+getMessage() '&7body&7 t%!-
123
/ate E:a%p!e
124
125
'ate E!ample
DES page importFK2ava1util1TK EJ DES page importFK*y%ocalesK EJ DES page content(ypeFKte,t)#tmlG c#arsetF-S"-==;U-;K EJ D#tmlJ D#eadJDtitleJ%ocali.ed DatesD)titleJD)#eadJ Dbody bgcolorFKw#iteKJ D2sp0use$ean idFKlocalesK scopeFKapplicationK classFK*y%ocalesK)J D&orm nameFKlocale/ormK actionFKinde,12spK met#odFKpostKJ DbJ%ocale0D)bJ
126
'ate E!ample
Dselect nameFlocaleJ DE -terator i F locales1get%ocaleHames471iterator47G String selected%ocale F request1get arameter4KlocaleK7G w#ile 4i1#asHe,t477 I String locale F 4String7i1ne,t47G i& 4selected%ocale @F null && selected%ocale1equals4locale7 7 I EJ Doption selectedJDEFlocaleEJD)optionJ DE N else I EJ DoptionJDEFlocaleEJD)optionJ DE N N EJ D)selectJ Dinput typeFKsubmitK nameFKSubmitK valueFK?et DateKJ D)&ormJ
127
'ate E!ample
DpJ D2sp0include pageFKdate12spK &lus#FKtrueK )J D)bodyJ D)#tmlJ
128
assion@
129