Re: Web Services

  • Hello,
    I have a Cocoa app that uses web services and SOAP to talk to a server
    running the Java version of Axis (1.1).  The Axis service is
    rpc/encoded.  Complex types were a pain to figure out, and you're right
    that WSMakeStubs just doesn't really do anything with them.  For a
    complex type, which on the server side is a java bean, here's what I
    have to do:

    NSDictionary* authInfo = [[NSDictionary alloc] initWithObjectsAndKeys:
                                                [prefs
    stringForKey:@"login"], @"login",
                                                [prefs
    stringForKey:@"password"], @"password",
                                                @"Mac Client SOAP 0.1",
    @"userAgent",

    @"urn:myservice",kWSRecordNamespaceURI,

    @"authInfo",kWSRecordType,nil];

    Basically, I make a dictionary where the keys are the member vars of
    the complex type, in this case reading authentication info from prefs.
    Then at the end you stick a value for kWSRecordNamespaceURI and
    kWSRecordType.  This, so far, has worked perfectly for all the main
    cocoa objects, including when nesting complex types.

    For objects with int values, I use [NSNumber numberWithInt:x] and it
    seems to be encoded correctly.

    The exception is NSData objects, which are not encoded properly in
    10.3.  In 10.3 NSData objects are serialized as xsd:base64 which isn't
    valid as part of http://www.w3.org/2001/XMLSchema (should be
    base64Binary).  I reported this bug and it is supposed to be fixed in
    the latest Tiger posts, although I don't have the right kind of
    developer membership to verify it myself.

    If you don't need to send binary data, then you should be okay,
    otherwise, my workaround for Axis was in my deploy.wsdd I have my
    normal service description and then a second with a different name that
    adds a typeMapping like this:

            <service name="myservice" provider="java:RPC">
                    <parameter name="className"
    value="my.service.SOAPservice"/>
                    <parameter name="allowedMethods" value="*"/>
                    <beanMapping qname="pns:authInfo"
    xmlns:pns="urn:myservice"

    languageSpecificType="java:my.service.authInfo"/>
                  <!-- other beanMappings... -->
        </service>
            <service name="myservice-m" provider="java:RPC">
                    <parameter name="className"
    value="my.service.SOAPservice"/>
                    <parameter name="allowedMethods" value="*"/>
                    <beanMapping qname="pns:authInfo"
    xmlns:pns="urn:myservice"

    languageSpecificType="java:my.service.authInfo"/>
                  <!-- other beanMappings... -->
    <typeMapping qname="xsd:base64"
    xmlns:xsd="http://www.w3.org/2001/XMLSchema"
    languageSpecificType="java:byte[]"
    serializer="org.apache.axis.encoding.ser.Base64SerializerFactory"
    deserializer="org.apache.axis.encoding.ser.Base64DeserializerFactory"
    encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
    />
        </service>

    This routes the invalid base64 type that 10.3 sends to the normal
    de/serializers that Axis provides for base64Binary.  So then my OS X
    client uses the service myservice-m while Java and .NET clients just
    use myservice.

    Not sure how much this helps... the short answer is it is possible to
    use Web Services with Axis.

    Ben

    On Mar 14, 2005, at 12:02 PM, Fred McCann wrote:

    > I'm trying to write an OS X application as a front end to java
    > middleware. I would like to use SOAP web services to communicate with
    > the server. I'm running into a number of issues just getting off the
    > ground.
    >
    > 1. Core Web Services seems to have problems. WSMakeStubs doesn't
    > handle complex types well and I'm having problems getting WebServices
    > Core to handle simple xsd:int properties on objects.
    >
    > 2. I've evaluated gSOAP to create web service consumers in C and C++.
    > It took some effort to get this working. The problem I'm having here
    > is that the results of calling web services in this fashion are C
    > structs or C++ objects, which aren't very useful for plugging into
    > Objective-C based widgits. To use this as a solution, it appers that
    > I'd have to write a layer on top of gSOAP to convert C structs or C++
    > objects to Objective-C objects. Even for simple domain models, I can
    > see this getting out of hand quickly.
    >
    > 3. I've tried using Apache Axis to create service consumers in Java.
    > This works like a champ, but then I have to write the entire Cocoa
    > application in Java. It's my understanding that this is somewhayt
    > buggy and very uncommon. Also, this would shut me out of some OS X
    > features and frameworks
    >
    > 4. I'm making a test right now of the axis generated stubs and
    > calling them via the Java Bridge. This way I can have native
    > Objective-C code and wrap the portion that does the web service
    > communication. I'm not 100% sure that this will work or that it is
    > feasable for a large scale project. What's mroe worrisome is that this
    > Java Bridge is no longer supported.
    >
    > So, my question is this: Is anyone connecting Cocoa applications to
    > J2EE middleware? If you are, how are you going about it?
    > _______________________________________________
    > Do not post admin requests to the list. They will be ignored.
    > Cocoa-dev mailing list      (<Cocoa-dev...>)
    > Help/Unsubscribe/Update your Subscription:
    > http://lists.apple.com/mailman/options/cocoa-dev/<benlevy...>
    >
    > This email sent to <benlevy...>
  • I recently implemented axis ws in my application and ran into the same
    problems. After investigating using a Java object model (a PITA) I
    ended up implementing my own framework on top of WebServicesCore.
    ComplexTypes are not only a problem for serializing but also
    deserializing as the type or recordNamespaceURI and recordType are also
    lost in the WebServicesCore framework. ComplexTypes are encoded as
    dictionaries but the types are not placed in the dictionary.

    Benjamin, out of curiosity how did you solve deserializing complex
    types? I was fortunate enough to have a "type" attribute in our object
    model model that I could use to lookup local classes when deserializing
    NSDictionaries.

    - Byron

    On Mar 14, 2005, at 9:55 AM, Benjamin Levy wrote:

    > Hello,
    > I have a Cocoa app that uses web services and SOAP to talk to a server
    > running the Java version of Axis (1.1).  The Axis service is
    > rpc/encoded.  Complex types were a pain to figure out, and you're
    > right that WSMakeStubs just doesn't really do anything with them.  For
    > a complex type, which on the server side is a java bean, here's what I
    > have to do:
    >
    > NSDictionary* authInfo = [[NSDictionary alloc] initWithObjectsAndKeys:
    > [prefs
    > stringForKey:@"login"], @"login",
    > [prefs
    > stringForKey:@"password"], @"password",
    > @"Mac Client SOAP 0.1",
    > @"userAgent",
    >
    > @"urn:myservice",kWSRecordNamespaceURI,
    >
    > @"authInfo",kWSRecordType,nil];
    >
    > Basically, I make a dictionary where the keys are the member vars of
    > the complex type, in this case reading authentication info from prefs.
    > Then at the end you stick a value for kWSRecordNamespaceURI and
    > kWSRecordType.  This, so far, has worked perfectly for all the main
    > cocoa objects, including when nesting complex types.
    >
    > For objects with int values, I use [NSNumber numberWithInt:x] and it
    > seems to be encoded correctly.
    >
    > The exception is NSData objects, which are not encoded properly in
    > 10.3.  In 10.3 NSData objects are serialized as xsd:base64 which isn't
    > valid as part of http://www.w3.org/2001/XMLSchema (should be
    > base64Binary).  I reported this bug and it is supposed to be fixed in
    > the latest Tiger posts, although I don't have the right kind of
    > developer membership to verify it myself.
    >
    > If you don't need to send binary data, then you should be okay,
    > otherwise, my workaround for Axis was in my deploy.wsdd I have my
    > normal service description and then a second with a different name
    > that adds a typeMapping like this:
    >
    > <service name="myservice" provider="java:RPC">
    > <parameter name="className"
    > value="my.service.SOAPservice"/>
    > <parameter name="allowedMethods" value="*"/>
    > <beanMapping qname="pns:authInfo"
    > xmlns:pns="urn:myservice"
    >
    > languageSpecificType="java:my.service.authInfo"/>
    > <!-- other beanMappings... -->
    > </service>
    > <service name="myservice-m" provider="java:RPC">
    > <parameter name="className"
    > value="my.service.SOAPservice"/>
    > <parameter name="allowedMethods" value="*"/>
    > <beanMapping qname="pns:authInfo"
    > xmlns:pns="urn:myservice"
    >
    > languageSpecificType="java:my.service.authInfo"/>
    > <!-- other beanMappings... -->
    > <typeMapping qname="xsd:base64"
    > xmlns:xsd="http://www.w3.org/2001/XMLSchema"
    > languageSpecificType="java:byte[]"
    > serializer="org.apache.axis.encoding.ser.Base64SerializerFactory"
    > deserializer="org.apache.axis.encoding.ser.Base64DeserializerFactory"
    > encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
    > />
    > </service>
    >
    > This routes the invalid base64 type that 10.3 sends to the normal
    > de/serializers that Axis provides for base64Binary.  So then my OS X
    > client uses the service myservice-m while Java and .NET clients just
    > use myservice.
    >
    > Not sure how much this helps... the short answer is it is possible to
    > use Web Services with Axis.
    >
    > Ben
    >
    > On Mar 14, 2005, at 12:02 PM, Fred McCann wrote:
    >
    >> I'm trying to write an OS X application as a front end to java
    >> middleware. I would like to use SOAP web services to communicate with
    >> the server. I'm running into a number of issues just getting off the
    >> ground.
    >>
    >> 1. Core Web Services seems to have problems. WSMakeStubs doesn't
    >> handle complex types well and I'm having problems getting WebServices
    >> Core to handle simple xsd:int properties on objects.
    >>
    >> 2. I've evaluated gSOAP to create web service consumers in C and
    >> C++. It took some effort to get this working. The problem I'm having
    >> here is that the results of calling web services in this fashion are
    >> C structs or C++ objects, which aren't very useful for plugging into
    >> Objective-C based widgits. To use this as a solution, it appers that
    >> I'd have to write a layer on top of gSOAP to convert C structs or C++
    >> objects to Objective-C objects. Even for simple domain models, I can
    >> see this getting out of hand quickly.
    >>
    >> 3. I've tried using Apache Axis to create service consumers in Java.
    >> This works like a champ, but then I have to write the entire Cocoa
    >> application in Java. It's my understanding that this is somewhayt
    >> buggy and very uncommon. Also, this would shut me out of some OS X
    >> features and frameworks
    >>
    >> 4. I'm making a test right now of the axis generated stubs and
    >> calling them via the Java Bridge. This way I can have native
    >> Objective-C code and wrap the portion that does the web service
    >> communication. I'm not 100% sure that this will work or that it is
    >> feasable for a large scale project. What's mroe worrisome is that
    >> this Java Bridge is no longer supported.
    >>
    >> So, my question is this: Is anyone connecting Cocoa applications to
    >> J2EE middleware? If you are, how are you going about it?
    >> _______________________________________________
    >> Do not post admin requests to the list. They will be ignored.
    >> Cocoa-dev mailing list      (<Cocoa-dev...>)
    >> Help/Unsubscribe/Update your Subscription:
    >> http://lists.apple.com/mailman/options/cocoa-dev/<benlevy...>
    >>
    >> This email sent to <benlevy...>
    >
    > _______________________________________________
    > Do not post admin requests to the list. They will be ignored.
    > Cocoa-dev mailing list      (<Cocoa-dev...>)
    > Help/Unsubscribe/Update your Subscription:
    > http://lists.apple.com/mailman/options/cocoa-dev/
    > <byron...>
    >
    > This email sent to <byron...>
    >
    >
    >
  • I ended up just using dictionaries as my complex type representations
    for the OS X client.  This takes some of the fun out of SOAP, since you
    have to know the types returned by each call to the server and you
    can't map them to custom classes or anything, but I was used to XMLRPC
    before that so it didn't seem so bad.  Without a type attribute like
    you had, I can't see of any way to automatically convert to your own
    classes.

    Ben

    On Mar 14, 2005, at 4:07 PM, Byron Wright wrote:

    > I recently implemented axis ws in my application and ran into the same
    > problems. After investigating using a Java object model (a PITA) I
    > ended up implementing my own framework on top of WebServicesCore.
    > ComplexTypes are not only a problem for serializing but also
    > deserializing as the type or recordNamespaceURI and recordType are
    > also lost in the WebServicesCore framework. ComplexTypes are encoded
    > as dictionaries but the types are not placed in the dictionary.
    >
    > Benjamin, out of curiosity how did you solve deserializing complex
    > types? I was fortunate enough to have a "type" attribute in our object
    > model model that I could use to lookup local classes when
    > deserializing NSDictionaries.
    >
    > - Byron
    >
    > On Mar 14, 2005, at 9:55 AM, Benjamin Levy wrote:
    >
    >> Hello,
    >> I have a Cocoa app that uses web services and SOAP to talk to a
    >> server running the Java version of Axis (1.1).  The Axis service is
    >> rpc/encoded.  Complex types were a pain to figure out, and you're
    >> right that WSMakeStubs just doesn't really do anything with them.
    >> For a complex type, which on the server side is a java bean, here's
    >> what I have to do:
    >>
    >> NSDictionary* authInfo = [[NSDictionary alloc] initWithObjectsAndKeys:
    >> [prefs
    >> stringForKey:@"login"], @"login",
    >> [prefs
    >> stringForKey:@"password"], @"password",
    >> @"Mac Client SOAP 0.1",
    >> @"userAgent",
    >>
    >> @"urn:myservice",kWSRecordNamespaceURI,
    >>
    >> @"authInfo",kWSRecordType,nil];
    >>
    >> Basically, I make a dictionary where the keys are the member vars of
    >> the complex type, in this case reading authentication info from
    >> prefs.  Then at the end you stick a value for kWSRecordNamespaceURI
    >> and kWSRecordType.  This, so far, has worked perfectly for all the
    >> main cocoa objects, including when nesting complex types.
    >>
    >> For objects with int values, I use [NSNumber numberWithInt:x] and it
    >> seems to be encoded correctly.
    >>
    >> The exception is NSData objects, which are not encoded properly in
    >> 10.3.  In 10.3 NSData objects are serialized as xsd:base64 which
    >> isn't valid as part of http://www.w3.org/2001/XMLSchema (should be
    >> base64Binary).  I reported this bug and it is supposed to be fixed in
    >> the latest Tiger posts, although I don't have the right kind of
    >> developer membership to verify it myself.
    >>
    >> If you don't need to send binary data, then you should be okay,
    >> otherwise, my workaround for Axis was in my deploy.wsdd I have my
    >> normal service description and then a second with a different name
    >> that adds a typeMapping like this:
    >>
    >> <service name="myservice" provider="java:RPC">
    >> <parameter name="className"
    >> value="my.service.SOAPservice"/>
    >> <parameter name="allowedMethods" value="*"/>
    >> <beanMapping qname="pns:authInfo"
    >> xmlns:pns="urn:myservice"
    >>
    >> languageSpecificType="java:my.service.authInfo"/>
    >> <!-- other beanMappings... -->
    >> </service>
    >> <service name="myservice-m" provider="java:RPC">
    >> <parameter name="className"
    >> value="my.service.SOAPservice"/>
    >> <parameter name="allowedMethods" value="*"/>
    >> <beanMapping qname="pns:authInfo"
    >> xmlns:pns="urn:myservice"
    >>
    >> languageSpecificType="java:my.service.authInfo"/>
    >> <!-- other beanMappings... -->
    >> <typeMapping qname="xsd:base64"
    >> xmlns:xsd="http://www.w3.org/2001/XMLSchema"
    >> languageSpecificType="java:byte[]"
    >> serializer="org.apache.axis.encoding.ser.Base64SerializerFactory"
    >> deserializer="org.apache.axis.encoding.ser.Base64DeserializerFactory"
    >> encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
    >> />
    >> </service>
    >>
    >> This routes the invalid base64 type that 10.3 sends to the normal
    >> de/serializers that Axis provides for base64Binary.  So then my OS X
    >> client uses the service myservice-m while Java and .NET clients just
    >> use myservice.
    >>
    >> Not sure how much this helps... the short answer is it is possible to
    >> use Web Services with Axis.
    >>
    >> Ben
    >>
    >> On Mar 14, 2005, at 12:02 PM, Fred McCann wrote:
    >>
    >>> I'm trying to write an OS X application as a front end to java
    >>> middleware. I would like to use SOAP web services to communicate
    >>> with the server. I'm running into a number of issues just getting
    >>> off the ground.
    >>>
    >>> 1. Core Web Services seems to have problems. WSMakeStubs doesn't
    >>> handle complex types well and I'm having problems getting
    >>> WebServices Core to handle simple xsd:int properties on objects.
    >>>
    >>> 2. I've evaluated gSOAP to create web service consumers in C and
    >>> C++. It took some effort to get this working. The problem I'm having
    >>> here is that the results of calling web services in this fashion are
    >>> C structs or C++ objects, which aren't very useful for plugging into
    >>> Objective-C based widgits. To use this as a solution, it appers that
    >>> I'd have to write a layer on top of gSOAP to convert C structs or
    >>> C++ objects to Objective-C objects. Even for simple domain models, I
    >>> can see this getting out of hand quickly.
    >>>
    >>> 3. I've tried using Apache Axis to create service consumers in
    >>> Java. This works like a champ, but then I have to write the entire
    >>> Cocoa application in Java. It's my understanding that this is
    >>> somewhayt buggy and very uncommon. Also, this would shut me out of
    >>> some OS X features and frameworks
    >>>
    >>> 4. I'm making a test right now of the axis generated stubs and
    >>> calling them via the Java Bridge. This way I can have native
    >>> Objective-C code and wrap the portion that does the web service
    >>> communication. I'm not 100% sure that this will work or that it is
    >>> feasable for a large scale project. What's mroe worrisome is that
    >>> this Java Bridge is no longer supported.
    >>>
    >>> So, my question is this: Is anyone connecting Cocoa applications to
    >>> J2EE middleware? If you are, how are you going about it?
    >>> _______________________________________________
    >>> Do not post admin requests to the list. They will be ignored.
    >>> Cocoa-dev mailing list      (<Cocoa-dev...>)
    >>> Help/Unsubscribe/Update your Subscription:
    >>> http://lists.apple.com/mailman/options/cocoa-dev/<benlevy...>
    >>>
    >>> This email sent to <benlevy...>
    >>
    >> _______________________________________________
    >> Do not post admin requests to the list. They will be ignored.
    >> Cocoa-dev mailing list      (<Cocoa-dev...>)
    >> Help/Unsubscribe/Update your Subscription:
    >> http://lists.apple.com/mailman/options/cocoa-dev/
    >> <byron...>
    >>
    >> This email sent to <byron...>
    >>
    >>
    >>
    >
    >
    >

    ---
    Ben Levy :: Technology Development Manager, GoKnow, Inc.
    direct line - 734.929.6605 :: http://www.goknow.com/
previous month march 2005 next month
MTWTFSS
  1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30 31      
Go to today