The naked web service

So-called because in this article we show how to put together all the parts of a simple web service so that when you come to use the tools out there, that make things easier and quicker, you can work out what has gone wrong and how to fix it.

So are all web services equal? No, they are not.  That is not to say one is better than another only that there are different types and different ways to produce a web service.  So what are we going to do?

We are going to produce a simple web service.  It will be written in Java and make use of the JAX-WS library provided with the core Java EE install.

I will use eclipse as my IDE but you can use any IDE or simply text files and “javac” if you so desire.

We are not using any tools that tie us into a specific vendor to build our web service.  We will use “wsgen” which comes with Java SE install and therefore is available to everyone.

The web service will be what is known as a SOAP web service.  SOAP stands for Simple Object Access Protocol and is essentially a standard way of structuring messages so different systems can understand them.  There are also REST or RESTful web services which stands for REpresentational State Transfer web services.  These are what is known as stateless operations and can support information exchange using varied structures such as HTML or JSON.  We are going with SOAP, it is the older of the two major approaches, both are widely used, but I have more experience of using SOAP.

Once we have built our web service, we will deploy to a product called Jetty.  Jetty is again a product which ships with Java EE so there is nothing special about this.  Jetty is a small footprint web server and servlet engine.  It is typically embedded into other products such as Apache Geronimo and Alfresco.  There is no special reason why we have chosen Jetty, we could just as easily have selected Glassfish which ships with eclipse and Java EE.  In fact, you can use any application server which supports running a standard Web Application Archive (WAR) file.

The only other thing to mention is that we will be including some “JAR” files in our project that support running web services within application servers.  These are provided for ease of access as part of the project resources but you can also access them directly from sites on the web if you so desire.

The last thing I want to mention in setting the scene is that we will be using some simple XML which is the descriptive language of web services and especially SOAP-based web services.  You do not need to know XML but we will be using it in defining connections between our web service objects as well as when it comes to testing our web service. To test the web service, I will be using a tool called SoapUI, it is a well-known test tool and makes testing our web service quick and easy.

So down to business.

The Web Service

What exactly do we want our web service to do?  As is typical of starter projects we could do a hello world type service which accepts the name of a person and returns “Hello <name>”.  Just to make it a little more interesting we will pass to the web service a name and an age and return “Hello <name>, I understand you are <age> years old.  This is still a very simple web service however the purpose of this exercise is to learn how to put together all the building blocks for a working web service.  Once that is mastered then we can go on to add bells and whistles such as arrays of information, transferring files and authentication.

Setting up the project

Ok, we have an idea of what we want to do.  Let us start with writing the web service in Java first.

  • To do this we will create a Java web project in Eclipse
  • We will then add the JAR libraries to our project.
  • We will then write our web service classes
  • We will need a web.xml file which describes all the connections between the various parts
  • We will use wsgen to generate classes which will enable the Java XML binding of the web service

Once those things are in place we can take a look at deployment.

So if you do not already have Eclipse for Java EE then you will need to download it.  This is simply a matter of going to the web site, selecting the correct install for your operating system, downloading it and then unzipping it to a location on your machine.

Once it is installed you can power it up

Eclipse project select wizard

Once it is installed you can power it up and we are ready for the next step.

Now, we create a new Java project.  Go to the menu-bar and select “File”, “New” and I went with “Other” so that I was presented with a list of all options. The project type we are looking for is “Dynamic Web Project” which I found under the Web folder.  You may see it under the “New” option without having to select “Other”.

We now need to give our project a name, I went with “helloage”.  Now I think I should mention here that web services and the connections between the items are case sensitive. It is a good idea to get into the habit of adhering to a naming convention and sticking to it otherwise later you can spend a lot of time trying to sort out all the different variations.  I only mention this because I have this failing, I should just stick to the industry convention but always seem to end up doing my own thing and regretting it later.  So the project is called “helloage” all lower case.

Now if you have looked at any other lessons on how to set up a web service you may have seen people say to select a “Target runtime”.  You would do this if you were going to use Eclipse to deploy to your server.  We are not doing this for two reasons

  1. I don’t seem to be able to find a way to add in Jetty to the list of options
  2. The idea of this tutorial is to show you what manual steps you need to do. Not use a wizard to hide from you the steps required.

So we can leave all the rest of the dialog box as is and press the finish button.  Note: if you press the next button a couple of times until you get to the Web Module page there is an option to generate the web.xml file.  Select this and it saves you having to create the file from scratch as I have to do later.

Setting up the web service project

So what we now have is a project with a collection of files and folders.  Now if you are using another type of IDE do not worry too much if you have something that looks different, the core part is to be able to export a WAR file once your project is compiled.

Basic web service project in Eclipse

What we now need to do is copy the jar files I mentioned earlier into the “lib” folder under the “WEB-INF” folder.  The files that need to be copied are:

JAXB is the Java Architecture for XML Binding and is used to move java objects into and out of memory in a structured method, XML.

JAXWS is the Java API for XML Web Services of which SOAP is one.

SAAJ is SOAP with Attachments API of Java which defines how to send XML documents over the internet from Java

Those are the main libraries but if you are interested you can look into what the others do.  It is very common these days to use an extensive collection of code from third parties to accomplish a task, particularly with web-based technology.

So, simply copy these from the file directory where you have them stored and paste them into the “lib” folder. These are not important for the building of the web service it just makes sure they are included when we build the WAR file.

Our web service code

Next, we need to write some Java.  The first class we will create is an interface class and then we will create a class that implements the interface.  So from the “src” folder which is located under the “Java Resources” folder in Eclipse, create a new interface class and call it “HelloService”.  I have placed this in the package “softwarepulse.web.app.helloage” but you can put it in any package you want, you will just need to remember what package you used as you will need to be consistent throughout the project.

Within our interface class, we will define methods.  These are the methods which will be available to call from our web service.  So in our case, we will have a “sayhello” method that can be called from our web service.  We will pass to it our name and age and get back from the service a message.  We need to tag this class and method to say that it is the entry point for a web service and this is the access method within the service.  We do this by adding an “@WebService” to the front of the class definition.   This will allow the Jax-ws service to correctly build the connections.  So translated, our interface class will look like this:

package softwarepulse.web.app.helloage; 

import javax.jws.WebService; 

/**
 * @author john McNeil
 * @copyright Software Pulse 2019
 */


@WebService 
public interface HelloService { 
	String sayhello(String name, int age); 
}

Now we create a class in the same package as our interface.  We will call the class “HelloServiceImp” as this is our implementation class.

The class will implement the “HelloService” interface we created in the previous step.  Now we will also add in some instructions about our web service so when it is generated the endpoint, port and service name are defined.  We do this by adding another “@WebService” tab but this time within parenthesis we specify values for these settings.

When we generate the WSDL for this web service we will see these values set and we will then use these same values for our web service client to connect to the web service, so all we are doing is describing how to connect and access our web service.  The code for the class looks like this:

package softwarepulse.web.app.helloage; 

import javax.jws.WebService; 

/** 
 * @author john McNeil
 * @copyright Software Pulse 
 */

@WebService(endpointInterface="softwarepulse.web.app.helloage.HelloService", portName="helloServicePort", serviceName="helloService") 
public class HelloServiceImp implements HelloService {
	
	/* (non-Javadoc) * @see softwarepulse.web.app.helloage.HelloService#sayhello(java.lang.String, int) */ 
	@Override 
	public String sayhello(String name, int age) { 
		return "Hello " + name + ", I understand you are " + age + " years old."; 
	} 
}

So that is all the Java code we need for our simple web service.  The rest is all setting up connections, packaging and deploying to a web service.

The web xml file

We will now open up our web.xml file.  This is the file used to describe where the various components are located and how they link together to provide the service.  Now I must confess when I created my project I did not get a web.xml file created so had to manually create it. Assuming you have the same issue, the file needs to be located under the “webContent\WEB-INF” directory.

In the web.xml file, we need to define a listener for our web service.  This is the code that runs before our web application starts and runs code before shutting down.  In our case, we have no need for anything special so we will use the class provided for us within Java “com.sun.xml.ws.transport.http.servlet.WSServletContextListener”.

We also need to set up a servlet within the webserver.  The servlet is the code which runs within the webserver and will receive and provide information to and from our web service.  Again we will make use of a general servlet provide by Java which will connect to our web service class.

We will need to give this servlet a reference name within the server and this is set to match the serviceName we set in the earlier code.  Once the servlet has a name we then link the name to a URL pattern.  What this means is that when someone wants to call the web service they will use a URL; the URL that is linked to this web service is defined in the URL pattern. As you can see we have gone for something different from what we have used so far “Hello2You”.  So what our web.xml file ends up looking like is this:

