2009年5月20日星期三

[fw-webservices] Re: [Question] How to create a Java client for a Zend_Soap server using autodiscover functionality

mouneyrac wrote:
> Hi Fabien,

Hi, and sorry for the late response, I'm in the middle of university exams :(

> my function example was more about to use complex parameters.
> If my Zend Soap Client can send array and object, why my java client can
> not?

I don't know Java clients very well, but Java is probably stricter than PHP...

The WSDL generated when using "@param array" uses soap-enc:Array, which is a bit
vague as it doesn't specify the type of the contained elements. Moreover, these
arrays are "flat" as far as I know.

In your case, you are expecting an *associative* array on the PHP side (with a
string as the key), which is a different matter.

If I remember correctly, PHP uses some kind of Apache "Map" type, defined in the
http://xml.apache.org/xml-soap namespace, for associative arrays. This seems to
be a fake URL though, and it won't give you an XML Schema for the Map type.. So I
don't think this solution is very interoperable at all. But again, I don't really
know Java clients. Maybe the solution is somewhere in Apache Axis? Maybe it could
magically convert a Java Hashtable into a "Map" that PHP understands ?

> To speak more about use case, I've got some functions called get_users,
> create_users, ... so you can see that I need to pass array containing
> objects. I think they are quite classic common web service functions. I
> guess there is a good way/pratice to use Zend_soap_server+autodiscover and
> be able to write a Java client?

Personally, I would use a PHP class to wrap these objects instead of an
associative array. For example:

class AuthData {
/** @var string */
$username;
/** @var string */
$password;
}

Then your web service class would look like that:

class ws_authentication {
/**
* Authenticate an user.
* @param AuthData $params
* @return integer
*/
public function get_token($params) {
if ($params->username == 'wsuser' && $params->password == 'wspassword') {
return '456';
} else {
throw new moodle_exception('wrongusernamepassword');
}
}
}

With this solution you should be able to get a Java client working, the only
downside is that you would have to create many classes if you have many
functions. But at least they would properly define what the client must provide.

Hope this helps.
- Fabien.

没有评论: