Departamento de Engenharia Informática Sistemas Distribuídos. Java Web Services Cookbook



Documentos relacionados
Livro de Receitas. Modelação Engenharia de Software Sistemas Distribuídos Versão 1.1. Framework de aplicações com Web Services

Web Services utilizando JAX-WS

Criar uma aplicação JPA2 com EclipseLink e H2

Criação de Servlets Name Directory Build WAR JSP/Servlet frameworks Launch URL Package Class name Generate header comments

UNIVERSIDADE. Sistemas Distribuídos

Sistemas Paralelos e Distribuídos /2004 Curso: Matemática /Informática Sistemas Distribuídos /2004 Curso: Ensino da Informática

Num sistema de objectos distribuídos, dois conceitos são fundamentais.

Como criar um EJB. Criando um projeto EJB com um cliente WEB no Eclipse

Guião de Introdução ao Eclipse IDE Índice

Prática da Disciplina de Sistemas Distribuídos Serviços Web IFMA DAI Professor Mauro Lopes C. Silva

Passo a Passo. WebSphere Message Broker. Fluxo como WebService

5 Everyware: Uma Arquitetura para Aplicações baseadas em serviços utilizando a Web Semântica

Grupo I [7v] 1. [1,0] Apresente o conteúdo do IDL relativo a este programa. Assuma PROGRAM=62015 e VERSION=1.

Introdução ao IDE Netbeans (Programação Java)

Aplicabilidade: visão geral

Grupo I [6v] Considere o seguinte extracto de um programa de definição de uma calculadora apenas com a função soma de dois valores reais

Chamadas Remotas de Procedimentos (RPC) O Conceito de Procedimentos. RPC: Programa Distribuído. RPC: Modelo de Execução

SOA na Prática Ricardo Limonta

Bases de Dados. Lab 1: Introdução ao ambiente

Professora Martha Spalenza Professora de Informática da Faetec

Programação para Internet Avançada. 4. Web Services. Nuno Miguel Gil Fonseca

Configuração de Cliente de Web Service HTTPS

Editor Eclipse para Programas F

Prática em Laboratório N.04 (Parte 01) Criando uma aplicação composta a partir de um serviço Web

Tutorial RMI (Remote Method Invocation) por Alabê Duarte

Tutorial Módulo 06 - Segurança

OWL-S Composer. MATE15 - Tópicos Especiais em Banco de Dados III. 17 de Julho de Marco Antonio Almeida 1 e Daniela Barreiro Claro 2

Conteúdo da Aula de Hoje. Web Services. Avaliação da Disciplina. O que é um web service? O que é um web service? Vantagens

Instalação do Plugin LeJOS

Engenharia de Software Sistemas Distribuídos

Manual de Instruções para a Criação de Ficheiros CSR. Microsoft IIS 5/6

Unidade 14: Web Services Prof. Daniel Caetano

Configurar o Furbot no Eclipse

Criação de um novo projeto no Eclipse utilizando Maven

Prática em Laboratório N.01 Criando um Serviço Web via Console

WSDL e UDDI. Pedro Miguel Martins Nunes WSDL. WSDL Exemplo prático Resumo UDDI. Serviço UDDI Estruturas de dados UDDI e WSDL API Resumo

O nome ANT é uma sigla para another neat tool (mais uma ferramenta organizada), segundo seu autor James Duncan Davidson.

Instalação e utilização do Eclipse / Fortran em Windows

Descompacte o arquivo site zip que foi baixado dentro da pasta do eclipse.

Exemplo de Aplicaça o Facebook

Invocação de Métodos Remotos

SISTEMAS DISTRIBUÍDOS

CURSO DE PROGRAMAÇÃO EM JAVA

Criação de um Web Services em.net

Web Services. Tópicos. Motivação. Tecnologias Web Service. Passo a passo Business Web Conclusão. Integração de aplicações SOAP, WSDL, UDDI, WSFL

WebWork 2. João Carlos Pinheiro.

Tencologia em Análise e Desenvolvimento de Sistemas Disciplina: WEB I Conteúdo: WEB Container Aula 04

Forms Authentication em ASP.NET

Computação Orientada a Serviços

Bases de Dados. O ficheiro create-bank.sql contém um conjunto de instruções SQL para criar a base de dados de exemplo ilustrada na figura 1.

Criação de um Web Services em.net

JPA: Persistência padronizada em Java

Java 2 Standard Edition. Fundamentos de. Objetos Remotos. Helder da Rocha

Nota de Aula: Utilização da IDE Code::Blocks

Arquitetura de Aplicações JSP/Web. Padrão Arquitetural MVC

Web Services e SOAP. Alexandre Zua CaldeiraTecnologias de Middleware 2006/ Faculdade de Ciências da Universidade de Lisboa

Capítulo 4. Packages e interfaces

Java Laboratório Aula 1. Divisões da Plataforma. Introdução a Plataforma Java. Visão geral da arquitetura da

Bases de Dados. Lab 1: Introdução ao ambiente. Figura 1. Base de dados de exemplo

Serviços Web: Arquitetura

Solutions for Information Technologies. BIS-Navegador. Manual de Instalação para Microsoft SQL Server

J550 Tag Libraries e JSTL

ESQUEMA AULA PRÁTICA 1 Familiarização com o Ambiente de Desenvolvimento Eclipse Introdução à Linguagem de Programação JAVA

Solutions for Information Technologies. BIS-Navegador. IBM DB2 UDB v8.x

Ficha prática nº 7. SGBD Microsoft Access e SQL Server

Hoje em dia é muito comum utilizar uma API de logging de mensagens como o Log4j para indicar os comportamentos de uma aplicação.

Connection String usada por uma Class Library

Desenvolvimento Web com Framework Demoiselle versão 1.0

Prática em Laboratório N.02 Criando um serviço Web via NetBeans

DSS 09/10. DSS 09/10 Que métodos é que fazem parte de cada camada? Aplicações Multi-camada JDBC. Aula 3 DSS 09/10

J820. Testes de interface Web com. HttpUnit. argonavis.com.br. Helder da Rocha

Impressão do Manual do Utilizador

Persistência de Classes em Tabelas de Banco de Dados

Para desenvolver a atividade a atividade desta aula utilizaremos o ambiente de desenvolvimento integrado NetBeans.

Documentação Symom. Agente de Monitoração na Plataforma Windows

VM Card. Referência das Definições Web das Funções Avançadas. Manuais do Utilizador

Engenharia de Software Sistemas Distribuídos

1 Criar uma entity a partir de uma web application que usa a Framework JavaServer Faces (JSF)

BlackBerry Messenger SDK

Web services. Um web service é qualquer software que está disponível através da Internet através de uma interface XML.

Integrando Flex + Java + BlazeDS

Guia rápido de uso da interface beta do NFS-e Easy para operação com Sistemas WebISS

Como o FIT funciona. FIT: Framework for Integrated Tests FIT. Dados de testes. Programa. Fixtures. classes. Resultados de testes

Redes de Computadores. Trabalho de Laboratório Nº8

Guia do Usuário Windows

Transcrição:

Departamento de Engenharia Informática Sistemas Distribuídos Java Web Services Cookbook 12 de Maio de 2009

Índice Nota prévia... 3 Criar um Web Service... 4 Estratégia... 4 Passos básicos... 4 Variantes... 8 Diagnóstico de erros... 8 Usar Eclipse... 8 Activar um JAX-WS Handler no servidor...10 Registar o Web Service no UDDI...10 Criar um servidor com dois endpoints...12 Criar um cliente de Web Service...15 Estratégia...15 Passos básicos...15 Variantes...17 Diagnóstico de erros...17 Usar Eclipse...17 Activar um JAX-WS Handler no cliente...18 Obter a localização do Web Service a partir do UDDI...19 Criar um cliente de dois Web Services...21 2

Nota prévia Este livro de "receitas" descreve procedimentos para o desenvolvimento de Web Services. Não explica nem pretende explicar todos os conceitos envolvidos, que deverão ser estudados e compreendidos em pormenor antes da utilização deste guia. A infra-estrutura de software que se assume é: Java 5, JWSDP 2.0+, Ant 1.7.0+ e ImportAnt 5.5.1+. São também apresentadas variantes que usam o Eclipse Java Enterprise Europa+. A estrutura base de directorias dos projectos (ImportAnt) é a seguinte: project build.xml Project Ant build file: - import modules - define properties - define classpaths - define build targets build.properties Property overrides config configuration files lib library (jar) files src source code java Java classes web Web resources (JSP, HTML,...) xml WSDL, XSD and other XML sources etc additional files build temporary build directory dist temporary application or library distribution directory 3

Criar um Web Service Estratégia Um Web Service é uma aplicação servidora que responde a pedidos de clientes formatados em XML e transportados em mensagens SOAP. O procedimento consiste em criar uma estrutura de directórios e ficheiros para o projecto, definir o Web Service através de WSDL e XSD, gerar código Java para tratamento da comunicação e da conversão de dados e, finalmente, escrever o restante código. Aqui o Web Service é genericamente designado como MyWS. Este e outros nomes relacionados deverão ser ajustados caso a caso, de acordo com o pretendido. Passos básicos 1. Criar projecto Ant a. Criar estrutura de directorias e ficheiros para o projecto. import-ant my-ws config resources jax-ws-server web.xml sun-jaxws.xml server-custom-binding.xml src java xml web.xml <?xml version="1.0" encoding="utf-8"?> <!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/j2ee/dtds/web-app_2_3.dtd"> <web-app> <display-name>jax-ws @ant.project.name@</display-name> <description>jax-ws application: @ant.project.name@</description> <listener> <listenerclass>com.sun.xml.ws.transport.http.servlet.wsservletcontextlistener</listenerclass> </listener> <servlet> <servlet-name>jax-ws-servlet</servlet-name> <display-name>jax-ws servlet</display-name> <description>jax-ws endpoint</description> <servletclass>com.sun.xml.ws.transport.http.servlet.wsservlet</servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>jax-ws-servlet</servlet-name> <url-pattern>/endpoint</url-pattern> </servlet-mapping> <session-config> <session-timeout>60</session-timeout> 4

</session-config> </web-app> sun-jaxws.xml <?xml version="1.0" encoding="utf-8"?> <endpoints xmlns="http://java.sun.com/xml/ns/jax-ws/ri/runtime" version="2.0"> <endpoint name="endpoint" interface="@jax-ws-server.ties.interface.name@" implementation="@jax-ws-server.impl.class.name@" wsdl="web-inf/wsdl/@jax-ws-server.wsdl.file-name@" service="{@jax-ws-server.wsdl.namespace@@jax-wsserver.wsdl.service-name@" port="{@jax-ws-server.wsdl.namespace@@jax-wsserver.wsdl.port-name@" url-pattern="/endpoint" /> </endpoints> server-custom-binding.xml <?xml version="1.0" encoding="utf-8" standalone="yes"?> <bindings xmlns:xsd="http://www.w3.org/2001/xmlschema" xmlns:jaxb="http://java.sun.com/xml/ns/jaxb" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" wsdllocation="@jax-ws-server.wsdl.file-name@" xmlns="http://java.sun.com/xml/ns/jaxws"> <bindings node="wsdl:definitions"> @jax-ws-server.handler-chains@ </bindings> </bindings> Todos estes ficheiros contêm itens de substituição (@...@) que serão substituídos pelo ImportAnt durante o processo de construção. Deste modo, estes ficheiros permanecem sempre iguais e o que muda é o build.xml. b. Criar ficheiro de construção build.xml: <project name="myws" default="build" basedir="."> <property name="import-ant" value="../import-ant" /> <!-- IMPORTS --> <import file="${import-ant/core.xml" /> <import file="${import-ant/tomcat.xml" /> <import file="${import-ant/jwsdp.xml" /> <import file="${import-ant/jax-ws-server.xml" /> <!-- Web Service definitions --> <property name="jax-ws-server.wsdl.file-name" value="" /> <property name="jax-ws-server.wsdl.namespace" value="" /> <property name="jax-ws-server.wsdl.service-name" value="" /> <property name="jax-ws-server.wsdl.port-name" value="" /> <property name="jax-ws-server.ties.package" value="" /> <property name="jax-ws-server.ties.interface.simple-name" value="" /> <property name="jax-ws-server.impl.package" value="" /> <property name="jax-ws-server.impl.class.simple-name" value="" /> <!-- CLASSPATHS --> <path id="compile.classpath"> <pathelement location="${build.classes.rel-dir" /> <path refid="project.lib.path" /> <path refid="jwsdp.jars.path" /> </path> 5

<!-- TARGETS --> <target name="build" depends="config,build-jax-ws-server" description="builds the project"> </project> c. Criar directorias temporárias build e dist e confirmar que sintaxe do build.xml está correcta: $ ant init 2. Definir contrato do serviço a. Criar ficheiro MyWS.wsdl em src/xml que especifica as operações do Web Service com o vocabulário WSDL. Os tipos de dados são definidos com o vocabulário XSD. <?xml version="1.0" encoding="utf-8"?> <definitions name="myws" targetnamespace="http://myws" xmlns:tns="http://my-ws" xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:xsd="http://www.w3.org/2001/xmlschema" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"> <types> <xsd:schema elementformdefault="qualified" targetnamespace="http://my-ws"> <xsd:complextype name="myoperationtype"> <xsd:sequence> <xsd:element name="i" type="xsd:int" /> <xsd:element name="z" type="xsd:string" /> </xsd:sequence> </xsd:complextype> <xsd:element name="myoperation" type="tns:myoperationtype" /> /> <xsd:complextype name="myoperationresponsetype"> <xsd:sequence> </xsd:sequence> </xsd:complextype> <xsd:element name="myoperationresponse" type="tns:myoperationresponsetype" <message name="myoperation"> <part name="parameters" element="tns:myoperation" /> </message> <message name="myoperationresponse"> <part name="result" element="tns:myoperationresponse" /> </message> <porttype name="myporttype"> <operation name="myoperation"> <input message="tns:myoperation" name="myoperation"/> <output message="tns:myoperationresponse" name="myoperationresponse"/> </operation> </porttype> <binding name="mybinding" type="tns:myporttype"> <soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="document" /> <operation name="myoperation"> <soap:operation soapaction="" /> <input> 6

