The naked web service

So called because this article puts together all the parts of a web service by hand so that when you use the available tools out there designed to 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.

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.

 

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 power it up and go to the workspace.  It should look something like this:

eclipse-workspace

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”.

select-new-project

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 setup 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.

project-setup

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.

project-explorer2

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-api.jar (Java Architecture for XML Binding)
  • jaxb-impl.jar
  • jaxws-rt.jar
  • saaj-api-1.3.4.jar
  • stax-ex.jar
  • jar

JAXB is the Java Architecture for XML Binding and is used to move java objects into and out of memory in a structure 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

 

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.

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 just 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;

@WebService
public interface HelloService {
&nbsp;&nbsp; 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 end point, 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;

@WebService(endpointInterface="softwarepulse.we.app.helloage.HelloService",
portName="helloServicePort",
serviceName="helloService")
public class HelloServiceImp implements HelloService {

   @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.

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. 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 your 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 setup a servlet within the web server.  The servlet is the code which runs within the web server 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 example.  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:

</pre>
<?xml version=<em>"1.0"</em> encoding=<em>"UTF-8"</em>?>

<web-app xmlns:xsi=<em>"http://www.w3.org/2001/XMLSchema-instance"</em> xmlns=<em>"http://java.sun.com/xml/ns/javaee"</em> xsi:schemaLocation=<em>"http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"</em> id=<em>"WebApp_ID"</em> version=<em>"3.0"</em>>

&nbsp;

	<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>
<pre>

 

 

Now we need to create another new file, this one is the “sun-jaxws.xml” file and it 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 we can be anything but we get this from 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>

The last part of the web service we need to build is what are called web service artifacts for web service deployment.  These are created from the web service end point 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 your 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 EE JDK.  The file can be found in the “bin” directory under wherever you have installed Java.

One of the parameters we pass into “wsgen” is the path to the class files, so we will copy the folders that represent the package and the class files to a directory we can access.

When “wsgen” is run it will create a jaxws folder and place the java and class files for the web service artifacts.  We will then copy these back into our project.

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 our java classes we created earlier.

Then we 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 expend the sub folders, we will see that we have a folder for each level of our package and finally our classes 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 if we 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 sub directory 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.

So 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.

So the we need to call the program followed by the location of the class path.  Our class path 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

project-navigator

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.

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.

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.3.13.  Click to download the zip file and unpack it into a location of your choice.

Now to launch Jetty we want to run it using the demo setup provided by Jetty and not the root base.  Jetty recommend not using the root and to set up your own application base and secure that.  We are simply going to make use of the “demo base” as this has all the part enabled that we require to run a web service.  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 look like this:

 

“C:\Program Files\Java\jdk1.8.0_31\bin\java” -jar “C:\Users\jmcneil\Documents\Java EE\Jetty\jetty-distribution-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”.

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 SaopUI 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 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:

soapui

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

soap-request

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 end point 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:

soap-response

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 our test tool SoapUI.  Now you are ready to move on to more sophisticated methods.

Advertisements
The naked web service

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s