Web
services are something new for me. I’ve heard all about them and the
popularity of them, but taking the task upon myself to create one was
something that I’d never done. The WSDLs looked somewhat complicated
and I just had no motivation until yesterday. However, to my surprise,
I found that the process is not really too complicated at all. In this
article I’ll show you how to make a simple web service that adds and
multiplies.
The Webservice
01.
02.
03.
package
com.jstaten.webService.server;
04.
05.
import
javax.jws.WebMethod;
06.
import
javax.jws.WebService;
07.
08.
@WebService
09.
public
class
MathExampleImpl {
10.
@WebMethod
(operationName=
"addInts"
)
11.
public
int
addInts(
int
a,
int
b)
12.
{
13.
return
a + b;
14.
}
15.
@WebMethod
(operationName=
"multiplyFloats"
)
16.
public
float
multiplyFloats(
float
a,
float
b)
17.
{
18.
return
a * b;
19.
}
20.
}
The service is very straightforward. Essentially you create a class
with the operations that will show up in the WSDL. This class has two, addInts and multiplyFloats which will add integers and multiply floats, respectively. The annotations @WebService and @WebMethod are later parsed when building this application.
The Server
01.
02.
03.
package
com.jstaten.webService.server;
04.
05.
import
javax.xml.ws.Endpoint;
06.
07.
public
class
MathService {
08.
private
Endpoint endpoint =
null
;
09.
public
MathService()
10.
{
11.
endpoint = Endpoint.create(
new
MathExampleImpl());
12.
}
13.
private
void
publish()
14.
{
15.
17.
}
18.
public
static
void
main(String[] args)
19.
{
20.
MathService hws =
new
MathService();
21.
hws.publish();
22.
System.out.println(
"Waiting"
);
23.
}
24.
}
The server relies on one key component, the Endpoint class.
Endpoints are used to publish a webservice to a specific address. In
this very simple example, we take a new instance of our MathExampleImpl
class that we created earlier and publish it to http://localhost:7070/MathExample/MathService which
will be where we direct any webservice calls to from a client. Finally,
we give the “Waiting” message to know that the server has started and
is waiting for a connection.
The Build File
01.
<?
xml
version
=
"1.0"
encoding
=
"UTF-8"
?>
02.
03.
<
project
basedir
=
"."
default
=
"build-server"
name
=
"MathServiceExample"
>
04.
05.
<
property
environment
=
"env"
/>
06.
<
property
name
=
"lib.home"
value
=
"${env.JAXWS_HOME}/lib"
/>
07.
<
property
name
=
"build.home"
value
=
"${basedir}/build"
/>
08.
<
property
name
=
"build.classes.home"
value
=
"${build.home}/classes"
/>
09.
10.
<
path
id
=
"jaxws.classpath"
>
11.
<
pathelement
location
=
"${java.home}/../lib/tools.jar"
/>
12.
<
fileset
dir
=
"${lib.home}"
>
13.
<
include
name
=
"*.jar"
/>
14.
<
exclude
name
=
"j2ee.jar"
/>
15.
</
fileset
>
16.
</
path
>
17.
18.
<
taskdef
name
=
"apt"
classname
=
"com.sun.tools.ws.ant.Apt"
>
19.
<
classpath
refid
=
"jaxws.classpath"
/>
20.
</
taskdef
>
21.
22.
<
target
name
=
"setup"
>
23.
<
mkdir
dir
=
"${build.home}"
/>
24.
<
mkdir
dir
=
"${build.classes.home}"
/>
25.
</
target
>
26.
27.
<
target
name
=
"build-server"
depends
=
"setup"
>
28.
<
apt
29.
fork
=
"true"
30.
debug
=
"true"
31.
verbose
=
"${verbose}"
32.
destdir
=
"${build.classes.home}"
33.
sourcedestdir
=
"${build.classes.home}"
34.
sourcepath
=
"${basedir}/src"
>
35.
<
classpath
>
36.
<
path
refid
=
"jaxws.classpath"
/>
37.
<
pathelement
location
=
"${basedir}/src"
/>
38.
</
classpath
>
39.
<
option
key
=
"r"
value
=
"${build.home}"
/>
40.
<
source
dir
=
"${basedir}/src"
>
41.
<
include
name
=
"**/server/*.java"
/>
42.
<
include
name
=
"**/common/*.java"
/>
43.
</
source
>
44.
</
apt
>
45.
</
target
>
46.
47.
<
target
name
=
"clean"
>
48.
<
delete
dir
=
"${build.home}"
includeEmptyDirs
=
"true"
/>
49.
</
target
>
The build file is where a lot of the magic is done. At first glace
it may seem a little confusing, but broken down, it is actually quite
simple. Lets step through it.
1.
<
property
environment
=
"env"
/>
2.
<
property
name
=
"lib.home"
value
=
"${env.JAXWS_HOME}/lib"
/>
3.
<
property
name
=
"build.home"
value
=
"${basedir}/build"
/>
4.
<
property
name
=
"build.classes.home"
value
=
"${build.home}/classes"
/>
The first section is properties that will be used throughout the
rest of the build file describing the location of JAX-WS and the
location to place compiled files.
1.
<
path
id
=
"jaxws.classpath"
>
2.
<
pathelement
location
=
"${java.home}/../lib/tools.jar"
/>
3.
<
fileset
dir
=
"${lib.home}"
>
4.
<
include
name
=
"*.jar"
/>
5.
<
exclude
name
=
"j2ee.jar"
/>
6.
</
fileset
>
7.
</
path
>
This section defines the classpath of JAX-WS for usage within the build file.
1.
<
taskdef
name
=
"apt"
classname
=
"com.sun.tools.ws.ant.Apt"
>
2.
<
classpath
refid
=
"jaxws.classpath"
/>
3.
</
taskdef
>
Within this element, we declare apt which is what does the
actual parsing of the annotations within your source files. We will use
it as an element later on in the build file.
01.
<
target
name
=
"build-server"
depends
=
"setup"
>
02.
<
apt
03.
fork
=
"true"
04.
debug
=
"true"
05.
verbose
=
"${verbose}"
06.
destdir
=
"${build.classes.home}"
07.
sourcedestdir
=
"${build.classes.home}"
08.
sourcepath
=
"${basedir}/src"
>
09.
<
classpath
>
10.
<
path
refid
=
"jaxws.classpath"
/>
11.
<
pathelement
location
=
"${basedir}/src"
/>
12.
</
classpath
>
13.
<
option
key
=
"r"
value
=
"${build.home}"
/>
14.
<
source
dir
=
"${basedir}/src"
>
15.
<
include
name
=
"**/server/*.java"
/>
16.
<
include
name
=
"**/common/*.java"
/>
17.
</
source
>
18.
</
apt
>
19.
</
target
>
The build-server target is the main operation within the build file. It utilizes apt like
we declared earlier and tells it where to place the compiled code as
well as the generated source. Using the properties we declared earlier,
we can essentially just fill in the blanks. destdir is the location of
the compiled code, sourcedestdir is the placement of generated source
code(from parsing the attributes), and sourcepath is the path to the
source files that you created earlier.
1.
<
target
name
=
"clean"
>
2.
<
delete
dir
=
"${build.home}"
includeEmptyDirs
=
"true"
/>
3.
</
target
>
Finally, the clean target removes old compiled code. This can be run by using ant clean
After compiling a simple java com.jstaten.webService.server.MathService will start the server and a quick pointing of your browser to http://localhost:7070/MathExample/MathService?wsdl will result in receiving a WSDL.
In a later article I will discuss the creation of a client to use this service a within both Java and C#.