Thursday, March 20, 2008

Lessons learned with Web Services in Eclipse 6

I am using MyEclipse 6. It is quite nice. I learned the hard way were to find some resources and how to do things like Exception handling. I found the process to be much more difficult and the learning curve much steeper than I thought it would be. Here are some things I learned. MyEclipse has a project type called Web Service Project. Use this to start a new project that will be your web service. It also allows you to use XFire web services (not CXF until version ?? of MyEclipse). You can use Java 1.5 or Java 5. Getting Started:
Start with the tutorial I mention in my blog to get started: http://www.myeclipseide.com/documentation/quickstarts/webservices/
Examples: Get the XFire distribution (http://xfire.codehaus.org/Download and pick the Binary Distribution in zip package for the newest release) because it has some good examples in it. I didn't find this until way too late. You can also download the source code for XFire on this page if you want to also. Once you download the zip I highly recommend the Book example. It shows how to return complex types, and how to create your own custom exceptions. How to store application settings
I am sure there are many ways to do this... check out my blog on: http://justgeeks.blogspot.com/2008/03/storing-application-settings-in.html Make Complex types that use java.util.Date as a data type be nillable when generated in the WSDL.
The basic solution is create a file called YourClassNameHere.aegis.xml and put it in the same location as the class that defines the complex type that contains the java.util.Date property. In the file, do something like this:
<mappings>
<mapping>
<property name="datePropertyName" nillable="true"/>
<property name="anotherDatePropertyName" nillable="true"/>
</mapping>
</mappings>
Now your automatically generated WSDL will have nillable="true" for the properties that you specified in the mapping file. This is particular important when using ASP.Net 2.0 and Nullable Types to consume your web service. It means the difference between DataTime and DateTime?. For more details check out: http://www.nileshk.com/node/69#comment-12609 Exception Handling You can follow the example in the Book example noted above, or you can do it another way also. You can do much like they did in the Book example, except just have your custom exception class extend java.lang.Exception instead of the XFire specific type. This will cause your custom exception class to be serialized and set as the Detail property in the SoapException. You can then parse it using a standard XML parser on the client side. You will be catching an Exception of type SoapException on ASP.Net. If you want your properties of your custom exception class to show up in the serialized text, you will need to make sure that you have setters and getters for each member variable in your class. One key is that your web methods must explicitly throw your custom exception, not just java.lang.Exception. If you don't, the Detail property of the SoapException won't be filled in when it is serialized and sent to your client (web service consumer). This basically tells Aegis to use our custom exception type instead of just java.lang.Exception. Changing parameters (in0, in1, in2, etc) to the real names when the WSDL is generated. I searched long and hard to find a simple solution for this one. Much to my amazement there did not seem to be too many intuitive solutions. I picked the easiest one. My solution is very simple and requires no maintenance. It seems to be a bug to me, so.... Do just like the tutorial referenced in the Getting Starting section of this blog and add the new web service just as says EXCEPT when you get to the page that asks you for the Service Interface and Service impl. class, set the Service interface to the same thing as Service impl class. This will affect your server.xml file. Finish the wizard as noted in the tutorial. Next, open the xxxImpl.java file and remove the implements xxxx from the class declaration such that it does not implement the interface file. If there is an interface file you can safely remove it from your project now. You will never need it now. Now, when the WSDL is generated it will use the proper parameter names as you would expect. Go figure! Word of caution, I did not have as much luck doing effectively manually doing the same thing AFTER I did the wizard as the tutorial suggests. So, I suggest doing it from the start when you do it in the wizard. I also found that I couldn't query the for the WSDL without my CPU going to nearly 100% when I did it manually. I don't really know why, but it did. I suspected that maybe I just had to many methods in my class and was slowing the parsing of the class to generate the WSDL or something, so I put all my real code in another class and just have stub like web methods that simply call the other object and a method on it. This seemed to help, but all these issues could have been do to needing a reboot and trying too many different things and messing up some files. Hard to tell, so let me know if anyone else has a similar experience. Other Tips Make your life easier, just forget about getting access to the Request and other servlet type things. It is just too much of a pain. Stay away from web.xml when it comes to storing application settings. Accessing it programmatically seems to be container (application server) specific, so use a properties file or xml file.

No comments: