Introducão  
de  
web services
 

Além de propaganda 

Por Robert Lazarski

 
 

Agenda 

O que é web services?

Golden Hammer

Breve história de distributed programming

Qual é o motivo de usar Web Services?

Quando não usar Web Services para chamdas remotas?

 
 

-----------------------------------------------------------

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

    XML Schema Data Type

    Equivalent Java Data Type

    (lower case indicates a primitive data type)

    boolean

    boolean

    byte

    byte

    short

    short

    int

    int

    long

    long

    float

    float

    double

    double

    integer

    java.math.BigInteger

    decimal

    java.math.BigDecimal

    string

    java.lang.String

    dateTime

    java.util.Calendar

    base64Binary

    byte[]

    hexBinary

    byte[]

    duration

    java.lang.String

    time

    java.util.Calendar

    date

    java.util.Calendar

    gYearMonth

    java.lang.String

    gYear

    java.lang.String

    gMonthDay

    java.lang.String

    gDay

    java.lang.String

    gMonth

    java.lang.String

    anyURI

    java.net.URI

    NOTATION

    java.lang.String

    token

    java.lang.String

    normalizedString

    java.lang.String

    language

    java.lang.String

    Name

    java.lang.String

    NMTOKEN

    java.lang.String

    NCName

    java.lang.String

    NMTOKENS

    java.lang.String[]

    ID

    java.lang.String

    IDREF

    java.lang.String

    ENTITY

    java.lang.String

    IDREFS

    java.lang.String[]

    ENTITIES

    java.lang.String[]

    nonPositiveInteger

    java.math.BigInteger

    nonNegativeInteger

    java.math.BigInteger

    negativeInteger

    java.math.BigInteger

    unsignedLong

    java.math.BigInteger

    positiveInteger

    java.math.BigInteger

    unsignedInt

    long

    unsignedShort

    int

    unsignedByte

    short

    Qname

    javax.xml.namespace.QName

      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