Un Saludo.
No me considero un experto en webservices, pero con la poca experiencia que he tenido, puedo dar un aporte que a mas de alguno le podra ser valioso a la hora de consumir web services. OJO estoy dando un aporte para CONSUMIR un ws y no para montar un server, lastimosamente no he tenido la experiencia de montar uno aun. Tomare como ejemplo el consumo de un webservice para loguearse a una pagina web x atraves de POO.
A ver, manos a la obra, para consumir un webservice lo primero que se necesita es un archivo con extension wsdl que te debe proporcionar la entidad que tiene el servidor, en este archivo, que no es mas que un xml, estan detalladas muchas cosas importantes, algunas se pueden leer a simple vista, otras es mas facil leerlas obteniendolas (mas abajo les muestro como), pero algo importante en este archivo para iniciar es tener la direccion donde sera consumido el wsdl, les pongo la siguiente parte de un wsdl como un ejemplo, y esta es la parte donde se define donde consumiremos el webservice
Código XML:
Ver original<wsdl:service name="miWebService">
<wsdl:port name="BasicHttpBinding_miWebService" binding="tns:BasicHttpBinding_miWebService">
<soap:address location="http://127.0.0.1:9091/miWebService/Services" />
</wsdl:port>
</wsdl:service>
Muchas veces, y casi siempre, cuando nos envian u obtenemos el wsdl, la direccion viene para local, y luego nos envian u obtenemos de otro lado la verdadera direccion, y con esto lo que debemos hacer es sustittuir esa direccion, por ejemplo, para dejarla asi
Código XML:
Ver original<wsdl:service name="miWebService">
<wsdl:port name="BasicHttpBinding_miWebService" binding="tns:BasicHttpBinding_miWebService">
<soap:address location="http://216.32.145.12:909/miWebService/Services" />
</wsdl:port>
</wsdl:service>
De esta forma, ya podremos consumir el web service.
Ahora bien, que mas necesitamos? necesitamos conocer los metodos/funciones y parametros, algunas veces nos lo pueden proporcionar, otras no, y la mayoria de las veces no se entiende que nos estan pasando, asi que para obtener esta info y tambien para depurar el consumo del ws, les dejo este codigo:
Código PHP:
Ver originalprint "<pre>\n";
print "Request : \n". ($ws->__getLastRequest()) ."\n";
print "RequestHeaders :\n". $ws->__getLastRequestHeaders() ."\n";
print "Response: \n". ($ws->__getLastResponse()) ."\n";
print "ResponseHeaders:\n". $ws->__getLastResponseHeaders() ."\n";
print "Functions: \n". var_export($ws->__getFunctions
(),true) ."\n"; print "Types: \n". var_export($ws->__getTypes
(),true) ."\n"; print "</pre>";
Si se ejecuta sin realizar una llamada al ws, unicamente nos devolvera la lista de funciones y parametros.
Ahora bien, como nos conectamos al webservice? yo lo estoy haciendo utilizando las funciones
SOAP que php tiene ya implementadas (NO ESTOY USANDO NUSOAP) y para definir el wsdl que vamos a utilizar se utiliza
SoapClient de la siguiente manera:
Código PHP:
Ver original$wsdl='miWebservice.wsdl';
$ws = new SoapClient
($wsdl,array("exceptions" => 1, 'trace'=>1, ));
Nota: agregamos array("exceptions" => 1, 'trace'=>1, ) para que nos devuelva los metodos y parametros, de lo contrario, no es necesario utilizarlo.
Muy bien, pero lo mas dificil, como le paso los parametros?
Bueno, esta parte ha sido lo mas dificil para mi, ya que nadie te explica ni te dice con claridad como enviar los parametros y como recibirlos, pero al obtener los metodos y funciones, esto se nos simplifica un poco, de esta manera, suponiendo que todo el codigo que he puesto esta bien configurado y el wsdl tambien, podemos usar lo siguiente para obtener los metodos y funciones:
Código PHP:
Ver originalclass SSON
{
public $wsdl;
public $request;
public $UsuarioInfo;
public $Code;
private function setWsdl($wsdl)
{
$this->wsdl='MiWebService.wsdl';
}
public function __construct()
{
$this->setWsdl();
}
public function LogIn($usuario,$password)
{
$this->request=array("user"=>$usuario,"password"=>$password); $ws = new SoapClient
($this->wsdl,array("exceptions" => 1, 'trace'=>1, )); $req = $ws->__soapCall
('LogonUser',array('LogonUser'=>$this->request));
print "<pre>\n";
print "Request : \n". ($ws->__getLastRequest()) ."\n";
print "RequestHeaders :\n". $ws->__getLastRequestHeaders() ."\n";
print "Response: \n". ($ws->__getLastResponse()) ."\n";
print "ResponseHeaders:\n". $ws->__getLastResponseHeaders() ."\n";
print "Functions: \n". var_export($ws->__getFunctions
(),true) ."\n"; print "Types: \n". var_export($ws->__getTypes
(),true) ."\n"; print "</pre>";
$res = $req->LogonUserResult;
if ($res->Code==0)
{
$this->setTicket($res->Ticket);
if ($this->TicketIsValid())
{
$this->request=array("ticket"=>$this->ticket); $req = $ws->__soapCall
('GetUserInfo',array('GetUserInfo'=>$this->request));
$res = $req->GetUserInfoResult;
if ($res->Code==0)
{
$this->setUsuarioInfo($res->Info);
return true;
}
else
{
return false;
}
}
else
{
return false;
}
}
else
return false;
}//end function
}
$test = new SSON();
$usuario="miusuario";
$password="mpassword";
if ($test->LogIn($usuario,$password))
{
echo 'ok <br>';
echo 'Nombrer: '.$test->UsuarioInfo->Nombre;
echo '<br>Apellido: '.$test->UsuarioInfo->Apellido;
echo '<br>Fecha Nac: '.$test->UsuarioInfo->FechaNac;
}
else
echo 'Error en login';
Muy bien, al ejecutar este ejemplo, asumiendo que el wsdl esta bien configurado, nos deberia devolver algo como lo siguiente:
Código TEXT:
Ver originalRequest :
miusuariomipassword
RequestHeaders :
POST /laurldelwsdl HTTP/1.1
Host: hostyportdelwsdl
Connection: Keep-Alive
User-Agent: PHP-SOAP/5.1.6
Content-Type: text/xml; charset=utf-8
SOAPAction: "http://miwebservice/LogonUser"
Content-Length: 335
Response:
0OK23974326-da86-4adc-845b-75abf0af8d91
ResponseHeaders:
HTTP/1.1 200 OK
Connection: Keep-Alive
Content-Length: 363
Date: Wed, 25 Aug 2010 16:05:13 GMT
Content-Type: text/xml; charset=utf-8
Server: Microsoft-IIS/7.5
X-Powered-By: ASP.NET
Functions:
array (
0 => 'TicketIsValidResponse TicketIsValid(TicketIsValid $parameters)',
1 => 'GetUserInfoResponse GetUserInfo(GetUserInfo $parameters)',
2 => 'LogonUserResponse LogonUser(LogonUser $parameters)',
3 => 'RegisterPersonUserResponse RegisterPersonUser(RegisterPersonUser $parameters)',
4 => 'ValidateUserRegistrationResponse ValidateUserRegistration(ValidateUserRegistration $parameters)',
5 => 'ExpireTicketResponse ExpireTicket(ExpireTicket $parameters)',
)
Types:
array (
0 => 'int char',
1 => 'duration duration',
2 => 'string guid',
3 => 'string ClientTypes',
4 => 'string UserStates',
5 => 'struct TicketIsValid {
string ticket;
}',
6 => 'struct TicketIsValidResponse {
TicketIsValidResult TicketIsValidResult;
}',
7 => 'struct TicketIsValidResult {
string Code;
boolean IsValid;
string Message;
}',
8 => 'struct GetUserInfo {
string ticket;
}',
9 => 'struct GetUserInfoResponse {
GetUserInfoResult GetUserInfoResult;
}',
10 => 'struct GetUserInfoResult {
string Code;
UserInfo Info;
string Message;
}',
11 => 'struct UserInfo {
ClientTypes ClientType;
string Email;
string FantasyName;
boolean IsClient;
string MovilePhone;
string Name;
string Sex;
dateTime BirthDate;
ArrayOfUserProductInfo Products;
base64Binary ProfileImage;
UserStates Status;
string SurName;
}',
12 => 'struct ArrayOfUserProductInfo {
UserProductInfo UserProductInfo;
}',
13 => 'struct UserProductInfo {
string Description;
boolean IsContactLine;
string ProductCode;
}',
14 => 'struct LogonUser {
string user;
string password;
}',
15 => 'struct LogonUserResponse {
LogonUserResult LogonUserResult;
}',
16 => 'struct LogonUserResult {
string Code;
string Message;
string Ticket;
}',
17 => 'struct RegisterPersonUser {
PersonRegistrationInfo newUserInfo;
}',
18 => 'struct PersonRegistrationInfo {
string Address;
dateTime BirthDate;
string DocumentId;
int DocumentTypeId;
string Email;
boolean IsClient;
string Locality;
string MobilePhone;
string Name;
string Neighborhood;
string Password;
string Sex;
string Surname;
}',
19 => 'struct RegisterPersonUserResponse {
RegisterPersonUserResult RegisterPersonUserResult;
}',
20 => 'struct RegisterPersonUserResult {
string Code;
string Message;
long RegistrationTicket;
}',
21 => 'struct ValidateUserRegistration {
long registrationTicket;
string validationToken;
}',
22 => 'struct ValidateUserRegistrationResponse {
ValidateUserRegistrationResult ValidateUserRegistrationResult;