Em que ano apareceram os serviços da web de sabão. Listagem da classe PersonServiceImpl

Com a evolução da Internet, surgiu a necessidade de criar aplicativos distribuídos. Os aplicativos instalados em um computador geralmente usam as bibliotecas localizadas nele. Vários programas podem usar uma biblioteca. Os análogos da biblioteca podem ser publicados na Internet para que diferentes sites possam chamá-los? Acontece que sim.

As empresas em suas páginas fornecem uma variedade de informações. Por exemplo, em seu site http://www.Ford.com, a empresa Ford publica informações sobre modelos e preços. O revendedor desta empresa também gostaria de ter essas informações em seu site. O serviço da web permite que um site de consumidor recupere informações de um site de provedor. O site do consumidor exibe essas informações em suas páginas. O código para gerar essas informações é escrito uma vez, mas pode ser usado por muitos consumidores. Os dados são apresentados em texto simples, portanto podem ser usados ​​independentemente da plataforma.

Os serviços da Web são amplamente usados ​​em aplicativos de desktop e de Internet. Eles não são aplicativos em si, mas fontes de dados para aplicativos. Eles estão sumidos interface de usuário... Os serviços da Web não precisam ser usados ​​na rede - eles podem fazer parte do projeto no qual são usados.

Os serviços da Web são funcionalidades e dados fornecidos para uso por aplicativos externos que interagem com os serviços por meio de protocolos e formatos de dados padrão. Os serviços da Web são totalmente independentes de linguagem e plataforma. A tecnologia de serviços da Web é a base do modelo de programação da Microsoft. LÍQUIDO.

isto desenvolvimento adicional programação de componentes CORBA e DCOM. Porém, para utilizar tais componentes, é necessário cadastrá-los no sistema do consumidor. Isso não é necessário para serviços da web. Os componentes funcionam bem em redes locais. HTTP não é um protocolo de chamada de procedimento remoto (RPC). Mesmo dentro da mesma organização, diferentes SO que só pode se comunicar por HTTP.

Várias tentativas têm sido feitas para criar uma linguagem de comunicação entre sistemas heterogêneos - DCOM, CORBA, RMI, IIOP. Não recebiam distribuição geral, pois cada um deles era promovido por fabricantes diferentes e, portanto, estava vinculado às tecnologias de um determinado fabricante. Ninguém queria aceitar o padrão de outra pessoa. Para superar esse dilema, várias empresas concordaram em desenvolver um padrão neutro de fornecedor para mensagens sobre HTTP. Em maio de 2000, IBM, Microsoft, HP, Lotus, SAP, UserLand e outros abordaram o W3C e apresentaram o SOAP como candidato a esse padrão. O SOAP revolucionou o desenvolvimento de aplicativos ao unir dois padrões da Internet, HTTP e XML.

SABÃO

Para interagir com os serviços da web, o protocolo SOAP baseado em XML é usado. Você poderia usar apenas XML, mas este é um formato muito vago, no qual cada documento realmente cria sua própria linguagem. SABÃOé uma convenção sobre o formato de um documento XML, sobre a presença de certos elementos e namespaces nele.

O SOAP permite que você publique e consuma estruturas de dados complexas, como um DataSet. Ao mesmo tempo, é fácil de aprender. Versão Atual SOAP - 1.2.

SOAP significa Simple Object Access Protocol. O SOAP foi projetado para facilitar a comunicação dos aplicativos por HTTP. É um formato de mensagem independente de plataforma específico pela Internet. Uma mensagem SOAP é um documento XML regular. Padrão

Parte lírica.

Imagine que você implementou ou está sendo implementado um determinado sistema que deve ser acessível de fora. Aqueles. existe um determinado servidor com o qual você precisa se comunicar. Por exemplo, um servidor web.

Este servidor pode realizar várias ações, trabalhar com o banco de dados, realizar algumas solicitações de terceiros para outros servidores, realizar algum tipo de cálculos, etc. viver e possivelmente desenvolver de acordo com seu cenário bem conhecido (ou seja, de acordo com o cenário dos desenvolvedores). Uma pessoa não está interessada em se comunicar com esse servidor, porque ela pode não ser capaz / querer fornecer belas páginas com fotos e outros conteúdos amigáveis. Está escrito e funciona de forma a trabalhar e emitir dados para pedidos a ele, sem se preocupar que sejam legíveis por humanos, o próprio cliente tratará deles.

Outros sistemas, referindo-se a este servidor, já podem dispor dos dados recebidos deste servidor a seu próprio critério - para processar, acumular, emitir para seus clientes, etc.

Bem, uma das opções para se comunicar com esses servidores é o SOAP. Protocolo de mensagens xml SOAP.

A parte prática.

Um serviço web (é o que o servidor fornece e o que os clientes utilizam) permite a comunicação com o servidor em mensagens claramente estruturadas. O fato é que o serviço web não aceita nenhum dado. Qualquer mensagem que não cumpra as regras será respondida pelo serviço web com erro. O erro estará, aliás, também na forma de xml com uma estrutura clara (o que não é verdade sobre o texto da mensagem).

WSDL (Web Services Description Language). As regras pelas quais as mensagens para o serviço da web são compiladas são descritas da mesma maneira com usando xml e também ter uma estrutura clara. Aqueles. se um serviço da web fornece a capacidade de chamar um método, ele deve permitir que os clientes saibam quais parâmetros são usados ​​para esse método. Se o serviço da web espera uma string para o método Method1 como um parâmetro e a string deve ser nomeada Param1, então essas regras serão especificadas na descrição do serviço da web.

Como parâmetros, não apenas tipos simples podem ser passados, mas também objetos, coleções de objetos. A descrição do objeto é reduzida à descrição de cada componente do objeto. Se um objeto consiste em vários campos, então cada campo é descrito que tipo, nome (quais valores possíveis). Os campos também podem ser de um tipo complexo, e assim por diante até que a descrição dos tipos termine em simples - string, booleano, número, data ... No entanto, alguns tipos específicos podem ser simples, é importante que os clientes possam entender quais valores podem estar contidos neles.

Para os clientes, basta saber a url do serviço web, estará sempre wsdl, através do qual poderá ter uma ideia dos métodos e dos seus parâmetros que este serviço web disponibiliza.

