Autor
Neste artigo apresento o Marcos de Melo Siega, que pode ser contatado pelo e-mail marcosmsiega@gmail.com. O Marcos foi meu aluno em algumas disciplinas de sua graduação e está concluindo o último período do curso de Tecnologia em Análise e Desenvolvimento de Sistemas da UTFPR campus Medianeira neste primeiro semestre de 2013. Trabalhou recentemente no setor de desenvolvimento de sistemas da empresa Itaipu Binacional.

1. Introdução

Um Web Service (Serviço Web) é um sistema de software projetado para suportar interação máquina-a-máquina interoperáveis sobre uma rede. Ele tem uma interface descrita em um formato processável por máquina (especificamente WSDL). Outros sistemas interagem com o Web Service de uma maneira prescrita por sua descrição usando mensagens SOAP, normalmente transmitidas por meio do protocolo HTTP com uma serialização XML e em conjunto com outros padrões relacionados à Web [W3C2004].

Este artigo apresenta detalhes da implementação de um Web Service utilizando a plataforma JEE6, o uso da API SAX para realizar a interpretação do descritor do serviço criado e a implementação de duas diferentes aplicações que farão o consumo do serviço criado, uma aplicação em C# e outra utilizando a tecnologia Java.

2. Implementação

Esta seção apresenta as etapas sugeridas para a criação de um Web Service sobre a plataforma JEE6, bem como a descrição dos recursos utilizados no processo de desenvolvimento.

2.1. Requisitos

A seguir estão listados os recursos necessários para a composição do ambiente de desenvolvimento:

2.2. Implementação

Com o ambiente de desenvolvimento instalado e corretamente configurado será dado início ao processo de implementação do Web Service.

2.2.1 Criação do Projeto

Para começar, criou-se um Novo Projeto no IDE NetBeans, e optou-se pelo tipo Aplicação Enterprise, como demostrado na Figura 1.

Janela do wizard para criação de um Novo Projeto na IDE NetBeans

Figura 1: Janela do wizard para criação de um Novo Projeto na IDE NetBeans

Em seguida, faz-se necessária a especificação do nome e da localização do projeto, conforme Figura 2.

Janela do wizard para definição do nome e da localização do projeto criado

Figura 2: Janela do wizard para definição do nome e da localização do projeto criado

Para finalizar, é necessário realizar configurações de características importantes do Novo Projeto. Definiu-se qual servidor de aplicação hospedará o projeto, a versão da plataforma Java utilizada, a ativação da injeção de contextos e dependências, o nível do código-fonte para adaptar-se ao JEE 6 e optou-se pela criação automática de um módulo EJB, conforme Figura 3.

Janela do wizard para definição das configurações finais do Novo Projeto

Figura 3: Janela do wizard para definição das configurações finais do Novo Projeto

2.2.2. Implementação do Web Service

Tendo criado o projeto, inicia-se a implementação do Serviço Web. Para começar, um novo Bean de Sessão (EJB) deve ser gerado dentro do módulo criado automaticamente na definição o Novo Projeto, conforme Figura 4, e este servirá de base para geração automática do Serviço Web.

Um nome para o novo EJB deve ser dado, a localização do Bean deve ser definida, e deve ser marcado como sendo Stateless, ou seja, destina-se a executar automaticamente operações individuais, não mantendo o seu estado para cada invocação de um método.

Janela do wizard para configuração do Novo EJB

Figura 4: Janela do wizard para configuração do Novo EJB

Tendo gerado o EJB, faz-se a implementação de um método nele, de acordo com a Listagem 1, que estará disponível no serviço gerado posteriormente.

Listagem 1: Implementação do EJB que servirá de base para a geração do Web Service


package EJBs;
import javax.ejb.LocalBean;
import javax.ejb.Stateless;
//EJB que não preserva estado para cada invocação de método.
@Stateless
//EJB estará disponível somente no contexto do servidor de aplicação
@LocalBean
public class Operacoes{
//Método que realiza a soma de dois valores reais 
public float soma(float numero, float outroNumero){
    return numero+outroNumero; 
};
}

Este EJB servirá de base para a geração automática do Web Service. Para tal, devem-se realizar os procedimentos apresentados nas Figuras 5 e 6.

Nesta etapa seleciona-se o tipo do arquivo criado. Na categoria Web Services encontra-se o tipo que deve ser criado, neste caso o tipo desejado é Web Service.

Janela do wizard para criação de Novo Web Service

Figura 5: Janela do wizard para criação de Novo Web Service

Janela do wizard para configuração do Novo Web Service

Figura 6: Janela do wizard para configuração do Novo Web Service

Na etapa apresentada pela Figura 6, deve ser especificado um nome para o serviço Web, sua localização no projeto e a criação do Web Service a partir de um Bean de sessão existente. O Bean existente pode ser encontrado por meio da opção “Procurar”, disponível na janela do wizard.