</definitions> <soap:body use="literal" /> </input> <output> <soap:body use="literal" /> </output> </operation> </operation> </binding> <service name="myservice"> <port name="myport" binding="tns:mybinding"> <soap:address location="replace_with_actual_url" /> </port> </service> b. Definir nomes seguindo a convenção dos sufixos:...service,...port,...porttype,...binding,... 3. Criar serviço a. Gerar ties i. Definir valores de propriedades de Web Service no build.xml de acordo com os valores definidos no WSDL <!-- Web Service definitions --> <property name="jax-ws-server.wsdl.file-name" value="myws.wsdl" /> <property name="jax-ws-server.wsdl.namespace" value="http://my-ws" /> <property name="jax-ws-server.wsdl.service-name" value="myservice" /> <property name="jax-ws-server.wsdl.port-name" value="myport" /> <property name="jax-ws-server.ties.package" value="my.ws.ties" /> <property name="jax-ws-server.ties.interface.simple-name" value="myporttype" /> <property name="jax-ws-server.impl.package" value="my.ws" /> <property name="jax-ws-server.impl.class.simple-name" value="myserviceimpl" /> ii. Executar wsimport $ ant build-jax-ws-server iii. Consultar ties gerados pelo wsimport em build/jax-wsserver/wsimport, em particular MyService.java e MyPortType.java 7