Quais são as vantagens de todos esses sinos e assobios:

  • Na maioria dos sistemas, a descrição de métodos e tipos ocorre em modo automático... Aqueles. basta que o programador do servidor diga que este método pode ser chamado por meio de um serviço da web e a descrição wsdl será gerada automaticamente.
  • Uma descrição bem estruturada pode ser lida por qualquer cliente de sabão. Aqueles. qualquer que seja o serviço da web, o cliente entenderá quais dados o serviço da web está aceitando. De acordo com essa descrição, o cliente pode construir sua própria estrutura interna de classes de objetos, as chamadas. binding "e. Como resultado, o programador que usa o serviço da web precisa escrever algo como (pseudocódigo):

    NewUser: = TSoapUser.Create ("Vasya", "Pupkin", "odmin"); soap.AddUser (NewUser);

  • Validação automática.

    • validação xml. xml deve ser bem formado. xml inválido - imediatamente um erro para o cliente, deixe-o descobrir.
    • validação de esquema. xml deve ter uma estrutura específica. xml não corresponde ao esquema - imediatamente um erro para o cliente, deixe-o entender.
    • a validação de dados é realizada pelo servidor soap para que os tipos de dados e as restrições correspondam à descrição.
  • Autorização e autenticação podem ser implementadas método separado... nativamente. ou usando autorização http.
  • Os serviços da Web podem funcionar tanto no protocolo soap quanto no http, ou seja, por meio de solicitações get. Ou seja, se os parâmetros são dados simples (sem estrutura), você pode simplesmente chamar o habitual get www.site.com/users.asmx/GetUser?Name=Vasia ou post. No entanto, isso não está em todos os lugares e nem sempre.
  • ... veja wikipedia

Também há muitos contras:

  • Tamanho de mensagem excessivamente grande. Bem, aqui a própria natureza do xml é tal que o formato é redundante, quanto mais tags, mais informações inúteis. Além disso, o sabão adiciona sua própria redundância. Para sistemas de intranet, o problema de tráfego é menos grave do que para a internet, então sabonete para redes locais mais procurado, em particular, o Sharepoint tem um serviço da web de sabão com o qual você pode se comunicar com sucesso (e com algumas restrições).
  • Alterar automaticamente a descrição de um serviço da web pode quebrar todos os clientes. Bem, é como em qualquer sistema, se a compatibilidade com métodos antigos não for suportada, tudo cairá ...
  • Não um sinal de menos, mas uma desvantagem. Todas as ações para chamar métodos devem ser atômicas. Por exemplo, trabalhando com uma subdivisão, podemos iniciar uma transação, executar várias solicitações e, em seguida, fazer rollback ou commit. Não há transações em sabão. Um pedido, uma resposta, a conversa acabou.
  • Pode ser muito difícil entender a descrição do que está no lado do servidor (tudo foi descrito corretamente por mim?), O que está no cliente (o que foi escrito para mim aqui?). Houve várias vezes em que tive que lidar com o lado do cliente e convencer o programador do servidor de que seus dados estavam descritos incorretamente, e ele não conseguia entender nada, porque a geração automática e ele, por assim dizer, não deveria, isso é uma empresa de software. E o erro estava naturalmente no código do método, o programador simplesmente não percebeu.
  • A prática mostra que os desenvolvedores de serviços da web estão terrivelmente distantes das pessoas que usam esses serviços da web. Em resposta a qualquer solicitação (válida de fora), pode ocorrer um erro ininteligível "Erro 5. Tudo está ruim". Tudo depende da consciência dos desenvolvedores :)
  • Provavelmente ainda não me lembrei de algo ...

Como exemplo, temos o serviço open web belavia:

  • http://86.57.245.235/TimeTable/Service.asmx - ponto de entrada, há também uma descrição de texto dos métodos para desenvolvedores de terceiros.
  • http://86.57.245.235/TimeTable/Service.asmx?WSDL - descrição wsdl de métodos e tipos de dados recebidos e retornados.
  • http://86.57.245.235/TimeTable/Service.asmx?op=GetAirportsList - uma descrição de um método específico com um exemplo de uma solicitação xml e uma resposta xml.

Você pode criar e enviar manualmente uma solicitação como:

POST /TimeTable/Service.asmx HTTP / 1.1 Host: 86.57.245.235 Tipo de conteúdo: text / xml; charset = utf-8 Content-Length: length SOAPAction: "http://webservices.belavia.by/GetAirportsList" ru

a resposta virá:

HTTP / 1.1 200 OK Data: Seg, 30 de setembro de 2013 00:06:44 GMT Servidor: Microsoft-IIS / 6.0 X-Powered-By: ASP.NET X-AspNet-Versão: 4.0.30319 Cache-Control: privado, máx -age = 0 Tipo de conteúdo: text / xml; charset = utf-8 Content-Length: 2940

Shl Anteriormente, o serviço da Web Aeroflot foi aberto, mas depois que 1C adicionou suporte a sabão para 8k, um grupo de testadores beta 1c o desativou com sucesso. Agora algo mudou lá (não sei os endereços, você pode pesquisar se estiver interessado).
Isenção de responsabilidade ZZY. Ele me disse em nível doméstico. Você pode chutar.

Isenção de responsabilidade:Muitos artigos sobre esse assunto foram escritos e, como você, é claro, já adivinhou, este é o próximo. Talvez você aprenda algo novo com ele, mas nada supersecreto que você não possa pesquisar no Google não está descrito aqui. Apenas notas de experiência pessoal.

Introdução

Só consideraremos a situação quando houver um serviço web de terceiros e a tarefa for estabelecer a troca de dados.

A estrutura do serviço é descrita no arquivo WSDL(Idioma de descrição de serviços da Web em inglês)

O arquivo geralmente está disponível no link em que o ponto de entrada para o serviço da web está localizado. Escrevi "na maioria das vezes", pois há exceções. Por exemplo, um serviço da web baseado em SAP não publica o wsdl e só pode ser obtido descarregando-o do próprio aplicativo.

E assim, temos uma descrição do serviço web, login, senha. Vamos nos conectar.

// Defina as configurações de URLServiceNameSpace = "http://Somesite.ru"; UserName = "TestUser"; Senha = "q1w2e3"; LocationWSDL = "https://Somesite.ru/WebService/Some?wsdl"; ServiceName = "SomeServiceName"; ConnectionPointName = "SomeService_Port"; // Criar conexão SSL = Novo SecureConnection OpenSSL (); WSDefinition = Novo WSDefinition (LocationWSDL, SSL); WSProxy = Novo WSProxy (WSDefinition, ServiceNameSpace URL, ServiceName, ConnectionPointName, SSL); WSProxy.User = UserName; WSProxy.Password = Senha;

Multar! Conectamos ao serviço da web! Em tese, essa é a base de qualquer opção de troca, já que permite criar objeto de estrutura de dados baseado em wsdl, e trabalhar com tal objeto é um prazer.

Considere o XML que o SoapUI nos oferece

357 121212 M 19900111 Mercedes GLS Audi TT

Agora vamos descrevê-lo programaticamente

// Cria um objeto e preenche-o com os dados XDTOFactory = WSDefinition.XDTOFactory; RootType = CustomXDTO.Type (ServiceNameSpace URL, "SUBMISSION"); RootObject = MyXDTOFactory.Create (RootType); RootObject.ID = "4356"; ClientType = CustomXDTO.Type (ServiceNameSpace URL, "CUSTOMER"); ClientObject = OwnXDTOFactory.Create (ClientType); ClientObject.CLIENT_ID = "121212"; ClientObject.SEX = "M"; // F - feminino, M - masculino ClientObject.CLIENT_BIRTHDAY = "19900111"; // Carros do cliente AutoType = OwnFactoryXDTO.Type (URLServiceNameSpace, "CARS"); AutoObject = OwnXDTOFactory.Create (AutoType); AutoObject.CLASS = "Mercedes"; AutoObject.MODEL = "GLS"; ClientObject.CARS.Add (AutoObject); AutoObject = OwnXDTOFactory.Create (AutoType); AutoObject.CLASS = "Audi"; AutoObject.MODEL = "TT"; ClientObject.CARS.Add (AutoObject); RootObject.CUSTOMER.Add (ClientObject);

Os dados foram preenchidos com sucesso. Agora você precisa enviá-los.

Neste exato momento, muitas nuances surgem. Vamos tentar considerar cada um.

Receita 1. Enviando todo o objeto XDTO

Resultado = WSProxy.AddCustomers (RootObject);

Resta apenas processar o resultado que o serviço nos devolveu e é isso. Concorde que isso é muito conveniente!

Mas, na prática, nem sempre é esse o caso. Por exemplo, 1c não se dá bem com a prefixação de certas tags dentro de xml quando o namespace da tag raiz é diferente daquele dos filhos. Nesses casos, você deve coletar o sabonete manualmente. Também tive que lidar com serviços da web que esperam por xml puro como parâmetro. Insanidade, mas ainda assim não é muito difícil.

Receita 2. Envio de xml limpo como parâmetro

XMLWriteParameters = New XMLWriterParameters ("UTF-8", "1.0", True); MyXML = Novo registro XML; MyXML.SetString (Opções XMLWriter); MyXML.WriteXMLDeclaration (); MyXDTOFactory.WriteXML (MyXML, RootObject); String XML = MyXML.Close (); If DeleteNamespaceDescription Then Attempt FirstTagVSRow = StrGetString (XMLString, 2); RootTagName = RootObject.Type (). Name; XMLString = StringReplace (XMLString, string FirstTagVS, "<"+ИмяКорневогоТэга+">"); Exceção // DescriptionErrors () EndExperimente; EndIf; Result = WSProxy.AddCustomers (XML String);

Se você não remover o namespace que 1c adiciona por padrão, ele se tornou mais de 5 linhas de código. Na maioria das vezes, envolvo a conversão xml em uma função, já que normalmente chamo mais de um método.

Receita 3. Enviando uma solicitação HTTP nativa.

StringSOAP = " | | | "+ String XML +" | |"; // Descreva os cabeçalhos da solicitação HTTP Headers = New Match; Headers.Insert (" Content-Type "," text / xml; charset = UTF-8 "); Headers.Insert (" SOAPAction "," http: // sap.com/xi/WebService/soap1.1 "); Headers.Insert (" Authorization "," Basic "+ GetBase64AuthorizationHeader (Username, Password)); // ATENÇÃO !!! // Não é possível preencher programaticamente o seguintes cabeçalhos, porque isso leva a um erro // A plataforma os preencherá corretamente // Cabeçalhos. ЧГ = ")); // comprimento da mensagem // Cabeçalhos. Insert (" Host "," Somesite.ru:8001 ") ; // Headers. Insert ("Connection", "Keep-Alive"); // Headers. Insert ("User-Agent", "Apache-HttpClient / 4.1.1 (java 1.5)"); // Conecte-se ao site. Connection = New HTTPConnection ("Somesite.ru/WebService/Some", Username, Password, SSL, False); // O endereço deve estar sem https: // // Obtenha o texto da página raiz por meio de uma solicitação POST . Solicitação HTTP c = Novo HTTPRequest ("/ GetCustomer", cabeçalhos); HTTPRequest.SetBodyFromString (StringSOAP); Result = Connection.CallHTTPMethod ("POST", HTTPRequest);

Nesse caso, teremos que coletar o sabonete manualmente. Na verdade, apenas envolvemos o xml da receita 2 em um sabonete, onde, dependendo dos requisitos do serviço web, podemos trocar o nosso sabonete como quisermos.

A seguir, descrevemos os cabeçalhos de acordo com a documentação. Alguns serviços irão mastigar calmamente nosso pedido sem cabeçalhos, aqui você precisa olhar para um caso específico. Se você não souber quais cabeçalhos escrever, a maneira mais fácil é espionar a solicitação no SoapUI, alternando para a guia RAW.

A função para obter a string Base64 se parece com esta (espionada):

Função GetBase64AuthorizationHeader (UserName, Password) FileCoding = TextCode.UTF8; TemporaryFile = GetTemporaryFileName (); Registro = Novo Registro de Texto (TemporaryFile, FileCode); Record.Record (nome de usuário + ":" + senha); Record.Close (); DWData = Novo BinaryData (TemporaryFile); Resultado = Base64String (DWData); DeleteFiles (TemporaryFile); Resultado = Avg (Resultado, 5); Resultado do reembolso; EndFunction