Após realizar estas configurações, basta selecionar a opção de finalizar. O resultado desta etapa é o serviço apresentado na Listagem 2.

Listagem 2: Web Service gerado automaticamente utilizando o EJB criado


package servicos
import EJBs.operacoes;
import javax.ejb.EJB;
import javax.ejb.Stateless;
import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebService;
//Anotação de definição de um serviço, bem como sua nomeação.
@WebService(serviceName = “ServicoOperacoes”)
//Anotação que define que o EJB não preserva estado para cada invocação de método.
@Stateless
public class ServicoOperacoes{
 //Injeção do EJB que possui o método que se deseja acessar.
@EJB
private  Operacoes ejbRef;
//@WebMethod – Serve para informar o nome do método ao gerador do WSDL.
//@WebParam – Serve para informar o nome do parâmetro ao gerador do WSDL.
@WebMethod(operationName = “soma”)
public float soma(@WebParam(name =”numero”) float numero, @WebParam(name = “outroNumero”) float outroNumero){
      return ejbRef.soma(numero, outroNumero);
}
}

Concluída a implementação do Web Service, resta apenas realizar sua implantação no servidor de aplicação GlassFish.

A Figura 7 apresenta o resultado da bem sucedida implantação do Web Service no servidor de aplicação.

Resultado da implantação do Web Service no servidor de aplicação Glassfish

Figura 7: Resultado da implantação do Web Service no servidor de aplicação Glassfish

Neste momento o serviço está disponível para consumo, e para tal, este artigo demonstra, nas seções seguintes, a implementação de dois clientes, um deles utilizando a tecnologia Java e outro C#.

Além dos clientes, utilizou-se a biblioteca SAX de processamento de XML para interpretar o descritor do serviço recém-criado.

3. Uso da API SAX (Simple API for XML)

SAX é uma API simples para manipulação de arquivos XML disponível para a plataforma Java. SAX foi a primeira API amplamente adotada para XML em Java, por este motivo é considerada padrão. Sua versão atual é SAX 2.0.1, e há versões para diversos ambientes de programação diferentes do Java. [Megginson 1998].

Esta seção apresenta um programa Java que ilustra a utilização prática da API SAX. O programa realiza o processamento do documento XML com informações sobre a descrição do serviço criado na seção anterior, representado pela Figura 8.

O XML contendo a descrição completa do serviço estará disponível no endereço fornecido pelo servidor de aplicação no momento em que a implantação ocorre. No exemplo trabalhado o descritor estará disponível através do seguinte endereço:

http://localhost:8080/ServicoOperacoes/ServicoOperacoes?wsdl

Estrutura do XML descritor do serviço implementado neste artigo

Figura 8: Estrutura do XML descritor do serviço implementado neste artigo

O programa Java é apresentado na Listagem 3. A classe MyParser processa o documento XML com o uso da API SAX, recuperando informações sobre as operações disponíveis. A explicação sobre o funcionamento do programa é apresentada no interior do código, em forma de comentário.

Listagem 3: Implementação do Parser Java utilizando a API SAX


package parser;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
 
public class MyParser extends DefaultHandler{
 static Map<String, String> operacoes = new HashMap<String, String>();
 private String tagAtual;
 private String siglaAtual;
//Método que fará o parsing do arquivo utilizado no argumento do método
 public void parsing(String pathDoArquivo){
 //Criação de uma instância da classe javax.xml.parsers.SAXParser, através da fábrica (factory) SAXParserFactory 
SAXParserFactory fabrica = SAXParserFactory.newInstance();
SAXParser parserSax;
try{
        parserSax = fabrica.newSAXParser();
//O “this” passado como argumento do método seguinte indica que a própria classe atuará como gerenciadora de eventos SAX
         parserSax.parse(pathDoArquivo, this);
//Tratamento de exceções
}catch(ParserConfigurationException | SAXException | IOException e){
       StringBuffer msg =  new StringBuffer();
       msg.append(“Erro:\n”);
       msg.append(e.getMessage()+”\n”);
       msg.append(e.toString());
       System.out.println(msg);
}
}
 //Método startDocument do SAX. Disparado antes do processamento da primeira linha do arquivo XML.
public void startDocument(){
        System.out.println(“Iniciando o parsing...”);
}
//Método disparado após o processamento da última linha do arquivo XML
public void endDocument(){
        System.out.println(“Encerrando o parsing...”);
}
//Método invocado quando o processador SAX identifica a abertura de uma Tag
public void startElement(String uri, String localName,String qName, Attributes atts){
 //Recupera o nome da Tag atual
         tagAtual = qName;
//Adiciona ao mapa caso encontre a Tag “<operation>”
    if(qName.compareTo(“operation”) == 0){
         siglaAtual = atts.getValue(0);
         operacoes.put(siglaAtual,”operation”);
     }
}
//Método disparado quando encontrado o fechamento de uma Tag
public void endElement(String uri, String localName, String qName) throws SAXException{
          tagAtual = “ ”;
}
 
public static void main(String[] args) throws Exception{
    if(args.length != 1){
        System.err.println(“Erro! Exemplo de utilização ‘MyParser   nome_do_XML’);
        System.exit(1);
     }
      MyParser meuParser = new MyParser();
      meuParser.parsing(args[0]);
   for(Entry<String,String> entrada : operacoes.entrySet()){
       System.out.println(“Operação = ”+entrada.getKey() );
    }
}
}

