This week's book giveaway is in the Other Open Source APIs forum. We're giving away four copies of Storm Applied and have Sean Allen, Peter Pathirana & Matthew Jankowski on-line! See this thread for details.
I did the 'pojo' sample for Axis2 1.5 web services. The pojo had a few private String attributes wrapped in sets and gets as per normal. It works fine.
I modified the pojo (de-pojo-ing it) so that it had a private HashMap within and added the appropriate setters and getters. The web service "works" partially - the String values are still being passed from client to server - but the HashMap isn't being included in the fun. I looked at the WSDL (which is tiny) and the reason is clear - the String variables are referenced but the HashMap variable is not.
What should I do to make sure the HashMap is serialized and passed to the server?
I realize this is a newb question, but since I don't know what any of this is called, I don't know what to look up to find the answer.
Give me a few search terms please, and I'll be happy to read like the wind.
The problem you have is related to marshaling, essentially when Axis tries to create a soap message from your pojo, it can't because there is no corresponding xml data type corresponding to a java.util.HashMap...
There are tricks to work around it..you could build a java to xml adapter and configure your binding framework to use this adapter..basically when Axis runtime converts the java to an xml it should use this adapter...to figure out your custom mechanism to convert a hashmap to a custom defined xml type..
Now go google...
OCMJEA/SCEA, SCDJWS, SCBCD 1.3, SCJP 1.4
My SCEA experience:http://javalogue.blogspot.com/
Joined: May 22, 2003
Ok, I need another hint. I was unable to do anything with a HashMap. However, I had some success with an ArrayList.
Anyway, the Axis2 server is generating my WSDL on the fly. I don't have it, nor do I use it. My client is very simple and wasn't built using wsdl2java. Have I fallen into a newb 'hello world' trap wherein critical pieces are ignored because in the trivial case they aren't needed? And now that I need a little more complexity I am dead in the water? If so should I start with the WSDL being generated by Axis2, copy it, and put it into my app's META-INF folder? Then I can modify it...
I'm pretty frustrated. If it didn't know what a HashMap was, it should have given me an error, not silently ignored it. My web service returns an ArrayList of strings. It isn't working - instead, it is returning each item in the 'incoming' arraylist as multiple arraylists, each having one string in it. That's clearly wrong. I did far more complex things 10 years ago by serializing classes and sending them back and forth.
I'm on the clock. I don't have time for this. I could just do this if I forego collections and so forth and use pipe-separated Strings and so forth - and parse them into collections or whatever as appropriate.
I like to use collections for their helpful features, but I keep them internal to my class. If I pass them around as an array of objects (in this case String) there should be no problem accessing. Also, this simple structure allows you to easily pass back an updated array that you can use back in the web svc.
Joined: May 22, 2003
Ok, let's take another tack.
When I deploy the web service and then read its wsdl using http://localhost/axis2/services/MyPain?wsdl I get a wsdl that just seems wrong. There is no provision for the class I'm passing to contain anything complex. Further, there's no provision for the ArrayList I'm trying to return.
My service looks something like this:
And ComplexClass is something like this:
That being said, I ran a java2wsdl that's built into my IDE (I do not know the parameters it uses) and got a *far* different wsdl file (in fact it is 3 files, 2 wsdl and one xsd. The main wsdl includes the other 2 files.) This wsdl includes type information including something for the hashmap. I made an aar file and placed the uber wsdl file in the META-INF folder. The wsdl is invalid or not being seen, unfortunately. I have tried naming it service.wsdl and MyPain.wsdl. Nothing changed. Browsing the ...?wsdl url returns
I have placed "<parameter name="useOriginalwsdl">true</parameter>" into the services.xml file. I didn't want it to generate a wsdl - I wanted it to use the one I supplied.
So in summary:
1. The wsdl generated automatically is wrong. If anyone has any hints on how to tweak the generation process, perhaps by putting annotations in the source files, I'd love to hear it.
2. I can't make axis2 recognize and use a wsdl I supply in the aar file. If anyone has any experience doing this, I'd love to hear about it.
3. Does anyone actually use this stuff using anything more complex than the 'stock symbol' sort of case?
I'm dead in the water now.
Joined: May 22, 2003
I replaced the HashMap with an array of SimpleClass, where SimpleClass was nothing more than a pojo containing a single String tag and a single String value pair and their setters and getters.
I had problems with the service returning an arraylist, so I changed it so it returned a String. This still didn't work. When the results were coming back from the service, the marshaling was failing with an array out of bounds exception. My guess is that invokeBlocking wasn't smart enough to create String of sufficient length.
So knowing I probably needed to return a scalar, I wrapped String in AnotherSimpleClass, a pojo having String and a setter and getter. I then made the service return AnotherSimpleClass.
I experimented with putting an ArrayList in AnotherSimpleClass instead of String. I was able to pick the data out of it but the types were wonky showing that something was getting confused. The items in the ArrayList were of type OMElementImpl instead of String.
1. Use arrays, not arraylists.
2. Simple classes seem to marshal ok.
3. Return one item instead of a collection.
Thanks for the assist all!
subject: I am passing a non-pojo to a web service. Not all attributes are being marshalled