der kl@mmeraffe | ruby. java. development.

a developers guide to the world of code

Tuesday, August 15, 2006

Working with wsdl2r, soap4r and complex types

Ruby has great support for SOAP built in. Trivial calls at least. Look at this example:

require 'soap/rpc/driver'
stub = SOAP::RPC::Driver.new("http://localhost:8080",
"http://somenamespace.com")
stub.add_method('gimmeAString', 'a_string')
p stub.gimmeAString("huhu!")

Easy, isn't it? You just create a new Driver object by handing over the location of the web service and its namespace. After that you can add the method you want to call and invoke it. Thats it. At least at the "Example-Stage". I real life, you need to declare complex types and use basic authentication and stuff. How to do that?
With soap4r, the standard soap framework for ruby, comes a nice script called "wsdl2ruby.rb". Example:
./wsdl2ruby.rb --wsdl coolWSDLFile.wsdl --type client 

That generates the complex types and the whole driver class you need to access your web service. Well, in theory, as brendon wilson describes in his article (thats written a lot better than this one here :-)). Because wsdl2ruby (and the whole wsdl4r part of the soap4r framework) is still in alpha stage, you can't expect too much. In my case, it couldn't handle all the complex types, so i had to fix it manually. Its not too difficult. Once you've got a generated driver you can add all necessary complex types that are missing and use the driver like in the first example at the top of this article.

A complex type definition looks like this (taken from the soap4r documentation):

require 'soap/mapping'

SampleStructServiceNamespace = 'http://tempuri.org/sampleStructService'

class SampleStruct; include SOAP::Marshallable
attr_accessor :sampleArray
attr_accessor :date

def initialize
@sampleArray = SampleArray[ "cyclic", self ]
@date = DateTime.now
end

def wrap( rhs )
@sampleArray = SampleArray[ "wrap", rhs.dup ]
@date = DateTime.now
self
end
end

class SampleArray < Array; include SOAP::Marshallable
end

To use this struct, just use it as a type in the method-definition:
stub.add_method('anotherMethod', 'sampleStruct')

btw, soap4r comes bundled with lots of extremely helpfull examples for all kind of usages.

As of basic authentication, you need to install http-access2.

With an additional line of code,
stub.options["protocol.http.basic_auth"] 
<< ["ws_url", "username", "password"]

basic authentication is done. More Information on that at Chris McMahons Blog

The SOAP implementation in Ruby itself is great. It seems to be reliable and it is rubyish to code (i.e "easy"). The wsdl2ruby generator needs some more work (i tried a second wsdl file, but that too didn't work), but it helped me a lot to write a SOAP-driver for my specific web service.

Another nice tutorial is here.

add to del.icio.us | submit to digg | submit to reddit

Wednesday, August 09, 2006

Java Stack Traces

add to del.icio.us | submit to digg | submit to reddit

Tuesday, August 08, 2006

Rails: All those little things

Image you've got a List (or an Array or whatever you like to call it) with objects. Those are articles with lots of fields. And you want to sort this List by one of its fields.
One thing some love (or hate) bout ruby is its use of blocks. Some say they are the most powerful thing imaginable, some say doing 2.times {p blub} isn't that cool (maybe they are both wrong and right).
Whatever. To sort a List is not a nice task in lots of programming languages. But look at this:

articles.sort! do |a, b|
a.value <=> b.value
end

Got it? You tell the List to sort itself (by calling the sort-method and putting a block in it). The block uses a funny operator that return -1, 0 or 1, depending on which element is bigger. The method uses this information to sort the List.

Those are the little things why i really like to code in ruby (with or without rails)

add to del.icio.us | submit to digg | submit to reddit

Sunday, August 06, 2006

Going on with Rails

Yesterday i started coding a small web app involving rss, mysql and stuff. Of course i chose Rails to check out how rapid and clean its possible to implement what i wanted to. I haven't that much with Rails till now, just a little testing. But the last to days (well, just for a couple of hours) it was possible for me to implement the database model + O/R mapping, the views, the rss-feed-aggregation-logic and user-management. Without even knowing the pitfalls or tricks in Rails i've done all of this in less than 4 hours or something (with my brain thinking how to do the design. coding was a joke!).
In Rails its fast to implement a web app because:

1. The ActiveRecord-Stuff.
Tell your app which database you use, generate models for the tables. Thats it for O/R mapping. When u change a field in the db, ActiveRecord dynamically changes its behaviour. And its extremely intuitive. Imagine a table "Customer". What if you want to find all of your customers? Right, just do
Customer.find_all
(or, nowadays:
Customer.find(:all)
). You want to change the customer-id? Type
customer.id = 1

Want to save the changes? Type
customer.save

There is nothing you have to code for the db-model in Rails.

2. Use of Ruby
I wanted to read rss-feeds. Of course, you can do this in every language imaginable. But with Ruby, its a sure bet that its extremely easy. I used "FeedTools":
@feedxml = FeedTools::Feed.open(feed.address)

now you can use the feed as a plain old ruby object.

3. no config
For some it may be a drawback to follow the conventions of Rails. Using plural-forms for tables isn't something everybody likes (including me), but when you create a "Customers"-Table you just have to generate your model "Customer" to dynamically access it. Same with actions in the controller. Create a method "login" and a rhtml "login". Now you can jump to localhost:3000/login and everything is done for you. Maybe for bigger apps thats not perfect but its great for prototyping.

4. No code bloat or bloated framework
The written code is always in Ruby, so its never to long, easy to read and to maintain. Rails has lots of stuff you will find handy but doesn't come with every latest technology every java developer have to fight with ;-)

I'll code along over the next couple of weeks, if the final app is something interesting i'll post it here :-)

add to del.icio.us | submit to digg | submit to reddit