b. Criar implementação do serviço i. Criar classe em src/java/my/ws, implementando todos os métodos definidos em MyPortType package my.ws; import my.ws.ties.*; @javax.jws.webservice (endpointinterface="my.ws.ties.myporttype") public class MyServiceImpl implements MyPortType { public void myoperation(int i, String s) { return; c. Construir Web Service e instalar $ catalina start $ ant deploy d. Confirmar instalação correcta http://localhost:8080/myws/endpoint http://localhost:8080/myws/endpoint?wsdl Variantes Diagnóstico de erros Consultar ficheiro de log: %CATALINA_HOME%\logs\launcher.server.log $ ant rebuild $ ant quick-redeploy O ficheiro de log pode ser consultado continuamente com o comando tail: $ tail -f %CATALINA_HOME%\logs\launcher.server.log Usar Eclipse (Antes do passo 2) Iniciar o Eclipse e criar novo projecto File, New, Project, Java Project, Project name: MyWS Create project from existing source, Next Source, Source folder, src/java, Default output folder: build/eclipse Libraries, Add library, User library: jwsdp-essd-2008, Finish Add class folder: build/classes, Finish O conjunto de bibliotecas (user library) jwsdp-essd-2008 pode ser importado a partir do ficheiro contido na directoria %JWSDP_HOME%\eclipse. 8

Configurar Ant Windows, Show View, Ant View build.xml ~drag-and-drop~> Ant View Hide internal targets (Apoio ao passo 2, a) Criar WSDL New, Other..., XML, WSDL Next Parent folder: src/xml File name: MyWS.wsdl, Next Target namespace: http://my-ws Namespace prefix: tns Create WSDL Skeleton Protocol: SOAP SOAP Binding options: document literal Finish Indentar XML WSDL, View Source Select All Text Source, Format, Document (Depois do passo 3, a, ii) Refrescar Eclipse Project, Refresh (Apoio ao passo 3, b, i) Criar classe File, New, Class package: my.ws name: MyServiceImpl superclass: java.lang.object interfaces: my.ws.ties.myporttype inherit abstract methods generate comments Anotar classe @javax.jws.webservice (endpointinterface="my.ws.ties.myporttype") Escrever código Java dos métodos. 9

Activar um JAX-WS Handler no servidor Acrescentar o seguinte target ao build.xml. <target name="-replace-jax-ws-server-custom-tokens(dir)"> <replace dir="${dir" token="@jax-ws-server.handler-chains@"> <replacevalue><![cdata[ <jws:handler-chains xmlns:jws="http://java.sun.com/xml/ns/javaee"> <jws:handler-chain> <jws:handler> <jws:handlerclass>my.ws.handler.myhandler</jws:handler-class> </jws:handler> </jws:handler-chain> </jws:handler-chains> ]]></replacevalue> </replace> A classe my.ws.handler.myhandler deverá existir e ser um JAX-WS Handler. Registar o Web Service no UDDI Obter uma biblioteca com as classes step.framework.ws.registry.* e colocar numa das directorias lib do projecto: lib my-ws lib Criar e preencher ficheiros de configuração de registo Registry.properties (dados do servidor UDDI) e Registration.properties (dados de registo). my-ws config ws-registry Registry.properties Registration.properties Registry.properties # # Registry # url=@ws-registry.url@ username=@ws-registry.username@ password=@ws-registry.password@ #locale= optionoutputmessages=true #optionvalidateuri=false #optionwarnaboutlocale=true Registration.properties # # Registration # organizationname=my Organization servicename=my Service servicebindingaccessuri=http://myserver:8080/myws/endpoint classificationscheme=unspsc-org:unspsc:3-1 10

classificationname=research and Science Based Services classificationvalue=81000000 Criar ou editar ficheiro build.properties para acrescentar: ws-registry.username=testuser ws-registry.password=testuser Modificar build.xml, acrescentando a importação de um novo módulo: <import file="${import-ant/ws-registry.xml" /> As propriedades relacionadas com o registo UDDI: <property name="ws-registry.url" value="http://localhost:8080/registryserver/" /> <property name="ws-registry.main-class" value="step.framework.ws.registry.main" /> <property name="dir" value="${build.config.ws-registry.rel-dir" /> <property name="ws-registry.publish.args" value="${dir/registry.properties publish ${dir/registration.properties ${dir/registrationkey.properties" /> <property name="ws-registry.delete.args" value="${dir/registry.properties delete key ${dir/registrationkey.properties" /> <property name="ws-registry.query.args" value="${dir/registry.properties query classification ${dir/registration.properties" /> Uma nova dependência no build.xml: <target name="build" depends="config,build-ws-registry,build-jax-ws-server" description="builds the project"> Efectuar o registo: $ ant build-ws-registry ws-publish Consultar o registo: $ ant build-ws-registry ws-query Apagar o registo: $ ant build-ws-registry ws-delete 11

Criar um servidor com dois endpoints É possível que o mesmo servidor disponibilize dois endpoints, neste caso, Hello e Calc. No entanto, os itens de substituição (@...@) do ImportAnt já não funcionam correctamente e é necessário efectuar a configuração directamente nos ficheiros. Criar dois ficheiros de custom bindings: my-ws config resources jax-ws-server web.xml sun-jaxws.xml server-custom-binding_hello.xml server-custom-binding_calc.xml web.xml <?xml version="1.0" encoding="utf-8"?> <!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/j2ee/dtds/web-app_2_3.dtd"> <web-app> <display-name>jax-ws Application</display-name> <description>jax-ws Application</description> <listener> <listenerclass>com.sun.xml.ws.transport.http.servlet.wsservletcontextlistener</listenerclass> </listener> <servlet> <servlet-name>jax-ws Servlet</servlet-name> <display-name>jax-ws Servlet</display-name> <description>jax-ws endpoint</description> <servletclass>com.sun.xml.ws.transport.http.servlet.wsservlet</servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>jax-ws Servlet</servlet-name> <url-pattern>/endpoint_hello</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>jax-ws Servlet</servlet-name> <url-pattern>/endpoint_calc</url-pattern> </servlet-mapping> <session-config> <session-timeout>60</session-timeout> </session-config> </web-app> sun-jaxws.xml <?xml version="1.0" encoding="utf-8"?> <endpoints xmlns="http://java.sun.com/xml/ns/jax-ws/ri/runtime" version="2.0"> <endpoint name="endpoint_hello" interface="hello.ties.helloporttype" implementation="hello.helloserviceimpl" wsdl="web-inf/wsdl/hello.wsdl" service="{http://hellohelloservice" port="{http://hellohelloport" url-pattern="/endpoint_hello" /> <endpoint name="endpoint_calc" interface="calc.ties.calcporttype" implementation="calc.calcserviceimpl" 12

wsdl="web-inf/wsdl/calc.wsdl" service="{http://calccalcservice" port="{http://calccalcport" url-pattern="/endpoint_calc" /> </endpoints> server-custom-binding_hello.xml <?xml version="1.0" encoding="utf-8" standalone="yes"?> <bindings xmlns:xsd="http://www.w3.org/2001/xmlschema" xmlns:jaxb="http://java.sun.com/xml/ns/jaxb" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" wsdllocation="hello.wsdl" xmlns="http://java.sun.com/xml/ns/jaxws"> <bindings node="wsdl:definitions"> <jws:handler-chains xmlns:jws="http://java.sun.com/xml/ns/javaee"> <jws:handler-chain> <jws:handler> <jws:handler-class>util.hellologginghandler</jws:handlerclass> </jws:handler> </jws:handler-chain> </jws:handler-chains> </bindings> </bindings> server-custom-binding_calc.xml <?xml version="1.0" encoding="utf-8" standalone="yes"?> <bindings xmlns:xsd="http://www.w3.org/2001/xmlschema" xmlns:jaxb="http://java.sun.com/xml/ns/jaxb" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" wsdllocation="calc.wsdl" xmlns="http://java.sun.com/xml/ns/jaxws"> <bindings node="wsdl:definitions"> <jws:handler-chains xmlns:jws="http://java.sun.com/xml/ns/javaee"> <jws:handler-chain> <jws:handler> <jws:handler-class>util.calclogginghandler</jws:handlerclass> </jws:handler> </jws:handler-chain> </jws:handler-chains> </bindings> </bindings> 13

O build.xml deverá ter agora os seguintes targets: <target name="build" depends="config,build-jax-ws-server-ties_hello,build-jax-wsserver-ties_calc,compile,create-jax-ws-server-war" description="builds the project"> <target name="build-jax-ws-server-ties_hello"> <echo level="info" message="creating Hello ties..." /> <antcall target="build-jax-ws-server-ties" inheritall="false"> <param name="jax-ws-server.wsdl.file-name" value="hello.wsdl" /> <param name="jax-ws-server.wsimport.bindings.file-pattern" value="*binding*hello.xml" /> <param name="jax-ws-server.ties.package" value="hello.ties" /> </antcall> <target name="build-jax-ws-server-ties_calc"> <echo level="info" message="creating Calc ties..." /> <antcall target="build-jax-ws-server-ties" inheritall="false"> <param name="jax-ws-server.wsdl.file-name" value="calc.wsdl" /> <param name="jax-ws-server.wsimport.bindings.file-pattern" value="*binding*calc.xml" /> <param name="jax-ws-server.ties.package" value="calc.ties" /> </antcall> As propriedades relativas a Web Services (jax-ws-server.wsdl.file-name, jaxws-server.wsdl.namespace, etc.) devem desaparecer, porque as definições são agora feitas directamente nos ficheiros de configuração e não através do mecanismo de substituição (@...@). 14

Criar um cliente de Web Service Estratégia Um cliente de Web Service é uma aplicação que invoca um Web Service. Nesta receita cria-se um cliente que se executa a partir da linha de comando, no entanto, o procedimento é idêntico para aplicações Web ou de outro tipo. O procedimento consiste em criar uma estrutura de directórios e ficheiros para o projecto, gerar código Java de invocação e de conversão de dados e, finalmente, escrever o restante código. Aqui o cliente de Web Service é genericamente designado como MyWSCli. Este e outros nomes relacionados deverão ser ajustados caso a caso, de acordo com o pretendido. Passos básicos 1. Criar projecto Ant a. Criar estrutura de directorias e ficheiros para o projecto. import-ant my-ws config resources jax-ws-client client-custom-binding.xml src java client-custom-binding.xml <?xml version="1.0" encoding="utf-8" standalone="yes"?> <bindings xmlns:xsd="http://www.w3.org/2001/xmlschema" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" wsdllocation="@jax-ws-client.wsdl.url@" xmlns="http://java.sun.com/xml/ns/jaxws"> <bindings node="wsdl:definitions"> @jax-ws-client.handler-chains@ </bindings> </bindings> Este ficheiro contêm itens de substituição (@...@) que serão substituídos pelo ImportAnt durante o processo de construção. Deste modo, o ficheiro permanece sempre igual e o que muda é o build.xml. b. Criar ficheiro de construção build.xml: <project name="mywscli" default="build" basedir="."> <property name="import-ant" value="../import-ant" /> <!-- IMPORTS --> 15

<import file="${import-ant/core.xml" /> <import file="${import-ant/console-app.xml" /> <import file="${import-ant/jwsdp.xml" /> <import file="${import-ant/jax-ws-client.xml" /> /> <!-- Console application --> <property name="run.main-class" value="my.myclient" /> <property name="run.args" value="http://localhost:8080/myws/endpoint" <!-- Web Service client --> <property name="jax-ws-client.wsdl.url" value="http://localhost:8080/myws/endpoint?wsdl" /> <property name="jax-ws-client.stubs.package" value="my.ws.stubs" /> <!-- CLASSPATHS --> <path id="compile.classpath"> <pathelement location="${build.classes.rel-dir" /> <path refid="project.lib.path" /> <path refid="jwsdp.jars.path" /> </path> <path id="run.classpath"> <path refid="compile.classpath" /> </path> <target name="build" depends="config,build-jax-ws-client,compile" description="build the project"> </project> c. Criar directorias temporárias build e dist e confirmar que sintaxe do build.xml está correcta: $ ant init 2. Criar cliente a. Gerar stubs i. Executar wsimport $ ant build-jax-ws-client ii. Consultar stubs gerados pelo wsimport em build/jax-wsclient/wsimport, em particular MyService.java e MyPortType.java b. Criar classe do cliente em src/java/my package my; import javax.xml.ws.bindingprovider; import javax.xml.ws.webserviceexception; import my.ws.stubs.*; public class MyServiceClient { public static void main(string[] args) { try { System.out.println("begin"); 16

// web service endpoint address String endpointurl = args[0]; System.out.println("Web Service endpoint URL: " + endpointurl); port; // // create Web Service stub // MyService service = new MyService(); MyPortType port = service.getmyport(); BindingProvider bindingprovider = (BindingProvider) // set endpoint address bindingprovider.getrequestcontext().put(bindingprovider.endpoint_ad DRESS_PROPERTY, endpointurl); // // invoke Web Service operation // port.myoperation(123, "abc"); catch(webserviceexception e) { // handle Web Service exception System.out.println("Caught web service exception: "); System.out.println(e.getClass().toString()); System.out.println(e.getMessage()); catch(exception e) { // handle general exception System.out.println("Caught exception: "); System.out.println(e.getClass().toString()); System.out.println(e.getMessage()); finally { System.out.println("end"); c. Construir cliente e executar $ ant run Variantes Diagnóstico de erros Consultar tipo e mensagem da excepção produzida. Usar Eclipse (Antes do passo 2) Iniciar o Eclipse e criar novo projecto File, New, Project, Java Project, Project name: MyWSCli Create project from existing source, Next Source, Source folder, src/java, Default output folder: build/eclipse Libraries, Add library, User library: jwsdp-essd-2008, Finish Add class folder: build/classes, Finish 17

O conjunto de bibliotecas (user library) jwsdp-essd-2008 pode ser importado a partir do ficheiro contido na directoria %JWSDP_HOME%\eclipse. Configurar Ant Windows, Show View, Ant View build.xml ~drag-and-drop~> Ant View Hide internal targets (Depois do passo 2, a, i) Refrescar Eclipse Project, Refresh (Apoio ao passo 2, b) Criar classe File, New, Class package: my name: MyServiceClient superclass: java.lang.object inherit abstract methods public static void main(string[] args) generate comments Activar um JAX-WS Handler no cliente Acrescentar o seguinte target ao build.xml. <target name="-replace-jax-ws-client-custom-tokens(dir)"> <replace dir="${dir" token="@jax-ws-client.handler-chains@"> <replacevalue><![cdata[ <jws:handler-chains xmlns:jws="http://java.sun.com/xml/ns/javaee"> <jws:handler-chain> <jws:handler> <jws:handlerclass>my.handler.myclienthandler</jws:handler-class> </jws:handler> </jws:handler-chain> </jws:handler-chains> ]]></replacevalue> </replace> A classe my.handler.myclienthandler deverá existir e ser um JAX-WS Handler. 18

Obter a localização do Web Service a partir do UDDI Obter uma biblioteca com as classes step.framework.ws.registry.* e colocar numa das directorias lib do projecto: lib my-ws lib Criar e preencher ficheiros de configuração de registo Registry.properties (dados do servidor UDDI), ClassificationQuery.properties (dados de pesquisa por classificação) ou NamePatternQuery.properties (dados de pesquisa por nome). my-ws config ws-registry Registry.properties ClassificationQuery.properties NamePatternQuery.properties Registry.properties # # Registry # url=@ws-registry.url@ username=@ws-registry.username@ password=@ws-registry.password@ #locale= optionoutputmessages=true #optionvalidateuri=false #optionwarnaboutlocale=true ClassificationQuery.properties # # Classification Query # queryclassificationscheme=unspsc-org:unspsc:3-1 queryclassificationname=research and Science Based Services queryclassificationvalue=81000000 NamePatternQuery.properties # # Name Pattern Query # querynamepattern=%organization% Criar ou editar ficheiro build.properties para acrescentar: ws-registry.username=testuser ws-registry.password=testuser Modificar build.xml, acrescentando a importação de um novo módulo: <import file="${import-ant/ws-registry.xml" /> As propriedades relacionadas com a pesquisa UDDI: <property name="ws-registry.url" value="http://localhost:8080/registryserver/" /> <property name="ws-registry.main-class" value="step.framework.ws.registry.main" /> 19

<property name="dir" value="${build.config.ws-registry.rel-dir" /> <property name="ws-registry.query.args" value="${dir/registry.properties query classification ${dir/classificationquery.properties" /> Uma nova dependência no build.xml: <target name="build" depends="config,build-ws-registry,build-jax-ws-client" description="builds the project"> Testar a pesquisa em tempo de compilação: $ ant build-ws-registry ws-query Efectuar a pesquisa no código do cliente: package my; import javax.xml.ws.bindingprovider; import javax.xml.ws.webserviceexception; import step.framework.ws.registry.*; import my.ws.stubs.*; public class MyServiceClient { public static void main(string[] args) { try { System.out.println("begin"); // // query web services registry // Registry registry = null; ClassificationQuery query = null; Registration[] registrationarray = null; try { registry = new Registry("/Registry.properties"); query = new ClassificationQuery("/ClassificationQuery.properties"); querying registry.setoptionoutputmessages(false); // no output registry.connect(false); // no authentication is required for registrationarray = registry.query(query); if(registrationarray == null) { System.out.println("No web service registrations found in registry server " + registry.geturl()); return; else { System.out.println("Found " + registrationarray.length + " web service registrations in registry server " + registry.geturl()); finally { if(registry!= null) registry.disconnect(); // // create Web Service stub // MyService service = new MyService(); MyPortType port = service.getmyport(); BindingProvider bindingprovider = (BindingProvider) port; // // for each web service, invoke Web Service operation // System.out.println("Invoking operation on all found web service 20

registrations"); for(int i=0; i < registrationarray.length; i++) { try { String endpointurl = registrationarray[i].getservicebindingaccessuri(); // set endpoint address System.out.println("Web Service endpoint URL: " + endpointurl); bindingprovider.getrequestcontext().put(bindingprovider.endpoint_address_property, endpointurl); port.myoperation(123, "abc"); catch(webserviceexception e) { // handle Web Service exception System.out.println("Caught web service exception: "); System.out.println(e.getClass().toString()); System.out.println(e.getMessage()); System.out.println("Proceed to next endpoint"); catch(exception e) { // handle general exception System.out.println("Caught exception: "); System.out.println(e.getClass().toString()); System.out.println(e.getMessage()); finally { System.out.println("end"); Criar um cliente de dois Web Services Para invocar dois Web Services a partir do mesmo cliente, suponhamos Hello e Calc, é necessário criar duas directorias de configuração: my-ws-cli config jax-ws-client_hello client-custom-binding.xml jax-ws-client_hello client-custom-binding.xml E modificar o build.xml: <target name="build" depends="config,build-jax-ws-client-stubs_hello,build-jax-ws-clientstubs_calc,compile" description="build the project"> <target name="build-jax-ws-client-stubs_hello"> <echo level="info" message="creating Hello stubs..." /> <antcall target="build-jax-ws-client-stubs" inheritall="false"> <param name="jax-ws-client.dir-name" value="jax-ws-client_hello" /> <param name="jax-ws-client.wsdl.url" value="http://localhost:8080/exemplohellows/endpoint?wsdl" /> <param name="jax-ws-client.stubs.package" value="hello.ws.stubs" /> <param name="jax-ws-client.custom-tokens.target-name" value="- replace-jax-ws-client-custom-tokens(dir)_hello" /> </antcall> <target name="-replace-jax-ws-client-custom-tokens(dir)_hello"> <replace dir="${dir" token="@jax-ws-client.handler-chains@"> 21

<replacevalue><![cdata[ <jws:handler-chains xmlns:jws="http://java.sun.com/xml/ns/javaee"> <jws:handler-chain> <jws:handler> <jws:handlerclass>step.framework.ws.handler.logginghandler</jws:handler-class> </jws:handler> </jws:handler-chain> </jws:handler-chains> ]]></replacevalue> </replace> <target name="build-jax-ws-client-stubs_calc"> <echo level="info" message="creating Calc stubs..." /> <antcall target="build-jax-ws-client-stubs" inheritall="false"> <param name="jax-ws-client.dir-name" value="jax-ws-client_calc" /> <param name="jax-ws-client.wsdl.url" value="http://localhost:8080/exemplocalcws/endpoint?wsdl" /> <param name="jax-ws-client.stubs.package" value="calc.ws.stubs" /> <param name="jax-ws-client.custom-tokens.target-name" value="- replace-jax-ws-client-custom-tokens(dir)_calc" /> </antcall> <target name="-replace-jax-ws-client-custom-tokens(dir)_calc"> <replace dir="${dir" token="@jax-ws-client.handler-chains@"> <replacevalue><![cdata[ <jws:handler-chains xmlns:jws="http://java.sun.com/xml/ns/javaee"> <jws:handler-chain> <jws:handler> <jws:handlerclass>step.framework.ws.handler.logginghandler</jws:handler-class> </jws:handler> </jws:handler-chain> </jws:handler-chains> ]]></replacevalue> </replace> Os targets -replace-jax-ws-client-custom-tokens(dir)_hello e -replace-jax-wsclient-custom-tokens(dir)_calc são definidos para permitir uma configuração individual de JAX-WS Handlers. O código do cliente deve importar e usar os stubs dos dois Web Services: import hello.ws.stubs.*; import calc.ws.stubs.*;... 22