<?xml version="1.0" encoding="UTF-8"?> 
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0"> 
	<listener> 
		<listener-class>com.sun.xml.ws.transport.http.servlet.WSServletContextListener</listener-class> 
	</listener> 
	<servlet> 
		<servlet-name>HelloService</servlet-name> 
		<servlet-class>com.sun.xml.ws.transport.http.servlet.WSServlet</servlet-class> 
	</servlet> 
	<servlet-mapping> 
		<servlet-name>HelloService</servlet-name> 
		<url-pattern>/Hello2You</url-pattern> 
	</servlet-mapping> 
</web-app>

Jaxws XML file

Now, we need to create another new file, this one is the “sun-jaxws.xml” file.  This file tells the Java API, used for creating web services, the details of the endpoint of the web service.  So, we create this file in the same location as our web.xml file and do this by selecting “New” from the options on the “File” menu and then “File”. When the dialog box appears select “WEB-INF” as the parent folder and set the file name to “sun-jaxws.xml” and press finish.

We then need to set the name of the web service which needs to match the servlet name in the web.xml file, the name of the implementation class which is the name of our Java class that implements the interface and the last item the URL which again we set in the web.xml file. So our “sun-jaxws.xml” file now looks like this:

<?xml version="1.0" encoding="UTF-8"?> 
<endpoints xmlns="http://java.sun.com/xml/ns/jax-ws/ri/runtime" version="2.0"> 
	<endpoint name="HelloService" implementation="softwarepulse.web.app.helloage.HelloServiceImp" url-pattern="/Hello2You" /> 
</endpoints>

Web service artifacts

The last part of the web service we need to build is what is called web service artifacts for web service deployment.  These are created from the web service endpoint class which in our case are the two Java classes we created earlier, the interface and implementation classes.  We need to take the byte code “.class” files, not the “.java” files and copy these to our file system.

First, let me explain what we are going to do and then you can follow the path that best suits your setup.  We will need to run an executable file called “wsgen” which ships with Java SE JDK.  The file can be found in the “bin” directory under wherever you have installed Java.

The way I will do this is first ensuring my project build is up to date by selecting “Project/Build Project” from the menu bar.  This will build the class files for the java classes we created earlier.

Then switch to the navigator view in Eclipse and expand the “build/classes” folders to reveal the top-level package name for our classes. If you have followed the naming used here, then that will be “softwarepulse”.   If we expand the subfolders, we will see that we have a folder for each level of our package and finally our class files.

We need to copy all of this from Eclipse to our local hard drive. If we select the “softwarepulse” folder and right-click we can then copy this structure.  Then, switch to, in my case Windows Explorer and navigate to the C:\ drive.  I choose this for simplicity sake you can paste the files anywhere you can access. So, we can easily find the files we are about to create I suggest you create a subdirectory to paste the files into.  I have chosen to call mine “helloage”, the same name as my project.  Within the new directory paste the files copied from Eclipse.

Next, we call “wsgen” with the command line parameters.  To do this open up a command line prompt and navigate to the directory where the files were pasted, so in my case, this would be “c:\helloage”.  Next, we call the program with the parameters.

To do this we call the program followed by the location of the classpath.  Our classpath location is where we are running wsgen from so we can simply use a dot “.”.  The next command is an instruction that we want to keep the files generated.  If we do not use this, they will be removed once wsgen completes.  Finally, we specify the web service entry point implementation which in our web service is “HelloServiceImp”.

Now in my case I do not have my Java EE JDK on my path and do not have JAVA_HOME defined so I cannot simply call the program using the name, I must specify the whole path to the program.  So my command line looks like this:

"C:\Program Files\Java\jdk1.8.0_31\bin\wsgen" -cp . 
-keep softwarepulse.web.app.helloage.HelloServiceImp

When it finishes running we are left with a new folder created at the same level as our java class files and this folder is called “jaxws”.  Within the folder are four files, two of type “.class” and two of type “.java”.  We need the “.java” files called “Sayhello.java” and “SayhelloResponse.java”.  Copy these and then go back to Eclipse.  Using the Navigator project view

The web service project with the jaxws folder

Create a new folder by right-clicking on the “helloage” folder located under the “src” directory and then select “create new folder”.  Call the new folder “jaxws” and then paste the files into this folder by right-clicking and selecting paste.