A classe MyParser processa o documento XML com o uso da API SAX, recuperando as informações sobre as operações disponíveis no serviço Web e as exibe na tela.

MyParser é uma subclasse de org.xml.sax.helpers.DefaultHandler, que faz com que ela ganhe automaticamente um processador SAX com o comportamento padrão.

4. Aplicações Clientes

Visto a criação do Web Service, as próximas seções apresentam a implementação de duas aplicações clientes que consumirão as operações oferecidas.

4.1 Java

Cria-se nesta seção uma aplicação Java que fará o consumo do Web Service desenvolvido. Os passos para a criação deste aplicativo podem ser vistos nas Figuras 9 e 10.

Janela do wizard para escolha do tipo da aplicação cliente

Figura 9: Janela do wizard para escolha do tipo da aplicação cliente

Janela do wizard para configurações do cliente Java

Figura 10: Janela do wizard para configurações do cliente Java

Tendo criado o projeto, dá-se início ao desenvolvimento da classe que consumirá o serviço. A geração dos componentes do projeto cliente, gerados a partir do serviço, e a estrutura da classe consumidora podem ser vistos na Figura 11 e na Listagem 4.

Janela do wizard para geração dos componentes do projeto cliente

Figura 11: Janela do wizard para geração dos componentes do projeto cliente

A Listagem 4 demonstra um exemplo de implementação que faz uso da operação de Soma disponível no serviço criado.

Listagem 4: Implementação da classe Java consumidora do serviço


package Application;
import AppClient.ServicoOperacoes;
import AppClient.ServicoOperacoes_Service;
 
public class Cliente {
public static void main(String[] args){
    ServicoOperacoes_Service service = new ServicoOperacoes_Service();
    ServicoOperacoes port = servisse.getServicoOperacoesPort();
    System.out.println(“Soma: ”+port.soma(12,13));
}
}

A Figura 12 apresenta o resultado obtido após a execução da classe Java implementada, disponível na Listagem 4.

Resultado obtido através da execução da classe Java implementada

Figura 12: Resultado obtido através da execução da classe Java implementada

4.2 C#

Esta seção apresenta uma aplicação C# que fará o consumo do Web Service desenvolvido. Os passos para a criação deste aplicativo podem ser vistos nas Figuras 13, 14 e 15.

Janela do wizard para criação do Novo Projeto C#

Figura 13: Janela do wizard para criação do Novo Projeto C#

No passo apresentado na Figura 13, criou-se um novo projeto do tipo Console Application, que servirá para a criação da classe que fará o consumo do Web Service.

Após a criação do projeto, deve ser adicionada a ele uma referência para o Web Service, como pode ser observado nas Figuras 14 e 15.

Adição de referência para o Web Service no projeto consumidor do serviço

Figura 14: Adição de referência para o Web Service no projeto consumidor do serviço

Janela do wizard para adição de referência para o Web Service

Figura 15: Janela do wizard para adição de referência para o Web Service

Após concluir a criação do projeto e a adição da referência para o Web Service, se inicia a implementação da classe que utilizará o serviço. A programação desta classe pode ser vista na Listagem 5.

Listagem 5: Implementação da classe em C# que fará o consumo do serviço


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ClienteWebService{
     class Program
    {
        Static void Main(String[] args)
       {
           Servico.ServicoOperacoesClient service =  new                     Servico.ServicoOperacoesClient();
           Console.WriteLine(“Soma: ”+service.soma(14,15));
           Console.ReadKey();
        }
      }
}

5. Considerações Finais

Este artigo apresentou exemplos de implementação de Web Services utilizando a Plataforma JEE, bem como a aplicação prática da API SAX na interpretação de XML, neste caso, bastante adequada, pois os arquivos descritores de serviços geralmente possuem tamanhos consideráveis.

Além deste How-to (Como fazer), este estudo buscou fornecer uma “receita de bolo'' para a criação de aplicações consumidoras de serviços Web em diferentes linguagens, o que demonstra o poder da tecnologia estudada na interação de diferentes sistemas.

Referências