Web Services na prática
Autores: Claúdio Lopes Furquim e JeffersonHenrique Marçal
1. Introdução
Este artigo apresenta uma demonstração de uso de Web Services utilizando plataformas heterogêneas.
Com a política de utilização de software livre no governo do Paraná, utilizamos como ambiente servidor plataforma Linux com desenvolvimento em Java, e mostraremos exemplos de clientes em ambiente livre e proprietários demonstrando a possibilidade de interoperabilidades entre aplicações.
Servidor Java
Para disponibilizar Serviços Web Java em plataforma Linux, usamos o gerenciador de container Java Apache Tomcat 4.1.18 com suporte a SOAP (Simple Object Access Protocol).
A instalação requer download do pacote Apache SOAP do site http://ws.apache.org/soap. Também precisamos de parser XML e optamos pelo Apache Xerces disponível para download em http://xml.apache.org.
Apache SOAP disponibiliza dois métodos de chamada de serviços: um RPC (Remote Procedure Call) e um baseado em mensagem (e-mail). O método RPC será o foco deste artigo.
Para usar Apache SOAP no ambiente Tomcat os arquivos “.jar” devem estar presente no diretório <TOMCAT_HOME>/common/lib: soap.jar, mail.jar, activation.jar, xerces.jar.
Aplicação exemplo
Para demonstrar o funcionamento do serviço criamos uma função exemplo que consulta uma Base de Dados via JDBC, contendo uma tabela de CEP (Código de Endereçamento Postal) e retorna um documento XML com o resultado da pesquisa. Os parâmetros da função são: Função “logradouro”, parâmetro de entrada: String contendo o código do CEP a ser pesquisado. Saída: String com XML de resultado.
Código do servidor Java
package CeleparWS;
import java.sql.*;
import java.io.*;
import org.w3c.dom.*;
import org.apache.xerces.dom.DocumentImpl;
import org.apache.xml.serialize.*;
public class Celepar{
private Connection conexao; // conexão com o banco de dados
private Statement comando; // comando SQL a ser emitido contra o banco
private String resposta = null;
private ResultSet rs = null;
// função logradouro
public String logradouro (String codigo) {
try{
String result=null;
Class.forName( “sun.jdbc.odbc.JdbcOdbcDriver” );
conexao = DriverManager.getConnection( “jdbc:odbc:cep”, “”, “” );
comando = conexao.createStatement( );
String cmd=”select * from DNELogradouros where codcep=”+codigo;
rs = comando.executeQuery(cmd);
if (rs.next( )) {
Element e = null;
Node n = null;
Document xmldoc= new DocumentImpl();
Element root = xmldoc.createElement(“CEPS”);
e = xmldoc.createElementNS(null, “TIPO”);
n = xmldoc.createTextNode(rs.getString( “tipo” ));
e.appendChild(n);
root.appendChild(e);
e = xmldoc.createElementNS(null, “TITULO”);
n = xmldoc.createTextNode(rs.getString( “tTitulo” ));
e.appendChild(n);
root.appendChild(e);
e = xmldoc.createElementNS(null, “LOGRADOURO”);
n = xmldoc.createTextNode(rs.getString( “logradouro” ));
e.appendChild(n);
root.appendChild(e);
e = xmldoc.createElementNS(null, “SEC”);
n = xmldoc.createTextNode(rs.getString(“seccionamento”));
e.appendChild(n);
root.appendChild(e);
e = xmldoc.createElementNS(null, “BAIRRO”);
n = xmldoc.createTextNode(rs.getString( “bairro” ));
e.appendChild(n);
root.appendChild(e);
e = xmldoc.createElementNS(null, “CIDADE”);
n = xmldoc.createTextNode(rs.getString( “cidade” ));
e.appendChild(n);
root.appendChild(e);
xmldoc.appendChild(root);
StringWriter fos = new StringWriter();
OutputFormat of = new OutputFormat(“XML”,”ISO-8859-1",true);
of.setIndent(1);
of.setIndenting(true);
XMLSerializer serializer = new XMLSerializer(fos,of);
serializer.asDOMSerializer();
serializer.serialize( xmldoc.getDocumentElement() );
resposta=fos.toString();
}else{
resposta=”Logradouro não encontrado”;
}
}catch(Exception e ){}
return resposta;
}
}
2. Registrando o serviço
Para que a aplicação fique disponível para o cliente é necessário realizar algumas configurações no servidor (“Deployement”). A instalação do pacote SOAP no servidor Tomcat disponibiliza uma interface para esta configuração, bastando informar o ID (identificação única). Exemplo: CeleparWS, escopo (no nosso caso Java application), o nome do método (exemplo: logradouro) e o nome da classe java responsável pelo processamento. Estas informações são necessárias para o Servlet gerenciador do Web Service em Java “/soap/servlet/rpcrouter” executar o serviço.
3. Clientes SOAP
A seguir mostraremos exemplos de aplicações clientes utilizando Java, JSP, PHP e ambiente Win32 Dephi6, Microsoft ASP, Vbscript que pode ser utilizado em Access, Excel, etc.
Cliente Java
import java.net.*;
import java.util.*;
import org.apache.soap.*;
import org.apache.soap.rpc.*;
public class ConsultaCEP {
public static void main(String[] args) throws Exception {
URL url = new URL (“http://10.15.21.146:8080/soap/servlet/rpcrouter”);
String cod = new String(args[0]);
Call call = new Call();
call.setTargetObjectURI(“CeleparWS”);
call.setMethodName(“logradouro”);
call.setEncodingStyleURI(Constants.NS_URI_SOAP_ENC);
Vector params = new Vector();
params.addElement(new Parameter(“codigo”, String.class, cod, null));
call.setParams (params);
Response resp = call.invoke(url, “” );
if (resp.generatedFault() ) {
Fault fault = resp.getFault ();
System.out.println(“The call failed: “);
System.out.println(“Fault Code = “ + fault.getFaultCode());
System.out.println(“Fault String = “ + fault.getFaultString());
}else{
Parameter result = resp.getReturnValue();
System.out.println(result.getValue());
}
}
}
Cliente JSP
O uso de Web Service em páginas JSP é basicamente o mesmo código acima, do cliente Java, que compilado pelo Tomcat é executado como Servlet.
<%@page contentType=”text/html; charset=iso-8859-1" language=”java”
import=”java.net.*,java.util.*,org.apache.soap.*,org.apache.soap.rpc.*”%>
<%
String XMLresp = “”;
try{
String cod = request.getParameter(“numcep”);
URL url = new URL (“http://10.15.21.146:8080/soap/servlet/rpcrouter”);
Call call = new Call();
call.setTargetObjectURI(“CeleparWS”);
call.setMethodName(“logradouro”);
call.setEncodingStyleURI(Constants.NS_URI_SOAP_ENC);
Vector params = new Vector();
params.addElement(new Parameter(“codigo”, String.class, cod, null));
call.setParams (params);
Response resp = call.invoke(url, “” );
if ( resp.generatedFault() ) {
Fault fault = resp.getFault ();
XMLresp = “Erro Code = “ + fault.getFaultCode()+”<br>”+
“Erro String = “ + fault.getFaultString();
}else {
Parameter result = resp.getReturnValue();
XMLresp = (String)result.getValue();
}
}catch(Exception e){
XMLresp = “CEP inválido”;
}
%>
<html>
<head>
<title>SOAP</title>
<meta http-equiv=”Content-Type” content=”text/html; charset=iso-8859-1">
</head>
<body>
<%=XMLresp%>
</body>
</html>
Cliente PHP
Para utilizar SOAP em aplicações PHP usamos um conjunto de classes denominado “NuSoap”. Está disponível “free” para download e uso em http://sourceforge.net/projects/nusoap.
Não requer instalação de extensão, basta disponibilizar o arquivo “nusoap.php” em um diretório visível para include.
<?php
// Obtém parâmetro CEP passado pelo form
$parmCEP = $numcep;
// include classes NuSOAP
require_once(‘nusoap.php’);
// define parâmetros
$param = array(‘codigo’=>(string)$parmCEP);
// define caminho para servidor da aplicação
$serverpath =’http://10.15.21.146:8080/soap/servlet/rpcrouter’;
//define nome do serviço
$namespace=”CeleparWS”;
// create client object
$client = new soapclient($serverpath);
// efetua a chamada
$resposta = $client->call(‘logradouro’,$param,$namespace);
if (isset($fault)) {
print “Erro: “. $fault;
} else {
print $resposta;
}
unset($client);
?>
Cliente WIN32
A maioria dos aplicativos win32 (Delphi, VB, Access, etc.) utilizam o arquivo WSDL (Web Services Description Language) na confecção da aplicação. Para auxiliar o programador, desenvolvemos uma página JSP que solicita o nome do Servidor, urn (uniform resource name), método e parâmetro, e como resultado tem-se um arquivo wsdl padrão para o objeto, conforme exemplo a seguir:
WSDL para CeleparWS
<?xml version=”1.0" encoding=”UTF-8" ?>
- <wsdl:definitions targetNamespace=”CeleparWS” xmlns=”http://schemas.xmlsoap.org/wsdl/” xmlns:intf=”CeleparWS” xmlns:soap=”http://schemas.xmlsoap.org/wsdl/soap/” xmlns:soapenc=”http://schemas.xmlsoap.org/soap/encoding/” xmlns:wsdl=”http://schemas.xmlsoap.org/wsdl/” xmlns:xsd=”http://www.w3.org/2001/XMLSchema”>
- <wsdl:message name=”logradouroResponse”>
<wsdl:part name=”resposta” type=”xsd:string” />
</wsdl:message>
- <wsdl:message name=”logradouroRequest”>
<wsdl:part name=”codigo” type=”xsd:string” />
</wsdl:message>
- <wsdl:portType name=”CeleparServicePortType”>
- <wsdl:operation name=”logradouro”>
<wsdl:input message=”intf:logradouroRequest” />
<wsdl:output message=”intf:logradouroResponse” />
</wsdl:operation>
</wsdl:portType>
- <wsdl:binding name=”CeleparServiceSoapBinding” type=”intf:CeleparServicePortType”>
<soap:binding style=”rpc” transport=”http://schemas.xmlsoap.org/soap/http” />
- <wsdl:operation name=”logradouro”>
<soap:operation soapAction=”” style=”rpc” />
- <wsdl:input>
<soap:body encodingStyle=”http://schemas.xmlsoap.org/soap/encoding/” namespace=”CeleparWS” use=”encoded” />
</wsdl:input>
- <wsdl:output>
<soap:body encodingStyle=”http://schemas.xmlsoap.org/soap/encoding/” namespace=”CeleparWS” use=”encoded” />
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
- <wsdl:service name=”CeleparService”>
- <wsdl:port binding=”intf:CeleparServiceSoapBinding” name=”CeleparServicePort”>
<soap:address location=”http://10.15.21.146:8080/soap/servlet/rpcrouter” />
</wsdl:port>
</wsdl:service>
</wsdl:definitions>
Delphi 6
A linguagem DELPHI 6 tem a vantagem de trazer nativamente suporte para SOAP através do componente HTTPRIO. Para escrever um cliente SOAP, basta importar o WSDL e utilizar o método publicado como uma simples função.
Utilize o componente SOAP da aba Web Services e assinale a propriedade WSDLlocation apontando para o arquivo wsdl do serviço.
Para importar o arquivo wsdl, execute File/New/Other/WebServices/WSDL Importer e terá o seguinte (parte) código “.pás” gerado:
……..
CeleparServicePortType = interface(IInvokable)
[‘{3147BCCC-0D19-A3E2-AA5B-3AF39550B767}’]
function logradouro(const codigo: String): String; stdcall;
end;
......
Código PAS da unit principal
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, Rio, SOAPHTTPClient, StdCtrls;
type
TForm1 = class(TForm)
Memo1: TMemo;
Button1: TButton;
HTTPRIO1: THTTPRIO;
Edit1: TEdit;
Label1: TLabel;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
uses CeleparWS;
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
var
str1: String;
begin
str1:= (HTTPRIO1 as CeleparServicePortType).logradouro(Edit1.Text);
memo1.Clear;
memo1.Lines.Add(str1);
end;
end.
ASP / VB /ACCESS / EXCEL
Para utilizar SOAP em ambiente Microsoft é necessário fazer downlaod do pacote Microsoft SOAP Toolkit disponível em http://www.microsoft.com/downloads. Para ASP, instalar o suporte a SOAP na máquina onde está rodando o IIS. Para Access, Excell, etc., deve estar instalado na máquina do cliente.
Exemplo de VBScript em ASP:
<%@LANGUAGE=”VBSCRIPT”%>
<html>
<head>
<title>CEP Web Services</title>
<meta http-equiv=”Content-Type” content=”text/html; charset=iso-8859-1">
</head>
<body>
<%
SET soapclient = CreateObject(“MSSOAP.SoapClient30”)
Call soapclient.mssoapinit(“c:CeleparWS.wsdl”,”cepService”,”cepServicePort”)
Response.write soapclient.logradouro(cLng(request(“numcep”)))
%>
</body>
</html>