Syndicate This Blog
Saturday, January 19. 2008
Welcome to the last entry of this blog. No I am not quitting, I am just moving. I just installed a new blog software framework. I was starting to dislike the way to interact and I wanted something that contained more out of the box. I am in the middle of moving to wordpress software. There is a very good reason to do this. I had found a great tool on the mac called MarsEdit. And again this could not be used with serendipity. I hope I did make a good choice. Since there is a lot of information in the old blog, I did not take this blog offline. It will stay to exist, but I will not make changes there anymore.
I hope to see you at the new version of the blog (check the page at http://www.gridshore.nl). You can attach you feedreader to the following url: feed://www.gridshore.nl/feed/
Monday, August 20. 2007
There are many blog entries and articles out there about web service versioning. So why write another? In my day-to-day work, I am often asked about how to solve web service versioning issues. The articles on the web provide different ways to do it, but do not take the impact on the codebase, deployment and testing into consideration. Now that's exactly what I'll be trying to do in this article.
First, I'll briefly describe what I mean with Web Service versioning. Then, I'll shed some light on different possible solutions. Finally, I'll compare all of these solutions in terms of complexity, codebase, deployment and testing.
Web service versioning, real or just a myth?
Many, maybe even all, projects that involve web services will encounter a problem they call "web service versioning". But what is it? And does it really exist?
Why versioning web services is an issue
Web Service versioning doesn't†exist. So why is it an issue? Because developers (myself included) want to be able to reuse existing classes for new versions of a service. So, in our Version Control System (VCS, e.g. Subversion or CVS) repository we¬?ll want to create a branch for the old version, and continue development in our main branch. We'd want to deploy our application with our old JAR and the new one and provide some mechanism for selecting either the old classes or the new ones.
Solutions for service versioning
The web is full of solutions for versioning. I'll mention each solution briefly, and explain how it is set up. At the end of this blog entry, I will compare these solutions in terms of codebase, deployment and testing.
Comparing the solutions
Now that I have mentioned each solution briefly, it is time to put them in the ring to compete against each other. Here we go:
Wednesday, July 4. 2007
My previous post was about creating a client with the spring-ws project. This dis take me some time to grasp. But without a published webservice a client is of no much use. Therefore I also had a look at the server side. To my surprise this was even easier than expected. I did have some requirements for the sample:
That does not sound to bad does it? Well try to do it with axis and you'll be surprised. If you know a little bid about spring-webmvc and the use of the dispatcher, you know you need one configuration file for spring. For the webservice I had to provide the spring config file and one class, yes really, just one class. I used maven to generate the jaxb stuff and this is wat I did:
The spring-ws framework provides a special servlet that receives the requests. No the really hard part, the spring configuration for the endpoint:
First check the endpoint mapping, this class SimpleMethodEndpointMapping is found by the dispatcher to map all incoming requests to endpoints. In our case we map to our only endpoint called the congressRegistrationEndpoint. This class has a special super class that needs a marshaller and unmarshaller. Other than that it needs nothing. By convention the name of the Request is used by the super class to know which method to call. In our case we have a CongressRegistrationRequest. Therefore we need to implement to method handleCongressRegistrationRequest as you can see in the following coded block.
In this code the argument and the return value are JAXB objects. I created the most easy method, do nothing with the request and always return the same response. Bu as you can see the code itself is very clean. I do not need to do a lot of conding. I think this is probably one of the easiest implementations I have seen that works in java 1.4 as well.
That is it for one of the requirements. Now I also wanted a solution for generating the wsdl. In the end this is only some springframework configuration. You also need an xsd, but you have already used this to generate the jaxb classes with maven. So we can reuse it. Check the following configuration
So you need the location of the xsd, the name of the bean is used to find the wsdl. The locationUri locates the endpoint and the targetNamespace is the namespace used in the xsd. By entering the following url you can find the wsdl.
You can check the code at the google code project.
I know it is pretty short, but with the code you should be able to understand it.
Saturday, June 30. 2007
Last week I attended the SpringOne Congress in Antwerp. Just one or two days before the congress I wanted to create a proof of concept for a client connecting to a webservice. I have been using the proxy way (spring-remote), but I did not really like the way this works. Therefore I was looking for something else. I stumbled upon the Spring Webservices project. I did try this out before, but not for clients. I started working and it did not look very complicated. I must admit I needed the help from Arjen Poutsma himself to make it work, but now I have a very light weight solution. I like the approach very much, therefore I will briefly describe the solution I have created. You can of course find the sources online as well. Check the google code subversion repo for gridshore.
Overview of application
Maven 2 for buildingThis time not much details about the maven2 part. There are some things interesting though. Most important part is the creation of the jaxb generated classes using the maven2 jaxb2 plugin.
Using spring-webmv for web projectI do not think it is really interesting to talk a long time about this. There can be found a lot (better) resources online. I used the spring webmvc project to make the client i18n compatible, used the form controllers from spring to help with the error messages and validation stuff. For the webservices part the most interesting thing starts in the file service-applicationcontext.xml. This spring configurtion file contains the webservice client, the converters for jaxb (using generics to abstract the technique marshalling technique).
Webservice client created using spring-wsLet's start by having a look at the configuration:
This configured class is the class that knows how to connect to the webservice. It uses a few values and classes to do it's work. The defaultUri is used to find the endpoint to connect to (we obtain it from a property file). Since we use JAXB2 to marshall and unmarshall the request we need the marshaller and unmarshaller. These (un)marshallers are provided by spring-ws as well. Actually they are provided by spring-oxm. The interface for the marshaller is the same as for the unmarshaller. The only thing you need to provide is the package where the jaxb files are generatd in. The other two references are converters used to convert the application specific components to JAXB2 components. More on this later as well. So the most important class is the Gateway class. Let's have a look at that now.
This is it, really. I show you the complete class, but in the end the most important works takes place in one line. That's the one in bold. Here we use the special webServiceTemplate class and ask it to marshall our request object and send it as a soap message to the configured endpoint. Ofcourse you can do a lot more, but for most situations this is all it takes. Do not forget to extend the WebServiceGatewaySupport class.
Mapping between objects and xml using jaxb2 and spring-oxmNot much to tell here as well. I keep saying this, but that's because it is true. We have configured the marshaller and the unmarshaller which are provided by spring-oxm. We also call the right method from the template adapter called marshalSendAndReceive. I did create an interface and some implementations that enable the gateway to be ignorand to the type of marshalling and unmarshalling we use. This is my first try to do something with generics. There can be a better way, if you know one, please let me know as well . Let's start with the generic interface.
So we have an interface specifying we have a object as a parameter and an object as a return type. Then there is a method called convert that uses these generic types. At the moment I have two concrete implementations for creating the JAXB request and handling the JAXB Response. One of them is presented below.
As you can see we now have a concrete implementation for the generic interface. The returned object is a String and the parameter is a JAXB object called CongressRegistrationResponse. Now look back at the gateway code, check that there is no jaxb reference in that code.
Again check out the code at google code subversion repo for gridshore. You can already find the code for a server implementation there as well. The next blog will deal with the server. I am also working on a sample about the Rule engine called Drools. so stay tuned.
Sunday, June 25. 2006
Finally I found some time to start experimenting with a webservice. I know I am not the first to write about creating your own webservice, still I think this is worth reading. I am writing a step by step creation of a webservice via maven2, axis 1.4 and spring 2.0RC1. Ofcourse you can use older versions, but I want to be ready for the future and keep on using this sample. For now I am working with a HelloWorld sample. I will make it more complicated when needed to show interesting things.
Download the sources here
Step 1 - Configuring your maven project environment
We create a new directory to store all projects : ~/WebservicePoc
Within this directory use the archetype of maven to create a structure for a web project:
The groupid is used within the create pom. The artifactId is used as project id and to create the folder to store all files in. The archetypeArtifactId defines the type of structure to create, in our case a web project.
Now it is time to create the pom in the root project directory. Beware if you create this pom first, the archetype:create won't work. Execute the command in a temporary directory and copy the files into the sub-directory of the module we are creating.
For a complete look at the pom, have a look at the downloadable source code.
We also need to make some adjustments to the generated pom of the webservice-jaxrpc-style module. Again have a look at the sources. Time to try the first compile. Execute the following command in the root of the project:
Step 2 - Decide upon the libraries that we are going to use
For the application we are going to create we are going to use some libraries. We do not want to code ourselves to much. We are going to use the spring library and axis. Add these to the module pom.
You will notice a problem with spring and maven 2 at the moment of writing. Maven provides the solution in the error message, we need to install the maven library manually. There aresome other options, but for now this is the easiest one. First download spring version 2.0 RC1, than issue the following command:
Step 3 - Time to get the eclipse wtp to work
I want to deploy the webservice via tomcat and ofcourse I want a nice environment for debugging, deploying, and developing. I like to work with spring WebTools project, there is a pretty good integration with maven from the maven perspective. Lets use that. Fire up your eclipse (with wtp) and create a workspace. Do not create this workspace inside our projects, do it on another part of the disk. After creating this workspace, add the maven repository as a variable by using the following command:
Now let maven generate the eclipse project and classpath files, issue the following command:
You are ready to import the project into eclipse, "File > Import > Existing projects into workspace"
step 4 - Lets publish a webservice
The webservice is deployed within a web container. Both axis and the spring container run in a servlet. There is a connection between the two via the servlet endpoint which will be discussed in a while. These servlets are configured in the web.xml file. The template for the file is generated by maven, lets add the servlets, servlet mappings and a spring specific parameter.
This parameter specifies the locations where spring can find the configuration files for the container. The applicationContext.xml contains the definition of the beans in the Business service domain. There is another configuration file for spring thats needs to be present. This is the default spring config file based on the name of the servlet that configures the spring container. In our case this file does not contain any beans, but it must be available. It must be called action-servlet.xml since we have given the spring dispatcher servlet the name action. The file should reside next to the web.xml in the WEB-INF folder.
Here you can see the spring dispatcher servlet and the axis servlet. Most important to notice is the load-on-startup parameter that tells the order of loading the servlets. The axis servlet connects to the loaded spring context via the special endpoint. Therefore the spring servlet needs to be loaded first. You do not need the dispatcher servlet if you plan to expose only webservices. If you also want to include spring mvc or the like, you do need the dispatcher servlet.
Next task is to configure the axis webservice, this is done via the server-config.wsdd file.
We are creating a jaxrpc style webservice with the name JaxrpcwebserviceProvider. Axis should redirect all calls to this service to the endpoint of type ServiceProvider. This is a subclass of a special spring implementation of the servletendpoint, this class is will be discussed later on. As you can see from the wsdd file, all public methods are exposed via the webservice. As a transport object we use the MessageBean.
Now all configuration is in place, time to do some real coding. We need to implement the following classes and interfaces.
MessageService and MessageServiceImpl - Business service interface and implementation
MessageBean - Object returned via the jaxrpc webservice
RemoteMessageService - Remote interface that is implemented by the service endpoint and therefore implemented by the webservice.
ServiceProvider - the special webservice endpoint that contains access to the laoded spring context. The endpoint contains the method that is called via axis.
The most important class is the endpoint, this is the class that gets called by axis. The spring superclass takes care of obtaining the spring web context. You can use this context to find spring wired beans. In our case we use it to find the Business service object MessageService.
Time to fire up the server. You can use the run on server with a right mouse click on the project within eclipse wtp. Popup a browser and go to the following url:
That should give you an overview of all deployed services, probably only the JaxrpcwebserviceProvider.
Step 5 - Using xml spy to send a message via soap to the webservice
The webservice is deployed, you can have a look at the wsdl file, nice. Now we want to call the webservice. We can write a special java client. There is however an easier way with xmlspy. Since this blog item is all about exposing the webservice and not about creating a client, I will use xmlspy.
Fire up xmlspy and use the menu: SOAP > Create new soap request and enter the next url in the pop-up box:
After clicking oke, choose the getMessage() operating name, the following request is generated:
Then we can send the request over soap via xmlspy: SOAP > Send request to server
That concludes this article, I learned a lot while writing this item, hope you learned something while reading. The coming weeks I want to write about creating a client, doing document style webservices, using spring webservices component and security. Stay tuned.
(Page 1 of 1, totaling 5 entries)