Existe um ponto importante. Ao trabalhar com HTTPConnection, especifique o endereço sem especificar os protocolos "http: //" e "https: //", caso contrário, você corre o risco de perder tempo procurando um erro óbvio.

Receita 4. Envio via WinHttpRequest

WinHttp = Novo COMObject ("WinHttp.WinHttpRequest.5.1"); WinHttp.Option (2, "UTF-8"); WinHttp.Option (4, 13056); // intSslErrorIgnoreFlag WinHttp.Option (6, true); // blnEnableRedirects WinHttp.Option (12, true); // blnEnableHttpsToHttpRedirects WinHttp.Open ("POST", "https://Somesite.ru/WebService/Some/GetCustomer", 0); WinHttp.SetRequestHeader ("Content-type", "text / xml"); WinHttp.SetCredentials (UserName, Password, 0); WinHttp.Send (String SOAP); WinHttp.WaitForResponse (15); XMLResponse = WinHttp.ResponseText ();

Aqui, em essência, o mesmo que na versão anterior, mas trabalhamos com um objeto COM. Indicamos a string de conexão completa, junto com o protocolo. Atenção especial deve ser dada apenas para ignorar sinalizadores de erro de certificado SSL. Eles são necessários se trabalharmos em SSL, mas sem um certificado específico, já que não é possível criar uma nova conexão segura nesta opção (ou não sei como). O resto do mecanismo é semelhante ao anterior.

Além disso, além de "WinHttp.WinHttpRequest.5.1", você pode usar "Microsoft.XMLHTTP", "Msxml2.XMLHTTP", "Msxml2.XMLHTTP.3.0", "Msxml2.XMLHTTP.6.0", se de repente não funcionar desligado em WinHttp. Os métodos são quase os mesmos, apenas o número de parâmetros é diferente. Suspeito que uma dessas opções está codificada dentro do objeto 1c HTTPRequest.

No momento, essas são todas as receitas que tenho. Se encontrar novos, com certeza complementarei o artigo.

Processando o resultado

Na receita 1, geralmente pegamos um objeto XDTO pronto e trabalhamos com ele como uma estrutura. Em todos os outros casos, você pode converter a resposta xml em um XDTO

If Result.StatusCode = 200 Then XMLReader = Novo XMLReader; ReadXML.SetString (Result.GetBodyAsString ()); ObjectResponse = OwnXDTOFactory.ReadXML (ReadXML); Relatório (ObjectResponse.Body.Response.RESPONSE_ID); Relatório (ObjectResponse.Body.Response.RESPONSE_TEXT); Fim se;

Tudo é simples aqui.

Em vez de uma conclusão

1. Comece a trabalhar com serviços da web com o programa SoapUI. Ele foi projetado para esse tipo de trabalho e permitirá que você entenda rapidamente como um serviço específico funciona. Existe um artigo para dominar

2. Se você trocar com o serviço por meio de um canal http desprotegido e surgir a pergunta sobre o que exatamente 1c envia em suas mensagens, você pode usar rastreadores de tráfego, como Wireshark, Fiddler e outros. O problema só surgirá se você estiver usando uma conexão SSL.

3. Se, no entanto, o serviço web se comunica via https, então colocamos na máquina remota (qualquer, o principal não é por nossa conta) o servidor Nginx, com o qual entraremos em contato, e ele, por sua vez, embalará tudo em https e envie quando necessário ( proxy reverso ) e adicione à configuração padrão:

