Dashboard > RIFE > ... > Webservices > SOAP web services and MetaData merging
RIFE Log In | Sign Up   View a printable version of the current page.
SOAP web services and MetaData merging


Added by Hynek Schlawack, last edited by Hynek Schlawack on Dec 12, 2006  (view change)
Labels: 
(None)

As already mentioned in Support for Hessian web services, RIFE's MetaData merging can be tricky when used together with web services which have to serialize the object.

The mentioned solution can't be easily adopted, because the SOAP is – even via XFire – a bit more complicated. The solution I went for, contains sub-classing:

For SOAP, we need a "pure" Bean, w/o any pollution through RIFE. As I want to have the Beans with MetaData for everything but SOAP, I implemented a second API just for SOAP and the "pure" Beans have special names – in this case they are prepended with the word "Bean".

Let's look at an example:

BeanFoo.java
public class BeanFoo {
    protected int val;

    public BeanFoo() {
    }

    public void setVal(int val) {
        this.val = val;
    }

    public int getVal() {
        return val;
    }
}

This is the Bean the SOAP-API is going to use.

Now let's define our Bean with MetaData for everything else (eg. DB access):

Foo.java
public class Foo extends BeanFoo {
    public Foo() {
    }

    public Foo(BeanFoo beanFoo) {
        this();
        val = beanFoo.val;
    }
}

The default constructor is really important here, as the MetaData gets only merged, if the object is instantiated using the default constructor. If you want one with arguments, don't forget to call the default constructor using this() inside of it. NB, that this approach wouldn't work if there wouldn't be the automatic merging, because Java has no multiple inheritance.

Now you just write your Adapter which wraps the class you want to expose (see Support for SOAP web services) and takes care to cast your beans to the "pure" ones.

Assuming your class looks like this:

Bar.java
public class Bar {
    private Foo foo;

    public Bar() {
        foo = new Foo();
    }

    public Foo getFoo() {
        return foo;
    }

    public void setFoo(Foo foo) {
        this.foo = foo;
    }
}

You'll need an adapter like this:

SoapBar.java
public class SoapBar implements SoapBarApi {
    private Bar bar;

    public SoapBar() {
        bar = new Bar();
    }

    public BeanFoo getFoo() {
        return bar.getFoo(); // Downcasts are no problem
    }

    public void setFoo(BeanFoo foo) {
        bar.setFoo(new Foo(foo)); // We need a copy-constructor in Foo for the upcast
    }
}

The definition of the interface is trivial an thus omitted. The conclusion is that there's a bit too much unnecessary boiler plate code – especially when being used to RIFE – and let's hope, that the XFire guys are going to support RIFE's MetaData in the near future.



Are you enjoying Confluence? Please consider purchasing it today.
Powered by Atlassian Confluence, the Enterprise Wiki. (Version: 2.2.1a Build:#515 May 19, 2006) - Bug/feature request - Contact Administrators