Introducão
de
web services
Além de propaganda
Por Robert Lazarski
Agenda
O que é web services?
No fundo, Web Services simplesmente é um jeito de chamar methods na outra máquina / empresa remotamente pelo protocolos HTTP ou SMTP sem um Web Browser, ou seja, com programação automática. Esse conceito de programação - uma maquina chamando uma outra remotamente, é chamada 'distributed programming' .
Golden Hammer
Martelo Dourado (Golden Hammer) é quando a única ferramenta disponível é um martelo, todo o resto vira prego.
Web Services não é um Martelo Dourado. Solução: Suportar filosofia de buscar novas tecnologias.
Breve história de distributed programming
RPC 1985 - o primeiro a ficar popular(Exemplos: nfs, portmapper)
Prós - Bem definido, leve, praticamente todo sistema/vendor tem apoio
Contras - não é object oriented, percepcão de tecnologia antiga, problemas com data encoding(binary, objetos, etc)
Corba 1991 - a reposta para o revolução de Orientação a Objetos (Exemplos: Gnome desktop para Linux, bancos de dados)
Prós - Bem definido, praticamente toda linguagem e sistema tem apoio(c++, Java, cobol, perl e vinte otros)
Contras - Microsoft não gosta (com+, dcom), IDL (mapping linguagem) difícil aprender, pesado, melhor opções existem cada dia mais (web services, ejb).
RMI 1997 - Distributed programming para Java(Exemplos: EJB, file servers)
Prós - todas as vantagems de Java, tem mapping por Corba(IIOP), bem mais facil do que Corba, tem bom futuro. A performance do RMI é bem melhor do que do Web Services
Contras - Não funciona bem com firewalls. Client e server precisam ser Java
JMS 1999 - Messaging por Java (Mesmo conceito do MQSeries)
Prós - Asynchronous communications que nem precisa esperar por um retorno, tem apoio a muito-a-muito (many to many) relacionamento, escalável e confiável, mais apoio no mercado do MQSeries. A mais importante parte de EJB 2.0 com Message Driven Beans
Contras - persistencia (criar queue de novo com um crash) precisa ter banco se tiver escalabilidade, um pouco complexo, algumas fucionalidades de JMS depende das implementações do vendedor (Websphere, JBOSS, OpenJMS etc). JMS é particular de Java
SOAP/Web Services - open standards, method calls pela internet
Prós - Baseado em XML e open protocols (opcões para SMTP ou HTTP), dynamic lookup dos clientes, primero vez que Sun, IBM, microsoft e communidade open source concordoram sobre qualquer coisa. Muitas linguagens de programação têm apoio. Especificação de EJB (2.1) está integrando EJB e web services. O melhor futuro de qualquer tipo de distributed programming nesse momento
Contras - Segurança é imatura, bem pesado, múltiplos 'padrões' estão em competitição e não funcionam juntos, ainda falta a infrastrutura facilitar a integração de web services complexos. No fundo, Web Services está no período de fluxo ainda
Qual é o motivo de usar Web Services?
OS Motivos de usar Web Services são padrões e apoio no mercado, fácil de escrever, tem muito pre-built types prontos (String, int, long, Array etc) que funcionam com Java, .net, c/c++ etc. Web Services são independentes da linguagem e sistema operacional. Web Services funciona com HTTP ou SMTP, e então, geralmente não tem problemas com firewalls.
Quando não usar Web Services para chamdas remotas?
Se tiver uma aplicação na rede interna sem firewalls, e só Java, RMI vai dar bem melhor performance. Um gráfico abaixo de IBM mostra a diferença de performance entre RMI e SOAP
![]() |
-----------------------------------------------------------
Java Web Services: Apache Axis ou JWSDP do Sun Microsytems ?
Apache SOAP (2000), Apache Axis 1 (2003), Apache Axis 2 (2006)
Prós - O mais popular de todos, software livre, na minha opinião uma arquitetura e API superior, IBM está apoiando Apache Axis com código e recursos. Geralmente, as novidades de Web Services padrões chegam no Axis primeiro.
Contras - Axis2 é novo ainda (versão .94 é a mais atual), não há boa vontade em ajudar quem usa Axis 1. O API do Axis2 está mudando rápido.
Java Web Services Developer Pack (JWSDP) da Sun Microsystems
Prós - Marketing do JWSDP é superior, funciona bem com JBoss e EJB, vem diretamente da Sun
Contras - bem menos usuários do que Axis, segurança imatura, complexo, difícil achar ajuda para problemas. Reputação de Sun é eles praticamente ignorarem bugs e desejos dos usúarios no site 'Bug Parade'. JWSDP não é software livre.
-----------------------------------------------------------
Arquitetura de web services: WSDL, XML, RPC
XML: RPC de novo
RPC é popular em protocolos no Unix/Linux e microsoft que já existem. Mas tradicionalmente, RPC tinha problemas ao transferir arquivos binary ou objetos - RPC é um protocolo de texto. Desde que XML é text também, bem defindo, extensível e um padrão, é bom definir como interpretar formatos de binary e objetos
RPC é leve, consome pouca memória, e tem apoio bom de Unix/Linux e Microsoft. É mais simples do que RMI e mais leve do que Corba - é independente da linguagem de programação. Por esses motivos, RPC é parte fundamental de SOAP
WSDL: Descrição interna do web service
O função do WSDL (Web Services definition language) é mapear as assinaturas dos métodos e tipos de variáveis com XML, para ser independente da linguagem de programação. Depois da definição de WSDL, pode converter, ou seja, transformar, O WSDL para fontes Java automaticamente por uma ferramenta tal como WSDL2Java do Axis2.
WSDL não é obrigatório, e para Web Services simples, não precisa. Porém, se tiver Web Services entre empresas ou projetos diferentes, WSDL pode agir como um contrato e definição dos Web Services. Para Web Services complexo, o custo / beneficio é bom para WSDL.
XML-to-Java Mapping for Built-In Data Types
Os três estilos do WSDL são: RPC Encoded (não funciona com .Net, mas é popular. Cada dia mais RPC Encoded é legado), RPC Literal, e Wrapped Document Literal.
Wrapped Document Literal é superior e tem bom apoio do Axis2 e .Net . SWA está usando Wrapped Document Literal.
WSDL em quatro partes: Parte 1, XML Schema
'Tudo deve ser feito o mais simples possível, mas não de forma simplista.' Albert Einstein
Como tratar exceções e estado de sessão (session state) ?
<?xml version="1.0" encoding="UTF-8"?>
<definitions name="SWAWiseService" targetNamespace="http://swaWiseNS" xmlns:tns="http://swaWiseNS" xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:ns2="http://swaWiseNS/types">
<types>
<schema targetNamespace="http://swaWiseNS/types" xmlns:tns="http://swaWiseNS/types" xmlns:soap11-enc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns="http://www.w3.org/2001/XMLSchema">
<import namespace="http://schemas.xmlsoap.org/soap/encoding/"/>
<complexType name="ReturnWebBase">
<sequence>
<element name="errorMessage" type="xsd:string"/>
<element name="successErrorCode" type="xsd:int"/>
</sequence>
</complexType>
<element name="wiseLogin">
<complexType>
<sequence>
<element name="user_name" type="xsd:string"/>
<element name="user_password" type="xsd:string"/>
</sequence>
</complexType>
</element>
<element name="wiseLoginResponse">
<complexType>
<complexContent>
<extension base="tns:ReturnWebBase">
<sequence>
<element name="soap_session_id" type="xsd:string"/>
<element name="web_user_name" type="xsd:string"/>
</sequence>
</extension>
</complexContent>
</complexType>
</element>
<element name="testService">
<complexType>
<sequence>
<element name="soap_session_id" type="xsd:string"/>
<element name="web_user_name" type="xsd:string"/>
</sequence>
</complexType>
</element>
<element name="testServiceResponse">
<complexType>
<complexContent>
<extension base="tns:ReturnWebBase">
<sequence>
<element name="testId" type="xsd:long"/>
</sequence>
</extension>
</complexContent>
</complexType>
</element>
<!-- 13a -->
<element name="acionarAutomatico">
<complexType>
<sequence>
<element name="soap_session_id" type="xsd:string"/>
<element name="web_user_name" type="xsd:string"/>
<element name="NumeroOS" type="xsd:string"/>
<element name="DataHoraDoAcionamento" type="xsd:dateTime"/>
</sequence>
</complexType>
</element>
<!-- 13b -->
<element name="deslocarAutomatico">
<complexType>
<sequence>
<element name="soap_session_id" type="xsd:string"/>
<element name="web_user_name" type="xsd:string"/>
<element name="NumeroOSStc" type="xsd:string"/>
<element name="DataHoraDoDeslocamento" type="xsd:dateTime"/>
<element name="KmFinalDeDeslocamento" type="xsd:string"/>
</sequence>
</complexType>
</element>
<!-- 13c -->
<element name="receberMsgTecnicoFinalDeslocamento">
<complexType>
<sequence>
<element name="soap_session_id" type="xsd:string"/>
<element name="web_user_name" type="xsd:string"/>
<element name="NumeroOSStc" type="xsd:string"/>
<element name="DataHoraFinalDaAtividade" type="xsd:dateTime"/>
<element name="kmFinalDeExecucao" type="xsd:string"/>
</sequence>
</complexType>
</element>
<!-- 13d -->
<element name="receberMsgTecnicoInicioExec">
<complexType>
<sequence>
<element name="soap_session_id" type="xsd:string"/>
<element name="web_user_name" type="xsd:string"/>
<element name="NumeroOSStc" type="xsd:string"/>
<element name="DataHoraFinalDaAtividade" type="xsd:dateTime"/>
</sequence>
</complexType>
</element>
<!-- 13e -->
<element name="receberMsgTecnicoFinalAtividade">
<complexType>
<sequence>
<element name="soap_session_id" type="xsd:string"/>
<element name="web_user_name" type="xsd:string"/>
<element name="NumeroOSStc" type="xsd:string"/>
<element name="DataHoraFinalDaAtividade" type="xsd:dateTime"/>
</sequence>
</complexType>
</element>
<complexType name="ArrayOfItemQtyConsumido">
<sequence>
<element minOccurs="0" maxOccurs="unbounded" name="ItemQtyConsumido" nillable="false" type="tns:ItemQtyConsumido" />
</sequence>
</complexType>
<complexType name="ItemQtyConsumido">
<sequence>
<element minOccurs="1" maxOccurs="1" name="ItemConsumido" type="xsd:string"/>
<element minOccurs="1" maxOccurs="1" name="QuantidadeItemConsumido" type="xsd:int"/>
</sequence>
</complexType>
<!-- 14 -->
<element name="encerrarAutomatico">
<complexType>
<sequence>
<element name="soap_session_id" type="xsd:string"/>
<element name="web_user_name" type="xsd:string"/>
<element name="NumeroOSStc" type="xsd:string"/>
<element name="Status" type="xsd:string"/>
<element name="InformacoesComplementares" type="xsd:string"/>
<element name="CodigoDeEncerramento" type="xsd:string"/>
<element name="DataHoraEncerramento" type="xsd:dateTime"/>
<element name="ProprietarioModem" type="xsd:string"/>
<element name="ModemRetirado" type="xsd:string"/>
<element name="NumRAT" type="xsd:string"/>
<element name="NotaFiscal" type="xsd:string"/>
<element name="ModemSemID" type="xsd:string"/>
<element name="Fonte" type="xsd:string"/>
<element name="USB" type="xsd:string"/>
<element name="Cbfonte" type="xsd:string"/>
<element name="Manual" type="xsd:string"/>
<element name="Cbrede" type="xsd:string"/>
<element name="CD" type="xsd:string"/>
<element name="Cbvoz" type="xsd:string"/>
<element name="Filtro" type="xsd:string"/>
<element name="QtdFiltro" type="xsd:string"/>
<element name="NaoAplicavel" type="xsd:string"/>
<element name="ATT" type="xsd:string"/>
<element name="CX" type="xsd:string"/>
<element name="SNR" type="xsd:string"/>
<element name="CB" type="xsd:string"/>
<element name="MAXT" type="xsd:string"/>
<element name="LAT" type="xsd:string"/>
<element name="DIST" type="xsd:string"/>
<element name="PAR" type="xsd:string"/>
<element name="SEC" type="xsd:string"/>
<element name="ARM" type="xsd:string"/>
<element name="ItemQtyConsumido" minOccurs="0" maxOccurs="1" type="tns:ArrayOfItemQtyConsumido"/>
<element name="SN" type="xsd:string"/>
</sequence>
</complexType>
</element>
<element name="ReturnWebBaseResponse" type="ns2:ReturnWebBase"/>
</schema></types>
WSDL em quatro partes: Parte 2, assinaturas dos métodos
<message name="SWAWiseEndpoint_encerrarAutomatico">
<part name="parameters" element="ns2:encerrarAutomatico"/>
</message>
<message name="SWAWiseEndpoint_encerrarAutomaticoResponse">
<part name="result" element="ns2:ReturnWebBaseResponse"/>
</message>
<message name="SWAWiseEndpoint_receberMsgTecnicoFinalDeslocamento">
<part name="parameters" element="ns2:receberMsgTecnicoFinalDeslocamento"/>
</message>
<message name="SWAWiseEndpoint_receberMsgTecnicoFinalDeslocamentoResponse">
<part name="result" element="ns2:ReturnWebBaseResponse"/>
</message>
<message name="SWAWiseEndpoint_receberMsgTecnicoInicioExec">
<part name="parameters" element="ns2:receberMsgTecnicoInicioExec"/>
</message>
<message name="SWAWiseEndpoint_receberMsgTecnicoInicioExecResponse">
<part name="result" element="ns2:ReturnWebBaseResponse"/>
</message>
<message name="SWAWiseEndpoint_receberMsgTecnicoFinalAtividade">
<part name="parameters" element="ns2:receberMsgTecnicoFinalAtividade"/>
</message>
<message name="SWAWiseEndpoint_receberMsgTecnicoFinalAtividadeResponse">
<part name="result" element="ns2:ReturnWebBaseResponse"/>
</message>
<message name="SWAWiseEndpoint_deslocarAutomatico">
<part name="parameters" element="ns2:deslocarAutomatico"/>
</message>
<message name="SWAWiseEndpoint_deslocarAutomaticoResponse">
<part name="result" element="ns2:ReturnWebBaseResponse"/>
</message>
<message name="SWAWiseEndpoint_acionarAutomatico">
<part name="parameters" element="ns2:acionarAutomatico"/>
</message>
<message name="SWAWiseEndpoint_acionarAutomaticoResponse">
<part name="result" element="ns2:ReturnWebBaseResponse"/>
</message>
<message name="SWAWiseEndpoint_testService">
<part name="parameters" element="ns2:testService"/>
</message>
<message name="SWAWiseEndpoint_testServiceResponse">
<part name="result" element="ns2:testServiceResponse"/>
</message>
<message name="SWAWiseEndpoint_wiseLogin">
<part name="parameters" element="ns2:wiseLogin"/>
</message>
<message name="SWAWiseEndpoint_wiseLoginResponse">
<part name="result" element="ns2:wiseLoginResponse"/>
</message>
WSDL em quatro partes: Parte 3, Port Type - Skeleton e nomes dos métodos
<portType name="SWAWiseEndpoint">
<operation name="encerrarAutomatico">
<input message="tns:SWAWiseEndpoint_encerrarAutomatico" name="SWAWiseEndpoint_encerrarAutomatico"/>
<output message="tns:SWAWiseEndpoint_encerrarAutomaticoResponse" name="SWAWiseEndpoint_encerrarAutomaticoResponse"/>
</operation>
<operation name="receberMsgTecnicoFinalDeslocamento">
<input message="tns:SWAWiseEndpoint_receberMsgTecnicoFinalDeslocamento" name="SWAWiseEndpoint_receberMsgTecnicoFinalDeslocamento"/>
<output message="tns:SWAWiseEndpoint_receberMsgTecnicoFinalDeslocamentoResponse" name="SWAWiseEndpoint_receberMsgTecnicoFinalDeslocamentoResponse"/>
</operation>
<operation name="receberMsgTecnicoInicioExec">
<input message="tns:SWAWiseEndpoint_receberMsgTecnicoInicioExec" name="SWAWiseEndpoint_receberMsgTecnicoInicioExec"/>
<output message="tns:SWAWiseEndpoint_receberMsgTecnicoInicioExecResponse" name="SWAWiseEndpoint_receberMsgTecnicoInicioExecResponse"/>
</operation>
<operation name="receberMsgTecnicoFinalAtividade">
<input message="tns:SWAWiseEndpoint_receberMsgTecnicoFinalAtividade" name="SWAWiseEndpoint_receberMsgTecnicoFinalAtividade"/>
<output message="tns:SWAWiseEndpoint_receberMsgTecnicoFinalAtividadeResponse" name="SWAWiseEndpoint_receberMsgTecnicoFinalAtividadeResponse"/>
</operation>
<operation name="deslocarAutomatico">
<input message="tns:SWAWiseEndpoint_deslocarAutomatico" name="SWAWiseEndpoint_deslocarAutomatico"/>
<output message="tns:SWAWiseEndpoint_deslocarAutomaticoResponse" name="SWAWiseEndpoint_deslocarAutomaticoResponse"/>
</operation>
<operation name="acionarAutomatico">
<input message="tns:SWAWiseEndpoint_acionarAutomatico" name="SWAWiseEndpoint_acionarAutomatico"/>
<output message="tns:SWAWiseEndpoint_acionarAutomaticoResponse" name="SWAWiseEndpoint_acionarAutomaticoResponse"/>
</operation>
<operation name="testService">
<input message="tns:SWAWiseEndpoint_testService" name="SWAWiseEndpoint_testService"/>
<output message="tns:SWAWiseEndpoint_testServiceResponse" name="SWAWiseEndpoint_testServiceResponse"/>
</operation>
<operation name="wiseLogin">
<input message="tns:SWAWiseEndpoint_wiseLogin" name="SWAWiseEndpoint_wiseLogin"/>
<output message="tns:SWAWiseEndpoint_wiseLoginResponse" name="SWAWiseEndpoint_wiseLoginResponse"/>
</operation>
</portType>
WSDL em quatro partes: Parte 4, Binding Style - Document Literal, HTTP, etc
<binding name="SWAWiseEndpointBinding" type="tns:SWAWiseEndpoint">
<soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="document"/>
<operation name="receberMsgTecnicoFinalDeslocamento">
<soap:operation soapAction="receberMsgTecnicoFinalDeslocamento"/>
<input name="SWAWiseEndpoint_receberMsgTecnicoFinalDeslocamento">
<soap:body use="literal"/>
</input>
<output name="SWAWiseEndpoint_receberMsgTecnicoFinalDeslocamentoResponse">
<soap:body use="literal"/>
</output>
</operation>
<operation name="receberMsgTecnicoInicioExec">
<soap:operation soapAction="receberMsgTecnicoInicioExec"/>
<input name="SWAWiseEndpoint_receberMsgTecnicoInicioExec">
<soap:body use="literal"/>
</input>
<output name="SWAWiseEndpoint_receberMsgTecnicoInicioExecResponse">
<soap:body use="literal"/>
</output>
</operation>
<operation name="receberMsgTecnicoFinalAtividade">
<soap:operation soapAction="receberMsgTecnicoFinalAtividade"/>
<input name="SWAWiseEndpoint_receberMsgTecnicoFinalAtividade">
<soap:body use="literal"/>
</input>
<output name="SWAWiseEndpoint_receberMsgTecnicoFinalAtividadeResponse">
<soap:body use="literal"/>
</output>
</operation>
<operation name="encerrarAutomatico">
<soap:operation soapAction="encerrarAutomatico"/>
<input name="SWAWiseEndpoint_encerrarAutomatico">
<soap:body use="literal"/>
</input>
<output name="SWAWiseEndpoint_encerrarAutomaticoResponse">
<soap:body use="literal"/>
</output>
</operation>
<operation name="receberMsgTecnicoInicioExec">
<soap:operation soapAction="receberMsgTecnicoInicioExec"/>
<input name="SWAWiseEndpoint_receberMsgTecnicoInicioExec">
<soap:body use="literal"/>
</input>
<output name="SWAWiseEndpoint_receberMsgTecnicoInicioExecResponse">
<soap:body use="literal"/>
</output>
</operation>
<operation name="wiseLogin">
<soap:operation soapAction="wiseLogin"/>
<input name="SWAWiseEndpoint_wiseLogin">
<soap:body use="literal"/>
</input>
<output name="SWAWiseEndpoint_wiseLoginResponse">
<soap:body use="literal"/>
</output>
</operation>
<operation name="testService">
<soap:operation soapAction="testService"/>
<input name="SWAWiseEndpoint_testService">
<soap:body use="literal"/>
</input>
<output name="SWAWiseEndpoint_testServiceResponse">
<soap:body use="literal"/>
</output>
</operation>
<operation name="acionarAutomatico">
<soap:operation soapAction="acionarAutomatico"/>
<input name="SWAWiseEndpoint_acionarAutomatico">
<soap:body use="literal"/>
</input>
<output name="SWAWiseEndpoint_acionarAutomaticoResponse">
<soap:body use="literal"/>
</output>
</operation>
<operation name="deslocarAutomatico">
<soap:operation soapAction="deslocarAutomatico"/>
<input name="SWAWiseEndpoint_deslocarAutomatico">
<soap:body use="literal"/>
</input>
<output name="SWAWiseEndpoint_deslocarAutomaticoResponse">
<soap:body use="literal"/>
</output>
</operation>
</binding>
<service name="SWAWiseService">
<port name="SWAWiseEndpointPort" binding="tns:SWAWiseEndpointBinding">
<soap:address location="http://200.129.63.33/swa_ws_test/services/SWAWiseEndpoint"/></port></service></definitions>
SWA Arquitetura e Alternativas
Exeções alternativas: WSDL:fault
Prós - a parte padrão de WSDL
Contras - não é simples, só Java tem RuntimeException(SOAPFaultException) e Checked Exceptions(RemoteException), em geral, muitos problemas.
WSDL Fault, individualizada:
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:stns="java:WS.exception"
elementFormDefault="qualified"
attributeFormDefault="qualified"
targetNamespace="java:WS.exception">
<xsd:import namespace="java:language_builtins.lang">
</xsd:import>
<xsd:element type="stns:MyCustomException"
name="MyCustomException">
</xsd:element>
<xsd:complexType name="MyCustomException">
<xsd:sequence>
<xsd:element type="xsd:string"
name="errorCode"
minOccurs="1"
nillable="true"
maxOccurs="1">
</xsd:element>
<xsd:element type="xsd:string"
name="errorDescription"
minOccurs="1"
nillable="true"
maxOccurs="1">
</xsd:element>
<xsd:element xmlns:tp="java:language_builtins.lang"
type="tp:ArrayOfString"
name="variables"
minOccurs="1"
nillable="true"
maxOccurs="1">
</xsd:element>
</xsd:sequence>
</xsd:complexType>
</xsd:schema>
<message name="MyCustomException">
<part xmlns:partns="java:WS.exception"
type="partns:MyCustomException"
name="MyCustomException">
</part>
</message>
<portType name="ESPort">
<operation name="echo">
<input message="tns:echo">
</input>
<output message="tns:echoResponse">
</output>
<fault name="MyCustomException"
message="tns:MyCustomException">
</fault>
</operation>
</portType>
Session state alternativas - cookies, WS-Addressing
Prós - todo mundo conhece cookies(Servlet Session JSESSIONID, etc), WS-Addressing está chegando como um padrão.
Contras - cookies e web services não combinam bem, não funciona entre web services multiplos juntos, muitas regras complexas e particulares na linguagem de programação. Tem que depender do Cliente fazer 'setMaintainSession(true)' . WS-Addressing é novo, complexo, e no fluxo ainda.
Session state alternativas - EJB Stateful Session Beans
Prós - Funciona semelhante ao Cookie, com timeout pelo servidor (JBoss, WebSphere).
Contras - todas as desvantagens de EJB
public interface EJBObject extends java.rmi.Remote
The EJBObject interface is extended by all
enterprise Beans' remote interfaces.
private String getId(EJBObject session)
throws ServiceLocatorException {
String id = null;
try {
Handle handleSoapSession =
session.getHandle();
ByteArrayOutputStream baos =
new ByteArrayOutputStream();
ObjectOutputStream stream =
new ObjectOutputStream(baos);
stream.writeObject(
handleSoapSession);
stream.flush();
stream.close();
id = new String(Base64.encode(
baos.toByteArray()));
} catch(Exception ex) {
throw new ServiceLocatorException(
ex.getMessage());
}
return id;
}
SWA Session State - Universally Unique Identifier (UUID)
Prós - UUID é um padrão de 'Open Software Foundation', independente de linguagem de programação. UUID é disponível para .Net pelo Microsoft's Globally Unique Identifiers (GUIDs), que implementa UUID. Para Java, temos java.util.UUID, que gera uma String aleatoriamente. Segurança é forte com 128 bits.
Contras - SWA precisa guardar e expirar os UUID's. Web Services que SWA acessa do Foconet e Wise Mobil precisa tratar os UUID's também. Pode ser com Singletons, Ehcache, JBoss Tree Cache, etc. SWA hoje em dia está usando Ehcache.
/**
* Auto generated method signature.
* @param wiseLoginDocument input complex object
* @return WiseLoginResponseDocument complex object return values
*/
public WiseLoginResponseDocument wiseLogin(
WiseLoginDocument wiseLoginDocument) {
// prepare output
WiseLoginResponseDocument retDoc =
WiseLoginResponseDocument.Factory.newInstance();
WiseLoginResponse retElement =
WiseLoginResponse.Factory.newInstance();
try {
// Get parameters passed in
WiseLogin wiseLogin = wiseLoginDocument.getWiseLogin();
String userName = wiseLogin.getUserName();
String password = wiseLogin.getUserPassword();
if (logger.isDebugEnabled()) {
logger.debug("wiseLogin "
+ "reached successfully by user: " + userName);
}
WebServiceAuthenticator authenticator = (WebServiceAuthenticator)
ObjectFactory.getObject("webServiceAuthenticator");
WiseMobilAdapter wiseMobilAdapter = (WiseMobilAdapter)
ObjectFactory.getObject("wiseMobilAdapter");
if (authenticator.authenticate(userName, password)) {
retElement.setWebUserName(userName);
retElement.setSoapSessionId(
authenticator.provisionSoapSessionId(userName));
retElement.setErrorMessage(MessagesCodes.getMessage(
MessagesCodes.SUCCESS));
retElement.setSuccessErrorCode(MessagesCodes.SUCCESS);
} else {
wiseMobilAdapter.handleDefaultAuthenticationError(
retElement, userName);
}
if (logger.isDebugEnabled()) {
logger.debug("wiseLogin "
+ "returning to user: " + userName);
}
} catch (Exception ex) {
logger.error("SWAWiseEndpointSkeleton.wiseLogin:"
+ ex.getMessage(), ex);
retElement.setErrorMessage(ex.getMessage());
retElement.setSuccessErrorCode(MessagesCodes.FAILURE);
}
retDoc.setWiseLoginResponse(retElement);
return retDoc;
}
/**
* Auto generated method signature.
* @param deslocarAutomaticoDocument input complex object
* @return ReturnWebBaseResponseDocument default complex object
* return values
*/
public ReturnWebBaseResponseDocument deslocarAutomatico(
DeslocarAutomaticoDocument
deslocarAutomaticoDocument) {
// prepare output
ReturnWebBaseResponseDocument retDoc =
ReturnWebBaseResponseDocument.Factory.newInstance();
ReturnWebBase retElement =
ReturnWebBase.Factory.newInstance();
DeslocarAutomatico deslocarAutomatico =
deslocarAutomaticoDocument.getDeslocarAutomatico();
try {
String soapSessionId =
deslocarAutomatico.getSoapSessionId();
String webUserName = deslocarAutomatico.getWebUserName();
if (logger.isDebugEnabled()) {
logger.debug("informarTecnicosList() "
+ "reached successfully by user: " + webUserName);
}
WebServiceAuthenticator authenticator = (WebServiceAuthenticator)
ObjectFactory.getObject("webServiceAuthenticator");
WiseMobilAdapter wiseMobilAdapter = (WiseMobilAdapter)
ObjectFactory.getObject("wiseMobilAdapter");
if (!authenticator.validateSoapSessionId(soapSessionId,
webUserName)) {
wiseMobilAdapter.handleDefaultTimeout(retElement, webUserName);
} else {
wiseMobilAdapter.deslocarAutomatico(retElement,
deslocarAutomatico.getNumeroOSStc(),
deslocarAutomatico.getDataHoraDoDeslocamento(),
deslocarAutomatico.getKmFinalDeDeslocamento());
}
} catch (Exception ex) {
logger.error("SWAWiseEndpointSkeleton.deslocarAutomatico:"
+ ex.getMessage(), ex);
retElement.setErrorMessage(ex.getMessage());
retElement.setSuccessErrorCode(MessagesCodes.FAILURE);
}
retDoc.setReturnWebBaseResponse(retElement);
return retDoc;
}
/** @see com.siemens.swa.webservices.security#WebServiceAuthenticator */
public String provisionSoapSessionId(String userName) {
UUID uuid = UUID.randomUUID();
UUIDCache cache = UUIDCache.getInstance();
Calendar now = new GregorianCalendar();
cache.putTimeStamp(uuid.toString(), now.getTimeInMillis());
if (logger.isDebugEnabled()) {
logger.debug("username: " + userName
+ " assigned soapSessionId: "
+ uuid.toString());
}
return uuid.toString();
}
/** @see com.siemens.swa.webservices.security#WebServiceAuthenticator */
public boolean validateSoapSessionId(String soapSessionId,
String userName) {
UUIDCache cache = UUIDCache.getInstance();
if (!cache.hasSOAPSession(soapSessionId)) {
logger.error("validateSoapSessionId() Can't find "
+ "soapSessionId: "
+ soapSessionId
+ "for user: " + userName);
return false;
} else {
if (logger.isDebugEnabled()) {
logger.debug("username: " + userName
+ " successfully found cached soapSessionId: "
+ soapSessionId);
}
}
// add policy time to last access time, and verify
// its before 'now'
Calendar soapTimeOut = new GregorianCalendar();
soapTimeOut.setTimeInMillis(cache.getTimeStamp(soapSessionId));
soapTimeOut.add(Calendar.MINUTE, this.timeout);
Calendar now = new GregorianCalendar();
if (now.before(soapTimeOut)) {
// renew timeout lease
cache.putTimeStamp(soapSessionId, now.getTimeInMillis());
if (logger.isDebugEnabled()) {
logger.debug("username: " + userName
+ " renewed soapTimeOut lease to time: "
+ DF.format(now.getTime()));
logger.debug("username soapSessionId valid, "
+ "returning true: " + userName);
}
return true;
} else {
logger.error("soapSessionId timed out for user: "
+ userName + ", System time: " + DF.format(now.getTime())
+ "is after timeout: "
+ DF.format(soapTimeOut.getTime())
+ ", timeout policy in minutes is: " + timeout);
}
return false;
}
O que é Axis2 ?
Um SOAP Processing Engine
Web Services Client API
Web Services Server API ( HTTP e SMTP )
WSDL2Java - gera fontes Java do WSDL automaticamente
SAAJ implementação (enviar arquivos em anexo)
Arquitetura flexível e extensivel
Ferramentas, exemplos, documentação
Open source de apache
A mais avançada versão de Web Services para Java que existe hoje - particularmente sobre segurança
Arquitetura de Apache Axis2
Estrutura de uma aplicação Axis2 Pasta WEB-INF
WEB-INF/ WEB-INF/modules WEB-INF/modules/LoggingModule.mar WEB-INF/modules/addressing.mar WEB-INF/modules/security.mar WEB-INF/services WEB-INF/services/RCService.aar WEB-INF/services/SWASmartEndpoint.aar WEB-INF/services/SWAWiseEndpoint.aar WEB-INF/axis2.xml WEB-INF/classes WEB-INF/lib
Estrutura de um AAR (Axis Archive) - um jar com extensão .aar. Vantagems do AAR são hot deploy, todo AAR tem um classloader separado.
![]() |
./META-INF ./META-INF/MANIFEST.MF ./META-INF/SWAWiseEndpoint.wsdl ./META-INF/services.xml ./com ./com/siemens ./com/siemens/swa ./com/siemens/swa/webservices ./com/siemens/swa/webservices/wisemobil ./com/siemens/swa/webservices/wisemobil/SWAWiseEndpointSkeleton.class
Estrutura de services.xml - se tiver WSDL, services.xml será gerado automaticamente pelo WSDL2Java
<!--Auto generated Axis Service XML--> <service name="SWAWiseEndpoint"> <parameter locked="false" name="ServiceClass">com.siemens.swa.webservices.wisemobil.SWAWiseEndpointSkeleton</parameter> <!--Mounting the method receberMsgTecnicoFinalDeslocamento--> <operation name="receberMsgTecnicoFinalDeslocamento"> <messageReceiver class="com.siemens.swa.webservices.wisemobil.SWAWiseEndpointMessageReceiver"/> </operation> <!--Mounting the method wiseLogin--> <operation name="wiseLogin"> <messageReceiver class="com.siemens.swa.webservices.wisemobil.SWAWiseEndpointMessageReceiver"/> </operation> <!--Mounting the method receberMsgTecnicoFinalAtividade--> <operation name="receberMsgTecnicoFinalAtividade"> <messageReceiver class="com.siemens.swa.webservices.wisemobil.SWAWiseEndpointMessageReceiver"/> </operation> <!--Mounting the method deslocarAutomatico--> <operation name="deslocarAutomatico"> <messageReceiver class="com.siemens.swa.webservices.wisemobil.SWAWiseEndpointMessageReceiver"/> </operation> <!--Mounting the method receberMsgTecnicoInicioExec--> <operation name="receberMsgTecnicoInicioExec"> <messageReceiver class="com.siemens.swa.webservices.wisemobil.SWAWiseEndpointMessageReceiver"/> </operation> <!--Mounting the method acionarAutomatico--> <operation name="acionarAutomatico"> <messageReceiver class="com.siemens.swa.webservices.wisemobil.SWAWiseEndpointMessageReceiver"/> </operation> <!--Mounting the method encerrarAutomatico--> <operation name="encerrarAutomatico"> <messageReceiver class="com.siemens.swa.webservices.wisemobil.SWAWiseEndpointMessageReceiver"/> </operation> <!--Mounting the method testService--> <operation name="testService"> <messageReceiver class="com.siemens.swa.webservices.wisemobil.SWAWiseEndpointMessageReceiver"/> </operation> </service>
Axis2 Web Services, Skeletons, Stubs, e Callbacks:
Skeleton e Stubs existem em outros Frameworks de programação, tal como RMI. Callbacks existem em outros Frameworks também, tal como JAAS (Java Authentication and Authorization Service) - segurança para Java. Com Axis2, o Skeleton, Stubs e Callbacks são gerados automaticamente pelo WSDL2Java. Definições: 1. Skeleton, o Web Service mesmo, ou seja, o servidor. 2. Stub, o API da cliente. 3. Callback - o API da Cliente para chamar o Web Services assíncrono, ou seja, sem esperar pelo retorno. Callbacks são parecido com function pointers na linguagem C.
Axis2 Web Services, etapa a etapa:
1. Escrever WSDL 2. Rodar WSDL2Java 3. Compilar os fontes Java gerado pelo WSDL2Java, menos o Skeleton e Callback. Cria um Jar com estes fontes. 4. Escreve as regras de negocio e arquitetura da sua aplicação por dentro o Skeleton. 5. Criar um AAR com o Skeleton. 6. Criar um WAR com a estrutura do Axis2, com o AAR por dentro. 7. Validar que o WAR com os Web Services estão instalado corretamente. 8. Criar o cliente que vai chamar os Web Services, usando o Stub, com a opção do Callback.
Etapa 1, Escrever o WSDL. Pode usar o exemplo acima
Etapa 2, Axis2 WSDL2Java, pelo Ant
Nota: Axis2 por default está usando XMLBeans,
mas, com Axis2, a transformação de XML pra
Java é 'pluggable'- pode usar JAXB invês de
XMLBeans
<target name="wise_wsdl2java" depends="clean,init">
<delete dir="${build.dir}/output" />
<java classname="org.apache.axis2.wsdl.WSDL2Java" fork="true">
<classpath refid="compile.classpath"/>
<arg value="-uri"/>
<arg file="${proj.swa}/src/java/com/siemens/swa/webservices/wisemobil/SWAWiseEndpoint.wsdl"/>
<arg value="-ss"/>
<arg value="-sd"/>
<arg value="-o"/>
<arg file="${build.dir}/output"/>
<arg value="-p"/>
<arg value="com.siemens.swa.webservices.wisemobil"/>
</java>
<!-- Move the schema folder to classpath-->
<move todir="${build.classes}">
<fileset dir="${build.dir}/output">
<include name="**/*schema*/**/*.class"/>
<include name="**/*schema*/**/*.xsb"/>
</fileset>
</move>
<!-- copy mandatory files generated by wsdl2java to package
for easy deployment
-->
<copy todir="${proj.swa}/src/java/com/siemens/swa/webservices/wisemobil/" >
<fileset dir="${build.dir}/output/service_descriptors/SWAWiseEndpoint" >
<!-- axis2 web services definitions file -->
<include name="**/services.xml"/>
</fileset>
</copy>
</target>
![]() |
Etapa 3, Complilar os fontes Java gerado pelo WSDL2Java, menos o Skeleton e Callback. Cria um Jar com estes fontes.
<!-- If methods are added or removed, look at the output/skeleton for the new method signature.
The same applies for the callback. If not used, the callback can simply be overwritten
in its components package. Its for this reason that this task doesn't call 'clean' - you
may need something from the skeleton and callback files.
-->
<target name="wise_jar_wsdl" depends="compile_wsdl">
<delete file="${build.classes}/com/siemens/swa/webservices/wisemobil/SWAWiseEndpointCallbackHandler.class" />
<delete file="${build.classes}/com/siemens/swa/webservices/wisemobil/SWAWiseEndpointSkeleton.class" />
<jar jarfile="${proj.lib}/axis2/swa_wise_wsdl.jar" >
<fileset dir="${build.classes}" />
</jar>
</target>
<target name="compile_wsdl">
<echo message="Compiling wsdl2 files"/>
<javac
destdir="${build.classes}"
deprecation="true"
failonerror="true" debug="true"
>
<src path="${build.dir}/output"/>
<exclude name="**/*Skel*"/>
<exclude name="**/*Callback*"/>
<classpath refid="compile.classpath"/>
</javac>
</target>
![]() |
Etapa 4, Escreve as regras de negocio e arquitectura da sua aplicação por dentro o Skeleton.
WSDL2Java, com o exemplo por cima, vai produzir um Skeleton assim:
/home/iksrazal/workspace/swa_oi/applications/velox/build/output/com/siemens/swa/webservices/wisemobil/SWAWiseEndpointSkeleton.java
/**
* SWAWiseEndpointSkeleton.java
*
* This file was auto-generated from WSDL
* by the Apache Axis2 version: 0.93 Dec 02, 2005 (08:37:58 LKT)
*/
package com.siemens.swa.webservices.wisemobil;
/**
* SWAWiseEndpointSkeleton java skeleton for the axisService
*/
public class SWAWiseEndpointSkeleton {
/**
* Auto generated method signature
* @param param0
*/
public com.siemens.swa.webservices.wisemobil.databinding.swaWiseNS.ReturnWebBaseResponseDocument receberMsgTecnico
FinalDeslocamento
(com.siemens.swa.webservices.wisemobil.databinding.swaWiseNS.ReceberMsgTecnicoFinalDeslocamentoDocument p
aram0 ){
//Todo fill this with the necessary business logic
return null;
}
...
A idéia é transformar esse código do 'output', para:
/home/iksrazal/workspace/swa_oi/components/swa/src/java/com/siemens/swa/webservices/wisemobil/SWAWiseEndpointSkeleton.java
/**
* SWAWiseEndpointSkeleton java skeleton for the axisService.
*/
public class SWAWiseEndpointSkeleton {
/**
* Auto generated method signature.
* @param receberMsgTecnicoFinalDeslocamentoDocument input complex object
* @return ReturnWebBaseResponseDocument default complex object
* return values
*/
public ReturnWebBaseResponseDocument receberMsgTecnicoFinalDeslocamento(
ReceberMsgTecnicoFinalDeslocamentoDocument
receberMsgTecnicoFinalDeslocamentoDocument) {
// prepare output
ReturnWebBaseResponseDocument retDoc =
ReturnWebBaseResponseDocument.Factory.newInstance();
ReturnWebBase retElement =
ReturnWebBase.Factory.newInstance();
ReceberMsgTecnicoFinalDeslocamento
receberMsgTecnicoFinalDeslocamento =
receberMsgTecnicoFinalDeslocamentoDocument.
getReceberMsgTecnicoFinalDeslocamento();
try {
String soapSessionId =
receberMsgTecnicoFinalDeslocamento.getSoapSessionId();
String webUserName =
receberMsgTecnicoFinalDeslocamento.getWebUserName();
if (logger.isDebugEnabled()) {
logger.debug("receberMsgTecnicoFinalDeslocamento() "
+ "reached successfully by user: " + webUserName);
}
WebServiceAuthenticator authenticator = (WebServiceAuthenticator)
ObjectFactory.getObject("webServiceAuthenticator");
WiseMobilAdapter wiseMobilAdapter = (WiseMobilAdapter)
ObjectFactory.getObject("wiseMobilAdapter");
if (!authenticator.validateSoapSessionId(soapSessionId,
webUserName)) {
wiseMobilAdapter.handleDefaultTimeout(retElement, webUserName);
} else {
wiseMobilAdapter.receberMsgTecnicoFinalDeslocamento(retElement,
receberMsgTecnicoFinalDeslocamento.getNumeroOSStc(),
receberMsgTecnicoFinalDeslocamento.
getDataHoraFinalDaAtividade(),
receberMsgTecnicoFinalDeslocamento.getKmFinalDeExecucao());
}
} catch (Exception ex) {
logger.error(
"SWAWiseEndpointSkeleton.receberMsgTecnicoFinalDeslocamento:"
+ ex.getMessage(), ex);
retElement.setErrorMessage(ex.getMessage());
retElement.setSuccessErrorCode(MessagesCodes.FAILURE);
}
retDoc.setReturnWebBaseResponse(retElement);
return retDoc;
}
...
Etapa 5, Criar um AAR com o Skeleton.
<!-- build an .aar file for axis2 web services -->
<target name="wise_aar" depends="clean,compile">
<mkdir dir="${build.classes}/temp/META-INF" />
<copy todir="${build.classes}/temp/META-INF" >
<fileset dir="${proj.swa}/src/java/com/siemens/swa/webservices/wisemobil" >
<!-- axis2 web services definitions file -->
<include name="services.xml"/>
<include name="SWAWiseEndpoint.wsdl"/>
</fileset>
</copy>
<copy todir="${build.classes}/temp/" >
<fileset dir="${build.classes}" >
<!-- axis2 web services definitions file -->
<include name="**/SWAWiseEndpointSkeleton.class"/>
</fileset>
</copy>
<jar jarfile="${proj.etc.war}/velox/WEB-INF/services/SWAWiseEndpoint.aar" >
<fileset dir="${build.classes}/temp" />
</jar>
</target>
![]() |
Etapa 6, Cria um WAR com a estrutura de Axis2, com o AAR por dentro.
![]() |
Etapa 7, Validar que o WAR com os Web Services estão instalados corretamente.
![]() |
Etapa 8, Criar o cliente que vai chamar os Web Services, usando o Stub, Callback ou 'Fire and Forget'.
Primeiro exemplo, Stub
/**
* Dados do Despacho Automático - #12.
* @param despacharAutomatico complex object for remote call
* @throws WebServiceClientException for all errors
*/
public void despacharAutomaticoClient(
DespacharAutomatico despacharAutomatico)
throws WebServiceClientException {
try {
if (!this.webServiceAuthenticator.clientHasValidToken(
userName + WISE)) {
runLogin();
}
// set mandatory session info
despacharAutomatico.setSoapSessionId(
this.webServiceAuthenticator.getClientToken(
this.userName + WISE));
despacharAutomatico.setWebUserName(this.userName);
if (!despacharAutomatico.validate()) {
throw new WebServiceClientException(
"complex objeto despacharAutomatico não é válida");
}
DespacharAutomaticoDocument despacharAutomaticoDocument =
DespacharAutomaticoDocument.Factory.newInstance();
despacharAutomaticoDocument.
setDespacharAutomatico(despacharAutomatico);
WiseSWAEndpointStub stub =
new WiseSWAEndpointStub(null, this.endpoint);
Options options = stub._getClientOptions();
options.setAction("despacharAutomatico");
ReturnWebBaseResponseDocument returnWebBaseResponseDocument =
stub.despacharAutomatico(despacharAutomaticoDocument);
if (logger.isDebugEnabled()) {
logger.debug("despacharAutomatico returned successfully");
}
ReturnWebBase returnWebBase =
returnWebBaseResponseDocument.getReturnWebBaseResponse();
if (returnWebBase.getSuccessErrorCode() != 0) {
throw new Exception("despacharAutomaticoClient "
+ "failed with error code: "
+ returnWebBase.getSuccessErrorCode()
+ ", message: "
+ returnWebBase.getErrorMessage());
} else {
System.out.println("\ndespacharAutomatico, Success!!!\n");
if (logger.isDebugEnabled()) {
handleDefaultSuccess(returnWebBase, "despacharAutomatico");
}
}
} catch (Exception ex) {
logger.error(ex.getMessage(), ex);
throw new WebServiceClientException(
ex.getMessage(), ex);
}
}
Segundo exemplo, Callbacks - chamadas remotas assíncronas
/**
* Sample for asynchronous dual channel non-blocking service invocation.
* Message Exchage Pattern IN-OUT
* Ulitmate asynchronous service invocation sample.
*/
public class RCServiceClient {
/** Access point inside the servlet container. **/
private static EndpointReference targetEPR =
new EndpointReference(
"http://127.0.0.1:8080/swa_ws_test/services/RCService");
/**
* Main.
*
* @param args Main
*/
public static void main(String[] args) {
try {
OMElement payload = ClientUtil.getRCExecuteOMElement();
Options options = new Options();
options.setTo(targetEPR);
options.setUseSeparateListener(true);
Call call = new Call();
call.setClientOptions(options);
//Callback to handle the response
Callback callback = new Callback() {
public void onComplete(AsyncResult result) {
try {
SOAPEnvelope env = result.getResponseEnvelope();
env.toString();
StringWriter writer = new StringWriter();
env.serialize(writer);
System.out.println("inside onComplete...");
writer.flush();
System.out.println(writer.toString());
} catch (XMLStreamException e) {
reportError(e);
}
}
public void reportError(Exception e) {
e.printStackTrace();
}
};
//Non-Blocking Invocation
call.invokeNonBlocking("rcExecute", payload, callback);
//Wait till the callback receives the response.
System.out.println("RC Service executed, "
+ "sleeping until completion, DO SOMETHING ELSE HERE...");
while (!callback.isComplete()) {
Thread.sleep(1000);
}
//Need to close the Client Side Listener.
call.close();
System.out.println("RC Service completed");
} catch (AxisFault axisFault) {
axisFault.printStackTrace();
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
Terceiro exemplo, 'Fire and Forget' - chamadas remotas sem retorno, bom para tarefas longas (Radio Commander)
public class RCFireAndForgetClient {
/** URL do RCService. **/
private static EndpointReference targetEPR =
new EndpointReference(
"http://127.0.0.1:8080/swa_ws_test/services/RCService");
/**
* Chama o web service com main() - fora do Servlet Container.
*
* @param args Main
*/
public static void main(String[] args) {
try {
OMElement payload = ClientUtil.getFireAndForgetOMElement();
Options options = new Options();
options.setTo(targetEPR);
MessageSender msgSender = new MessageSender();
msgSender.setClientOptions(options);
System.out.println("rcFireAndForget, firing...");
msgSender.send("rcFireAndForget", payload);
System.out.println("rcFireAndForget, completed!!!");
} catch (AxisFault axisFault) {
axisFault.printStackTrace();
}
}
}
Web Services Security
Nós temos um problema grande com o demonstação de web services até agora - segurança. A mensagem 'hello world', abaixo, foi transmitida em 'clear text' - um hacker pode ler a mensagem e mudar a mensagem tambem. Pode-se ver esse problema pelo SOAPMonitor applet
![]() |
Vamos olhar o SOAP Monitor de novo no browser. A esquerda são os dados que o cliente está enviando, e a direta é a reposta do web service. Esses informações são encríptadas e tem uma XML Digital signature. Somente para 'hello world' , temos esse resultado
![]() |
O que é Web Services Security?
Existem quatro áreas que um modelo de segurança para comunicação das dados deve tratar:
Integridade:
Permitir ao destinatário de uma mensagem verificar que a mensagem não foi modificada desde seu envio pelo remetente.Confidencialidade:
Assegurar-se de que uma mensagem pode ser lida somente pelo destinatário.
Autenticação:
Permitir a um destinatário assegurar-se de quem é o remetente da mensagem.
Comprovação:
Permitir ao um destinatário comprovar que o remetente enviou uma mensagem.
As tecnologias que tratam dessas áreas em Web Services Security são XML Encryption e XML Digital Signatures
XML Signatures
Uma especificacão que é um esforço conjunto de W3C e IETF
Providenciar para integridade das dados e autenticação (as duas mensagens e 'signer authentication') características, dentro XML formato
Implementado no Java pelo JSR-105
XML Encryption
Um especificação de W3C
Providenciar para confidencialidade das dados usando encryption características, dentro das XML tags definidas pela especificacão XML encryption
Implementado no Java pelo JSR-106
![]() |
Apache Axis SOAP Handlers
- Axis tecnologia 'Handlers' pode agir como um XML Firewall, fazendo o encryption e assinando o XML Signatures na saida do Cliente, e validar o XML Signatures e fazer o decryption no recepcão pelo lado do Web Services Servidor. Na volta de dados de Servidor pelo Cliente, o inverso pode acontecer
- Descubra o que varia, e encapsule-o . Requisitos sobre segurança, implementaçôes do XML Signature e XML Encryption, etc, é provável que mudanças venham. Com Axis Handlers, manutenção deverá ser mais fácil
Para mais informações sobre Axis2, dê uma lida sobre o artigo 'Avoiding Mistakes Made Using Axis2
![]() |