This section has an example that uses GlassFish to host a website and Tomcat to host a SOAP-based web service that the website accesses. Chapter 3, on RESTful clients, has examples in which jQuery clients make calls against REST-style services that respond with JSON payloads; the JavaScript embedded in the web page puts the JSON to good use. The website in the current example is old school in that the HTML page contains no JavaScript. Instead, the page has a familiar submit button that, when pressed, causes an HTML form to be POSTed to a JSP script, which then calls upon a SOAP-based service to perform simple computations. The results of these computations are displayed on the web page. The interaction is among an HTML page, a JSP script with access to wsimport-generated artifacts, and a SOAP-based service (see Figure 7-5). This distributed application performs temperature conversions. To make the example realistic and to set up a comparison between deployment details, the web service is published with standalone Tomcat and the website is published with GlassFish.
The HTML page index.html (see Example 7-2) contains a simple form with a text box into which a user enters temperatures to be converted into fahrenheit and centigrade. To keep matters simple, the CSS styling is embedded in the HTML. When the HTML form is submitted with a button push, a POST request is sent to the JSP script named tempConvert.jsp. There is also an error script, error.jsp, to handle errors that result from trying to convert non-numeric input (e.g., the string foo) into a decimal number. The two JSP scripts and the HTML page, together with some other artifacts discussed shortly, are deployed in the WAR file tcWeb.war. GlassFish hosts the website.
Example 7-2. The HTML document index.html
<!
DOCTTYPE
html
>
<
html
>
<
head
>
<
style
type
=
"text/css"
>
input
{
background
-
color:
white
;
font
-
weight:
bold
;
font
-
size:
medium
}
legend
{
color:
#
990000
;
font
-
size:
large
;}
fieldset
{
width:
600
px
;
background
-
color:
rgb
(
225
,
225
,
225
);}
</
style
>
</
head
>
<
body
>
<
form
method
=
'
post
'
action
=
'
tempConvert
.
jsp
'
>
![]()
<
fieldset
>
<
legend
>
Temperature
conversion
</
legend
>
<
table
>
<
tr
>
<
td
>
Temperature:
</
td
>
<
td
><
input
type
=
'
text
'
name
=
'
temperature
'
/></
td
>
![]()
</
tr
>
</
table
>
<
input
type
=
'
submit
'
value
=
'
Convert
'
/>
![]()
</
fieldset
>
</
form
>
</
body
>
</
html
>
For context, the main contents of the website WAR file are:
WEB
-
INF
/
web
.
xml
WEB
-
INF
/
classes
/
tempConvertClient
/
C2F
.
class
WEB
-
INF
/
classes
/
tempConvertClient
/
C2FResponse
.
class
WEB
-
INF
/
classes
/
tempConvertClient
/
F2C
.
class
WEB
-
INF
/
classes
/
tempConvertClient
/
F2CResponse
.
class
WEB
-
INF
/
classes
/
tempConvertClient
/
ObjectFactory
.
class
WEB
-
INF
/
classes
/
tempConvertClient
/
TempConvert
.
class
WEB
-
INF
/
classes
/
tempConvertClient
/
TempConvertService
.
class
error
.
jsp
index
.
html
tempConvert
.
jsp
The HTML page index.html provides a text field (line 2) into which a user can enter input. When the form (line 1) is submitted by clicking the submit button (line 3), the targeted action is the JSP script tempConvert.jsp, which receives the contents of the text field as request data.
The code of JSP script tempConvert.jsp (see Example 7-3) has two page
directives (lines 1 and 2), which import wsimport-generated classes for the
web service. These classes reside in the package/directory tempConvertClient, which
is included in the deployed WAR file tcWeb.war. The JSP script extracts the
user input from the HTTP POST request (line 3) and then tries to convert the input
to a floating-point number. If there are any errors, control immediately goes via an
automatic redirect, which GlassFish manages, to the
error page error.jsp (see Example 7-4); the HTTP status code is 400 for bad request
(see line 1 in the displayed error page).
The error page announces an input error and,
through a hyperlink back to index.html, gives the user the option of trying again.
Example 7-3. The JSP script tempConvert.jsp, deployed in the tcWeb.war file
<!
DOCTYPE
html
>
<%
@
page
errorPage
=
"error.jsp"
%>
<!--
wsimport
-
generated
artifacts
-->
<%
@
page
import
= "
tempConvertClient.TempConvertService
"
%>
![]()
<%
@
page
import
= "
tempConvertClient.TempConvert
"
%>
![]()
<
html
>
<
head
>
<
style
type
=
'
text
/
css
'
>
a
{
color:
#
151
b8d
;
text
-
decoration:
none
;}
a:
visited
{
color:
#
151
b8d
;}
a:
hover
{
color:
#
fff
;
background
-
color:
#
666
;}
.
p
{
color:
blue
;
font
-
size:
large
;}
legend
{
color:
#
990000
;
font
-
size:
large
;}
fieldset
{
width:
600
px
;
background
-
color:
rgb
(
225
,
225
,
225
);}
</
style
>
<%!
private
float
f2c
,
c2f
,
temp
;
%>
<%
String
tempStr
=
request
.
getParameter
(
"temperature"
);
// text field
![]()
if
(
tempStr
!=
null
)
this
.
temp
=
Float
.
parseFloat
(
tempStr
.
trim
());
this
.
f2c
=
this
.
c2f
=
this
.
temp
;
TempConvert
port
=
new
TempConvertService
().
getTempConvertPort
();
c2f
=
port
.
c2F
(
temp
);
![]()
f2c
=
port
.
f2C
(
temp
);
![]()
%>
<
body
>
<
fieldset
>
<
legend
>
Temperature
conversions
</
legend
>
<
p
><%=
this
.
temp
%>
F
=
<%=
this
.
c2f
%>
C
</
p
>
![]()
<
p
><%=
this
.
temp
%>
C
=
<%=
this
.
f2c
%>
F
</
p
>
![]()
</
fieldset
>
<
hr
/>
<
a
href
=
'
index
.
html
'
>
Try
another
</
a
>
![]()
</
body
>
</
html
>
If the conversion of the input data to a floating-point number succeeds, the JSP script calls the SOAP-based tcService, running on Tomcat, to convert the number into centigrade (line 4) and fahrenheit (line 5). The values returned from the tcService then are displayed (lines 6 and 7). A hyperlink at the bottom of the page (line 8) gives the user the option to try again.
Example 7-4. The error page error.jsp
<%
@
page
isErrorPage
=
"true"
%>
<!
DOCTYPE
html
>
<
html
>
<
head
>
<
style
type
=
'
text
/
css
'
>
a
{
color:
#
151
b8d
;
text
-
decoration:
none
;}
a:
visited
{
color:
#
151
b8d
;}
a:
hover
{
color:
#
fff
;
background
-
color:
#
666
;}
.
p
{
color:
red
;
font
-
size:
large
;}
</
style
>
</
head
>
<
body
>
<%
response
.
setStatus
(
400
);
%>
<!--
bad
request
-->
![]()
<
p
class
= '
p
'
>
Numbers
only
,
please
.</
p
>
<
hr
/>
<
a
href
=
'
index
.
html
'
>
Try
again
.</
a
>
</
body
>
</
html
>
The tcService.war file, which contains the SOAP-based web service, has these contents:
WEB
-
INF
/
web
.
xml
![]()
WEB
-
INF
/
classes
/
tempConvert
/
TempConvert
.
class
WEB
-
INF
/
lib
/
webservices
-
api
.
jar
![]()
WEB
-
INF
/
lib
/
webservices
-
rt
.
jar
![]()
WEB
-
INF
/
sun
-
jaxws
.
xml
Two deployment files are needed (lines 1 and 4) because the Metro JWSServlet
acts as the intermediary
between the client request and the TempConvert
service. The web.xml (see Example 7-5) specifies the Metro servlet (line 1)
as the request handler, and the sun-jaxws.xml then routes the request from the Metro servlet to a
TempConvert
instance (see Example 7-5). Further, the two Metro JAR files (lines 2 and 3) are needed because Tomcat
does not come with the Metro implementation of JAX-WS.
Example 7-5. The web.xml for the TempConvert
service deployed under Tomcat
<?
xml
version
=
"1.0"
encoding
=
"UTF-8"
?>
<
web
-
app
>
<
listener
>
<
listener
-
class
>
com
.
sun
.
xml
.
ws
.
transport
.
http
.
servlet
.
WSServletContextListener
</
listener
-
class
>
</
listener
>
<
servlet
>
<
servlet
-
name
>
jaxws
</
servlet
-
name
>
<
servlet
-
class
>
com
.
sun
.
xml
.
ws
.
transport
.
http
.
servlet
.
WSServlet
![]()
</
servlet
-
class
>
<
load
-
on
-
startup
>
1
</
load
-
on
-
startup
>
</
servlet
>
<
servlet
-
mapping
>
<
servlet
-
name
>
jaxws
</
servlet
-
name
>
<
url
-
pattern
>/*</
url
-
pattern
>
</
servlet
-
mapping
>
</
web
-
app
>
The JSP script tempConvert.jsp makes calls against the tcService by using the wsimport-generated
classes in the package/directory tempConvertClient. This JSP script together with the HTML page, the
error page, and the contents of the tempConvertClient directory are encapsulated in the
WAR file tcWeb.war, which is deployed with GlassFish instead of Tomcat. The point of interest is
that the Metro JAR files are not included in the deployed tcWeb.war precisely because GlassFish
itself comes with the full Metro implementation. Accordingly, if the tcService were deployed under
GlassFish instead of standalone Tomcat, the two JAR files in tcService.war could be removed—indeed, these
JAR files would have to be removed in order to avoid a conflict with the Metro library that comes installed
with GlassFish. The tcService still would use the JWSServlet
as the intermediary, which in turn means that the
web.xml and the sun-jaxws.xml configuration files would be needed as well.
It is hardly surprising that GlassFish includes the Metro libraries. Metro is the reference implementation of JAX-WS; the GlassFish JAS includes this implementation as one of the JAS components. The GlassFish JAS officially comes under the GlassFish Metro Project, which in turn includes the full web service stack that implements JAX-WS. As earlier examples with Tomcat and Jetty illustrate, the web service stack can be used independently of the GlassFish JAS. Among JASes, Oracle WebLogic also includes the Metro web service stack.