Servidor (ouvir 0.0.0.0:8080; server_name MyServer; localização ~. * (Proxy_pass https://Somesite.ru:8001; proxy_set_header Host $ host; proxy_set_header Autorização "Básico "; autorização proxy_pass_header;))

5. Se a autenticação envolver o uso de cookies, foi encontrado o seguinte

P.S. Se você tem dúvidas, sugestões para melhorar o código, tem receitas próprias diferentes das descritas, encontrou erros ou acha que o autor é "nippy" e ele "não tem lugar no 1c", então escreva comentários e nós faremos discuta tudo.

O título do tópico é realmente uma questão, uma vez que Eu mesmo não sei o que é e pela primeira vez tentarei trabalhar com ele no âmbito deste artigo. A única coisa que posso garantir é que o código abaixo funcionará, mas minhas frases serão apenas suposições e palpites sobre como eu mesmo entendo tudo isso. Então vamos ...

Introdução

Precisamos começar com o que o conceito de serviços da web foi criado. Na época em que surgiu esse conceito, já existiam no mundo tecnologias que permitiam que os aplicativos interajam à distância, onde um programa poderia chamar algum método em outro programa, que ao mesmo tempo poderia ser lançado em um computador localizado em outra cidade ou mesmo um país. Tudo isso é abreviado como RPC (Remote Procedure Calling). Os exemplos incluem tecnologias CORBA e para Java - RMI (Remote Method Invoking). E tudo parece estar bem neles, principalmente no CORBA, tk. você pode trabalhar com ele em qualquer linguagem de programação, mas ainda faltava algo. Acredito que a desvantagem do CORBA é que ele funciona por meio de alguns dos seus próprios protocolos de rede em vez de HTTP simples, que se arrastará por qualquer firewall. A ideia por trás do serviço da web era criar um RPC que ficaria em pacotes HTTP. Foi assim que o desenvolvimento do padrão começou. Quais são os conceitos básicos deste padrão:
  1. SABÃO... Antes de chamar um procedimento remoto, você precisa descrever esta chamada em Arquivo XML e formato SOAP. SOAP é simplesmente uma das muitas marcações XML usadas em serviços da web. Tudo o que queremos enviar a algum lugar via HTTP é primeiro transformado em uma descrição XML SOAP, depois é colocado em um pacote HTTP e enviado a outro computador na rede via TCP / IP.
  2. WSDL... Existe um serviço da web, ou seja, um programa cujos métodos podem ser chamados remotamente. Mas o padrão requer que uma descrição seja anexada a este programa, que diz que "sim, você não está enganado - este é realmente um serviço da web e você pode chamar tais e tais métodos a partir dele." Esta descrição é representada por outro arquivo XML que possui um formato diferente, a saber, WSDL. Aqueles. WSDL é apenas um arquivo de descrição XML para um serviço da web e nada mais.
Por que você pergunta tão brevemente? Você não pode obter mais detalhes? Provavelmente você pode, mas para isso você precisa recorrer a livros como Mashnin T. "Java Web Services". Lá vai pelas primeiras 200 páginas descrição detalhada cada tag dos padrões SOAP e WSDL. Devo fazer isso? Na minha opinião, não, tk. tudo isso é gerado automaticamente em Java e tudo o que você precisa fazer é escrever o conteúdo dos métodos que devem ser chamados remotamente. Portanto, em Java existia uma API como JAX-RPC. Se alguém não sabe, quando diz que o Java possui tal e tal API, significa que existe um pacote com um conjunto de classes que encapsulam a tecnologia em questão. JAX-RPC evoluiu de versão para versão por um longo tempo e eventualmente evoluiu para JAX-WS. WS obviamente significa WebService e você pode pensar que esta é uma simples renomeação de RPC em uma palavra popular nos dias de hoje. Este não é o caso, uma vez que Agora, os serviços da web se distanciaram da ideia original e permitem não apenas chamar métodos remotos, mas também simplesmente enviar mensagens de documentos no formato SOAP. Por que isso é necessário, eu não sei ainda, a resposta provavelmente não será "apenas no caso, de repente será necessário." Eu mesmo gostaria de aprender com camaradas mais experientes. E por último, havia também JAX-RS para os chamados serviços da web RESTful, mas este é um tópico para um artigo separado. Neste ponto, a introdução pode ser encerrada, pois a seguir, aprenderemos a trabalhar com JAX-WS.

Abordagem geral

Os serviços da Web sempre têm um cliente e um servidor. O servidor é nosso serviço da web e às vezes é chamado de endpoint (como o endpoint para onde vão as mensagens SOAP do cliente). Precisamos fazer o seguinte:
  1. Descreva a interface do nosso serviço web
  2. Implementar esta interface
  3. Comece nosso serviço web
  4. Escreva um cliente e chame o método de serviço da web necessário remotamente
O serviço da web pode ser iniciado jeitos diferentes: declare uma classe com um método principal e execute o serviço da web diretamente como um servidor, ou implante-o em um servidor como o Tomcat ou qualquer outro. No segundo caso, nós mesmos não corremos novo servidor e não abra outra porta no computador, mas simplesmente diga ao contêiner de servlet Tomcat que "escrevemos as classes de serviço da web aqui, publique-as, por favor, para que todos que entrarem em contato com você possam usar nosso serviço da web." Independentemente do método de lançamento do serviço web, teremos o mesmo cliente.

Servidor

Vamos começar o IDEA e criar novo projeto Criar Novo Projeto... Vamos inserir um nome HelloWebService e aperte o botão Próximo, então o botão Terminar... Na pasta src criar um pacote ru.javarush.ws... Neste pacote, criaremos a interface HelloWebService: package ru. Javarush. ws; // são anotações, ou seja, uma forma de marcar nossas classes e métodos, // conforme relacionado à tecnologia de serviço da web import javax. jws. WebMethod; import javax. jws. Serviço de internet; import javax. jws. sabão. SOAPBinding; // dizemos que nossa interface funcionará como um serviço da web@Serviço de internet // diga que o serviço da web será usado para chamar métodos@SOAPBinding (style = SOAPBinding. Style. RPC) interface pública HelloWebService ( // dizemos que este método pode ser chamado remotamente@WebMethod public String getHelloString (String name); ) Neste código, as classes WebService e WebMethod são chamadas de anotações e não fazem nada além de marcar nossa interface e seu método como um serviço da web. O mesmo é verdadeiro para a classe SOAPBinding. A única diferença é que SOAPBinding é uma anotação de parâmetro. V nesse caso o parâmetro style é usado com um valor que diz que o serviço da web não funcionará por meio de mensagens de documento, mas como um RPC clássico, ou seja, para chamar o método. Vamos implementar a lógica de nossa interface e criar uma classe HelloWebServiceImpl em nosso pacote. A propósito, observo que o final da aula em Impl é uma convenção em Java, segundo a qual a implementação de interfaces é denotada desta forma (Impl - da palavra implementação, ou seja, implementação). Este não é um requisito e você é livre para nomear a classe como quiser, mas as regras de boa forma exigem isso: pacote ru. Javarush. ws; // a mesma anotação usada para descrever a interface, import javax. jws. Serviço de internet; // mas usado aqui com o parâmetro endpointInterface, // especificando o nome de classe totalmente qualificado da interface de nosso serviço da web@WebService (endpointInterface = "ru.javarush.ws.HelloWebService") public class HelloWebServiceImpl implementa HelloWebService (@Override public String getHelloString (String name) ( // apenas retorne uma saudação return "Hello," + name + "!" ; )) Vamos começar nosso serviço web como um servidor independente, ou seja, sem o envolvimento de qualquer Tomcat e servidores de aplicativos (este é um tópico para uma discussão separada). Para fazer isso, na estrutura do projeto na pasta src vamos criar um pacote ru.javarush.endpoint, e nele criar uma classe HelloWebServicePublisher com um método principal: pacote ru. Javarush. ponto final; // classe para iniciar um servidor web com serviços web import javax. xml. ws. Ponto final; // classe do nosso serviço web import ru. Javarush. ws. HelloWebServiceImpl; public class HelloWebServicePublisher (public static void main (String ... args) ( // inicia o servidor web na porta 1986 // e no endereço especificado no primeiro argumento, // inicia o serviço da web passado no segundo argumento Ponto final. publicar ( "http: // localhost: 1986 / wss / hello", novo HelloWebServiceImpl ()); )) Agora vamos executar esta aula clicando em Shift + F10... Nada aparece no console, mas o servidor está em execução. Você pode verificar isso digitando no navegador a linha http: // localhost: 1986 / wss / hello? Wsdl. A página que se abre, por um lado, prova que um servidor web (http: //) foi iniciado em nosso computador (localhost) na porta 1986 e, por outro lado, mostra a descrição WSDL de nosso serviço web. Se você interromper o aplicativo, a descrição ficará inacessível, assim como o próprio serviço da web, portanto, não faremos isso, mas seguiremos escrevendo para o cliente.

Cliente

Na pasta do projeto src crie um pacote ru.javarush.client, e nele a classe HelloWebServiceClient com o método principal: pacote ru. Javarush. cliente; // necessário obter a descrição wsdl e por meio dela // alcance o próprio serviço da web import java. líquido. URL; // tal execução ocorrerá ao trabalhar com um objeto URL import java. líquido. MalformedURLException; // classes para analisar xml-ku com descrição wsdl // e alcançar a etiqueta de serviço nele import javax. xml. namespace. QName; import javax. xml. ws. Serviço; // a interface do nosso serviço web (precisamos de mais) import ru. Javarush. ws. HelloWebService; public class HelloWebServiceClient (public static void main (String args) lança MalformedURLException ( // cria um link para a descrição wsdl Url url= novo URL ( "http: // localhost: 1986 / wss / hello? wsdl") ; // Vemos os parâmetros do próximo construtor na primeira tag da descrição WSDL - definições // veja o primeiro argumento no atributo targetNamespace // veja o segundo argumento no atributo name QName qname = new QName ("http: //ws.site/", "HelloWebServiceImplService"); // Agora podemos alcançar a etiqueta de serviço na descrição wsdl, Serviço de serviço= Serviço. criar (url, qname); // e, em seguida, até a tag da porta aninhada, de modo que // obter um link para um objeto de serviço da web remoto de nós HelloWebService hello = service. getPort (HelloWebService. class); // Hooray! Agora você pode chamar o método remoto Sistema. Fora. println (hello. getHelloString ("CodeGym")); )) Dei comentários máximos sobre o código na listagem. Não tenho nada a acrescentar, então execute (Shift + F10). Devemos ver o texto no console: Hello, CodeGym! Se você não viu, provavelmente se esqueceu de iniciar o serviço da web.

Conclusão

Neste tópico, foi apresentada uma breve excursão em serviços da web. Novamente, muito do que escrevi é minha suposição de como funciona e, portanto, não deve ser muito confiável. Eu ficaria muito grato se pessoas conhecedoras eles vão me corrigir, porque então vou aprender alguma coisa. UPD.

Alexey Boyko

Serviços da Web SOAP e XML na plataforma .Net

XML Web Services oferece este nível de compatibilidade e interoperabilidade entre sistemas operacionais,

plataformas e idiomas que anteriormente simplesmente não estavam disponíveis.

Andrew Troelsen (MVP (Profissional Mais Valioso da Microsoft))

Se você ainda não trabalhou com serviços da web em XML, provavelmente já ouviu a palavra “SOAP”. É hora de entender esses conceitos.

Introdução

Se você estiver interessado na Internet ou em redes menores, é provável que mais cedo ou mais tarde se depare com XML Web Services. Um serviço da web em XML não é apenas um aplicativo da web que pode enviar informações para um navegador. Em vez disso, é uma tecnologia remota que permite que métodos e propriedades de um objeto na rede sejam invocados usando solicitações HTTP padrão.

Na prática, isso significa que os clientes desse serviço podem ser escritos em diferentes idiomas e para diferentes sistemas operacionais.

Como um "transporte" de informação entre o serviço e o cliente, pode-se utilizar os métodos HTTP GET ou POST.

E você pode "sobrepor" mais um protocolo - SOAP (Simple Object Access Protocol). Isso geralmente é feito, pois neste caso é possível passar tipos complexos (incluindo aqueles definidos pelo usuário). E os métodos clássicos GET e POST suportam apenas listas, arrays simples e strings.

Exemplo de interoperabilidade SOAP

Uma mensagem SOAP é um documento XML empacotado no corpo de uma solicitação HTTP.

Listagem 1. Estrutura de uma mensagem SOAP

A interação entre o cliente e o serviço é a seguinte:

  • o cliente faz uma solicitação SOAP e a envia ao serviço;
  • serviço em computador remoto executa o procedimento e envia uma resposta SOAP.

Por exemplo, uma solicitação SOAP pode ter a seguinte aparência, chamando o método HelloWorld () de um serviço da web XML remoto:

Listagem 2. Um exemplo de solicitação SOAP

O método HelloWorld (), conforme esperado, retorna a string "Olá, mundo!":

Listagem 3. Amostra de resposta SOAP

Xmlns: xsi = "http://www.w3.org/2001/XMLSchema-instance" xmlns: xsd = "http://www.w3.org/2001/XMLSchema">

Olá Mundo!

Criando um XML Web Service em .NET 2.0

Você pode criar um serviço jeitos diferentes, usaremos o Visual Studio 2005. Clique em "Arquivo -> Novo -> Site", na janela aberta selecione "Serviço web ASP.NET". No endereço especificado durante a criação, você encontrará os seguintes arquivos e diretórios (ver Fig. 1).

Em princípio, um serviço pode conter apenas um único arquivo com a extensão * .asmx. (A extensão * .asmx é usada para denotar serviços da web .Net.) Nesse caso, não é o caso, observe o conteúdo do arquivo Service.asmx:

Listagem 4. Service.asmx define arquivo externo Apoio, suporte

<%@ WebService Language="C#" CodeBehind="~/App_Code/Service.cs" class="Service" %>

O atributo CodeBehind especifica um arquivo externo localizado na pasta App_Code que contém o código que implementa o método HelloWorld ():

Listagem 5. Arquivo Service.cs que implementa o método HelloWorld ()

using System;

usando System.Web;

using System.Web.Services;

Serviço público () (

Retorne "Hello World";

É possível criar um único arquivo Service.asmx, sem código de suporte, que tenha a mesma funcionalidade:

Listagem 6. Service.asmx sem código de suporte externo

<%@ WebService Language="C#" class="Service" %>

using System;

usando System.Web;

using System.Web.Services;

using System.Web.Services.Protocols;

public class Service: System.Web.Services.WebService

Serviço público () (

String pública HelloWorld () (

Retorne "Hello World";

Não precisamos disso e não faremos isso.

Como você pode ver, o único método em nosso serviço da Web é marcado com um atributo que informa ao tempo de execução do ASP.NET que esse método está disponível para solicitações HTTP de entrada. Membros não identificados com este atributo não estarão disponíveis para programas clientes.

Um serviço tão simples é bastante adequado para nossos experimentos, resta apenas publicá-lo.

Publicando XML Web Service usando IIS

Não se trata de publicar na Internet, mas de criar condições para testar o nosso serviço num computador local.

A primeira etapa é instalar o IIS (Internet Information Server). Para fazer isso, abra a janela "Adicionar ou Remover Programas" e selecione "Instalar Componentes do Windows" (Algum Versões Windows não envolva uma instalação do IIS, como o Windows XP Home Edition.)

Observação: Servidor IISé melhor instalar antes do .Net Framework, caso contrário, você terá que configurar o IIS para oferecer suporte a aplicativos .Net executando o utilitário linha de comando aspnet_regiis.exe (com o sinalizador / i).

Crie um diretório virtual. Se você estiver usando o Windows XP Pro, vá para "Painel de Controle -> Ferramentas Administrativas -> Serviços de Informações da Internet". Na janela que é aberta, selecione Ação -> Criar -> Diretório virtual.

O Assistente de novo diretório virtual será iniciado. Alias ​​Soap1 e especifique o caminho para o diretório onde deseja colocar o serviço, por exemplo C: \ Soap1. Agora copie o conteúdo do nosso serviço da web para lá.

Digite http: //localhost/soap1/Service.asmx na barra de endereço do seu navegador e você deverá ver a página de teste do serviço (veja a Figura 2).

Visualizando Mensagens SOAP

A página de teste não permite o envio e a leitura de mensagens SOAP. Por esse motivo, você terá que usar o desenvolvimento de terceiros, recomendo usar o soapUI. (Este é um produto gratuito disponível em http://www.soapui.org.)

Depois de instalar o soapUI, crie um novo projeto chamado soap1, deixando o campo WSDL inicial vazio (consulte a Figura 3).

Clique com o botão direito no projeto recém-criado e selecione "Adicionar WSDL do URL". Na caixa de diálogo que é aberta, digite http: //localhost/soap1/Service.asmx? Wsdl. Agora podemos enviar solicitações SOAP para nosso serviço e visualizar as respostas recebidas. (As solicitações serão geradas pelo soapUI automaticamente.)

O que é esse WSDL? O documento WSDL descreve como os clientes interagem com um serviço da web. Ele descreve quais métodos de serviço estão disponíveis para chamada externa, quais parâmetros eles aceitam e o que eles retornam, bem como outras informações necessárias para comunicação remota. Tal documento pode ser compilado manualmente, ou pode-se confiar sua geração ao servidor, para isso basta adicionar o sufixo? Wsdl à URL que aponta para o arquivo * .asmx.

Para visualizar o documento WSDL de nosso serviço, digite http: //localhost/soap1/Service.asmx? Wsdl em seu navegador. As informações deste documento são usadas por soapUI para gerar solicitações SOAP automaticamente.

Extensões SOAP

Como você deve ter notado, a criação de um serviço da web em XML (bem como de um cliente) não precisa se preocupar com a aparência das mensagens SOAP. Basta marcar os métodos requeridos com um atributo, e o tempo de execução do ASP.NET gera pacotes no formato requerido.

Na fig. 4 mostra a solicitação e a resposta do serviço da web recebido usando o programa soapUI.

Vamos fazer mais uma vez. A solicitação é gerada por soapUI - ao criar clientes reais para o serviço, você também não precisa formatar manualmente os pacotes SOAP. Também não participamos diretamente na criação da resposta de serviço. Tudo isso acontece automaticamente.

No entanto, é provável que você mesmo precise modificar esses pacotes. Por exemplo, comprima ou criptografe os dados transmitidos. Este é o propósito das extensões SOAP.

Extensões SOAP é um mecanismo que permite modificar arbitrariamente as mensagens SOAP enviadas e recebidas.

"Caminho" da mensagem SOAP

Para começar a programar, você precisa considerar o caminho que uma mensagem SOAP percorre antes de ser recebida e processada pelo método apropriado (consulte a Figura 5).

Uma mensagem SOAP pode ser considerada um documento XML que descreve um objeto transmitido por uma rede. Antes de usar o objeto passado desta forma, ele deve ser restaurado (ou, se preferir, montado) a partir desta descrição. O serializador XML serve a esse propósito.

Os pacotes de entrada são desserializados (restaurando um objeto de uma descrição XML) e os enviados são serializados (criando uma descrição XML de um objeto).

Na fig. 5 mostra quatro pontos (BeforeSerialize, AfterDeserialize, BeforeDeserialize, AfterSerialize) nos quais podemos interceptar uma mensagem SOAP usando extensões SOAP. Modifique-o e envie-o posteriormente.

Implementação de extensão SOAP

Para começar, vamos definir uma tarefa: digamos que queremos modificar os pacotes SOAP enviados pelo serviço da web, conforme mostrado na Listagem 7:

Listagem 7. Respostas de serviço da web em XML antigo e novo

Xmlns: xsi = "http://www.w3.org/2001/XMLSchema-instance" xmlns: xsd = "http://www.w3.org/2001/XMLSchema">

Olá Mundo

Xmlns: xsi = "http://www.w3.org/2001/XMLSchema-instance" xmlns: xsd = "http://www.w3.org/2001/XMLSchema">

Texto cifrado

Plano de ação para implementação de extensão SOAP:

  • Crie uma dll com uma classe herdada de SoapExtension.
  • Adicione a pasta bin ao nosso serviço web e coloque a dll criada lá.
  • Adicione o arquivo web.config ao serviço e faça as alterações necessárias nele.

Discutiremos a função da pasta bin e do arquivo web.config posteriormente.

Criação de DLL com extensão SOAP

Crie um novo projeto de "Biblioteca de Classes" chamado SoapExtensionLib. Neste projeto, precisamos apenas implementar uma classe que fará as modificações necessárias nos pacotes SOAP. Esta classe deve ser herdada da classe SoapExtension.

Listagem 8. Criando uma classe herdada de SoapExtension

using System;

using System.Web.Services;

using System.Web.Services.Protocols;

using System.IO;

usando System.Net;

using System.Xml;

Cada extensão SOAP recebe como parâmetro um stream contendo o objeto a ser passado pela rede (antes ou depois da serialização). E deve retornar um fluxo.

A extensão SOAP pode ser considerada uma "caixa" que pode ser colocada em um ou todos os quatro pontos (BeforeSerialize, AfterDeserialize, BeforeDeserialize, AfterSerialize) mostrados na Fig. 5. Em cada ponto, pode haver qualquer número dessas "inserções" (ver Fig. 6).

O método ChainStream é usado para receber esses fluxos.

Listagem 9. Implementando o método ChainStream

classe pública TraceExtension: SoapExtension

Stream wireStream;

Stream appStream;

// método como um parâmetro de entrada

// obtém um fluxo contendo o objeto passado

Modificação pública Stream ChainStream (stream stream)

WireStream = stream;

AppStream = novo MemoryStream ();

Return appStream;

Em BeforeDeserialize, o wireStream contém a solicitação SOAP recebida da rede. Esta solicitação SOAP precisa ser passada para o fluxo do aplicativo (appStream).

E no ponto de AfterSerialize, você precisa enviar a resposta SOAP enviada à rede para o wireStream, que será colocado no appStream.

Para trabalhar com threads em cada um dos quatro pontos, você precisa implementar o método ProcessMessage.

Listagem 10. Implementação do método ProcessMessage que não modifica mensagens SOAP

// ProcessMessage fazendo a cópia obrigatória

// transmite em dois pontos (BeforeDeserialize e AfterSerialize)

Mudar (mensagem.Estágio)

// no ponto BeforeDeserialize você deve passar

// Solicitação SOAP do stream de rede (wireStream)

// para o fluxo do aplicativo (appStream)

Case SoapMessageStage.BeforeDeserialize:

Copiar (wireStream, appStream);

AppStream.Position = 0;

Pausa;

// no ponto AfterSerialize deve ser passado

// Resposta SOAP do fluxo do aplicativo para o fluxo da rede

AppStream.Position = 0;

Pausa;

void Copy (Stream de, Stream para)

Leitor TextReader = novo StreamReader (de);

Escritor de TextWriter = novo StreamWriter (para);

Writer.WriteLine (reader.ReadToEnd ());

Writer.Flush ();

Pense na Listagem 10 como um espaço em branco para mais experimentação. Essa implementação do método ProcessMessage não faz nenhum sentido - a resposta SOAP de saída não é modificada de nenhuma forma. Vamos consertar isso:

Listagem 11. Implementando o Método ProcessMessage para Modificar a Resposta SOAP

public override void ProcessMessage (mensagem SoapMessage)

Mudar (mensagem.Estágio)

Case SoapMessageStage.AfterSerialize:

WriteOutput (mensagem);

Pausa;

// parte do código foi cortado para economizar espaço

// reescrever a resposta SOAP

public void WriteOutput (mensagem SoapMessage)

AppStream.Position = 0;

// cria um documento XML a partir do fluxo

Documento XmlDocument = novo XmlDocument ();

Document.Load (appStream);

// Para usar XPath, você precisa definir

// NamespaceManager

XmlNamespaceManager nsmgr = novo XmlNamespaceManager (document.NameTable);

Nsmgr.AddNamespace ("soap", "http://schemas.xmlsoap.org/soap/envelope/");

XmlNode ResultNode = document.SelectSingleNode ("// soap: Body", nsmgr);

// substitui o conteúdo do nó

ResultNode.InnerText = "texto cifrado";

// limpe o fluxo e escreva uma nova resposta SOAP para ele

AppStream.SetLength (0);

AppStream.Position = 0;

Document.Save (appStream);

// AÇÃO OBRIGATÓRIA

// passa a resposta SOAP do fluxo do aplicativo (appStream)

// no fluxo da rede (wireStream)

AppStream.Position = 0;

Copiar (appStream, wireStream);

Em seguida, é necessário definir dois métodos (um dos quais está sobrecarregado, ou seja, pode ser chamado com diferentes conjuntos de parâmetros), que em nosso caso não são necessários. No entanto, devemos defini-los de acordo com as regras de herança da classe SoapExtension.

Listagem 12. Outros métodos exigidos

// De acordo com as regras de herança, devemos

// define esses métodos, mas não os usamos de forma alguma

objeto de substituição pública?

GetInitializer (LogicalMethodInfo methodInfo, atributo SoapExtensionAttribute)

Return null;

objeto de substituição pública GetInitializer (digite WebServiceType)

Return null;

public override void Initialize (inicializador de objeto)

Retornar;

É isso, compilamos o projeto. Finalmente conseguimos uma dll com extensão SOAP. A lista completa de SoapExtensionLib.dll pode ser encontrada no site da revista na seção "Código-fonte".

Configurando um serviço da Web para funcionar com extensão SOAP

Abra nosso projeto de serviço da web em XML novamente com o Visual Studio. Clique em "WebSite -> Adicionar Referência" e selecione o SoapExtensionLib.dll que você criou anteriormente.

A pasta Bin será adicionada automaticamente ao projeto. Os arquivos * .dll localizados na pasta Bin são referenciados automaticamente pelo aplicativo.

Agora coloque o seguinte conteúdo no arquivo Web.Config no diretório do serviço da web:

Listagem 13. O arquivo Web.Config

Prioridade = "1"

Grupo = "0" />

Agora a estrutura do nosso serviço se parece com a mostrada na Fig. 7

Usamos o arquivo Web.Config para informar à estrutura ASP.NET que adicionamos a extensão XML Soap ao serviço da web, que é implementada na classe TraceExtension localizada no arquivo SoapExtensionLi.dll.

Listagem 14. A seção webServices no arquivo Web.Config

Prioridade = "1"

Grupo = "0" />

Como você já sabe, muitas extensões SOAP podem ser feitas, e o fluxo que carrega o objeto passado (antes ou depois da serialização) passará por cada uma delas. A ordem na qual o fluxo flui através das várias extensões SOAP é especificada usando os atributos de prioridade e grupo.

Vale destacar que configurando o Web.Config desta forma, informamos ao ambiente que nossa Extensão SOAP será chamada para cada método do serviço marcado com o atributo. É possível criar seu próprio atributo e marcar com ele apenas os métodos para os quais você precisa chamar a extensão SOAP.

Listagem 15. Um exemplo de uso de um atributo customizado

public string HelloWorld () (

Retorne "Hello World";

Para fazer isso, adicione uma classe herdada de SoapExtensionAttribute a SoapExtensionLi.dll (consulte a Figura 8).

Conclusão

Este artigo reflete os principais pontos da construção e operação de serviços web XML na plataforma .Net. Espero que o material apresentado seja suficiente para que, se necessário, você possa se engajar em um estudo mais aprofundado do tema.


Em contato com