Creating the WAR file

We now build the project to ensure everything is up to date and then from the menu bar select “File/Export”.  From the dialog box that appears select “Web/WAR File”, press “Next” and give the WAR file a name and select an export destination.  We now have our WAR file for deployment to our web server.  Now you should be able to deploy this to any web server that supports standard WAR files such as IBM WebSphere or JBoss or Tomcat or Glassfish.  Here I’m going to use Jetty.

Setup the Jetty Server

Now, Jetty comes with Java and with Eclipse but I am going to download a standalone copy and deploy to it.  So to get a copy of Jetty we need to go to http://www.eclipse.org/jetty/ and locate the download link.  From the download, section select the release you want to use.  I went for version 9.4.18.  Click to download the zip file and unpack it into a location of your choice.

To launch Jetty we want to run it using the demo setup provided by Jetty and not the root base.  Jetty recommends using your own application base and not the root. This allows you to set up your application base and secure that.  We are simply going to make use of the “demo base” as this has all the parts enabled that we require to run a web service and it is not the intention to publish to service to the web.  So to run up Jetty using the “demo base” open a command prompt and navigate to the directory for the demo directory which in my case is:

“C:\Users\jmcneil\Documents\Java 
EE\Jetty\jetty-distribution-9.3.13.v20161014\demo-base”

Now run java passing it the -jar switch and the path to the “start.jar” provided with the Jetty release.  So my command line looks like this:

"C:\Program Files\Java\jdk1.8.0_31\bin\java" -jar 
"C:\Users\jmcneil\Documents\Java EE\Jetty\jetty-di
stribution-9.3.13.v20161014\start.jar"

Jetty starts up and uses the “start.ini” file from the directory which has the current focus, the demo base.  To check everything is up and running, open a browser and go to:

http://localhost:8080/

Jetty uses the web port 8080 by default, not the web standard of port 80 hence the colon and the “8080”.  What you should see displayed is a page with links to the various demos.

Now to deploy our application we need to copy the WAR file from where we exported it and place it in the “webapps” directory under the “demo-base” directory.  You can do this while the server is running as web servers are designed to scan the directory for changes and load new applications.

Once you have copied your WAR file into the “webapps” directory you can check it has loaded correctly by altering the web browser address to:

http://localhost:8080/helloage/Hello2You?wsdl

What you should see displayed is the Web Service Definition Language (WSDL) for the web service.  We will need this for the next step so right-click on the page and “Save page as” and save the file somewhere with an extension of “.wsdl”.

Testing our web service with SOAPUI

The last thing to do is to test out our web service and to do this we will use SoapUI.  Now I admit SoapUI is a heavy-duty tool but it is very good at what it does and if you are going to be writing lots of web services a tool such as SoapUI will be invaluable.  To download SoapUI go to https://www.soapui.org/

Select the download section and download the OpenSource version.  Follow the instructions to install and then launch SoapUI.

Whilst the tool can do many things, for what

SOAPUI simple SOAP project to test the web service

we want to do there are only a few steps we need to follow.  Go the menu bar and select “File/New Soap Project”.  Give the project a name, this can be anything, and then select the “WSDL” file we saved to our local machine in an earlier step.  Leave the “Create sample requests for all operations?” checked.  Press the OK button and a project with the name you provided will be created.  If you expand the project it will look like this:

Now double click on “Request 1” to open up the soap XML.

SOAP request for our web service

The XML will have two parameters which can be set to a value, highlighted in yellow.  The other thing to ensure is that the URL is pointing at the endpoint of the web service.  In my case this is

http://localhost:8080/helloage/Hello2You

Then press the green triangular button to submit the soap message to your web service and on the other side of the request window you should receive some XML as a response which will look like this:

Response XML from the SOAP request

And as you can see our response message has been returned from the web service.

So that’s it.  We have built a web service in Java using the JAX-WS library, deployed it to our Jetty web server and tested it using the test tool SoapUI.  Now we are ready to move on to more sophisticated methods.

There is no source code download for this example as there is very little code to type, most of the work is in downloading, installing and configuring the various components.  If you do have any problems leave a comment.

One Reply to “The naked web service”

  1. Thanks for the tutorial.
    I try to add capabilities to Apache Ignite for JaxWS.
    With your tutorial thats is complete.

Leave a Reply

Your email address will not be published.

This site uses Akismet to reduce spam. Learn how your comment data is processed.