Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TOMEE-2861 Translate to Portuguese: examples/webservice-holder #683

Merged
merged 3 commits into from
Jul 13, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
203 changes: 203 additions & 0 deletions examples/webservice-holder/README_pt.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,203 @@
:index-group: Web Services :jbake-type: page :jbake-status:
status=published = parâmetros @WebService OUT via javax.xml.ws.Holder

Com SOAP é possivel retornar multiplos valores em uma única requisição.
Isto é impossível em Java pois um método pode retornar somente um objeto.

JAX-WS resolve esse problema com o conceito de Holders. Um
`javax.xml.ws.Holder` é um simples wrapper objeto que pode ser passado para
o método `@WebService` como um parâmetro. A aplicação atribui o valor
do mantenedor durante a requisição e o servidor enviará valor de volta
como um parâmetro OUT.

== Usando @WebParam e javax.xml.ws.Holder

A anotação `@WebParam` nos permite declarar os Holders `soma` e `multiplicação`
como parâmetros `WebParam.Mode.OUT`. Como mencionado, esses mantenedores
são simplesmente cestas vázias, a aplicação pode preencher com dados para poder
enviar para o cliente. O servidor irá passar então, em não inicializado.

[source,java]
----
@Stateless
@WebService(
portName = "CalculatorPort",
serviceName = "CalculatorService",
targetNamespace = "http://superbiz.org/wsdl",
endpointInterface = "org.superbiz.ws.out.CalculatorWs")
public class Calculator implements CalculatorWs {

public void sumAndMultiply(int a, int b,
@WebParam(name = "sum", mode = WebParam.Mode.OUT) Holder<Integer> sum,
@WebParam(name = "multiply", mode = WebParam.Mode.OUT) Holder<Integer> multiply) {
sum.value = a + b;
multiply.value = a * b;
}
}
----

Se os Holders foram especificados como parâmetros `WebParam.Mode.INOUT`, então o
cliente consegueria utilizá-los para enviar dados e a aplicação também. A
instância `Holder` seria então inicializada com os dados que da
requisição do cliente. A aplicação poderia verificar os dados antes eventualmente
sobrescrevendo-os com os valores de resposta.

== O WSDL

O componente JAX-WS `@WebService` acima resulta no seguinte WSDL
que será criado automaticamente. Aviso o tipo complexo `sumAndMultiplyResponse`
retorna dois elementos. Estes correspondem as declarações `@WebParam`
e nossos dois parâmetros `Holder<Integer>`.

[source,xml]
----
<?xml version="1.0" encoding="UTF-8"?>
<wsdl:definitions xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
name="CalculatorService"
targetNamespace="http://superbiz.org/wsdl"
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:tns="http://superbiz.org/wsdl"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<wsdl:types>
<xsd:schema attributeFormDefault="unqualified" elementFormDefault="unqualified"
targetNamespace="http://superbiz.org/wsdl"
xmlns:tns="http://superbiz.org/wsdl"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:element name="sumAndMultiply" type="tns:sumAndMultiply"/>
<xsd:complexType name="sumAndMultiply">
<xsd:sequence>
<xsd:element name="arg0" type="xsd:int"/>
<xsd:element name="arg1" type="xsd:int"/>
</xsd:sequence>
</xsd:complexType>
<xsd:element name="sumAndMultiplyResponse" type="tns:sumAndMultiplyResponse"/>
<xsd:complexType name="sumAndMultiplyResponse">
<xsd:sequence>
<xsd:element minOccurs="0" name="sum" type="xsd:int"/>
<xsd:element minOccurs="0" name="multiply" type="xsd:int"/>
</xsd:sequence>
</xsd:complexType>
</xsd:schema>
</wsdl:types>
<wsdl:message name="sumAndMultiplyResponse">
<wsdl:part element="tns:sumAndMultiplyResponse" name="parameters"/>
</wsdl:message>
<wsdl:message name="sumAndMultiply">
<wsdl:part element="tns:sumAndMultiply" name="parameters"/>
</wsdl:message>
<wsdl:portType name="CalculatorWs">
<wsdl:operation name="sumAndMultiply">
<wsdl:input message="tns:sumAndMultiply" name="sumAndMultiply"/>
<wsdl:output message="tns:sumAndMultiplyResponse" name="sumAndMultiplyResponse"/>
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name="CalculatorServiceSoapBinding" type="tns:CalculatorWs">
<soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
<wsdl:operation name="sumAndMultiply">
<soap:operation soapAction="" style="document"/>
<wsdl:input name="sumAndMultiply">
<soap:body use="literal"/>
</wsdl:input>
<wsdl:output name="sumAndMultiplyResponse">
<soap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name="CalculatorService">
<wsdl:port binding="tns:CalculatorServiceSoapBinding" name="CalculatorPort">
<soap:address location="http://127.0.0.1:4204/Calculator?wsdl"/>
</wsdl:port>
</wsdl:service>
</wsdl:definitions>
----

== Testando os parâmetros OUT

Aqui nós vemos um cliente JAX-WS executando a operação `sumAndMultiply`.
Duas instâncias vázias do `Holder` são criadas e passadas como parâmetros.
Os dados da `sumAndMultiplyResponse` são colocados na instância `Holder`
e então ficam disponíveis para o cliente depois da operação completa.

Os mantenedores não são realmente enviados na requisição, a menos que eles
estejam configurados como parâmetros INOUT via WebParam.Mode.INOUT em `@WebParam`

[source,java]
----
import org.junit.BeforeClass;
import org.junit.Test;

import javax.ejb.embeddable.EJBContainer;
import javax.xml.namespace.QName;
import javax.xml.ws.Holder;
import javax.xml.ws.Service;
import java.net.URL;
import java.util.Properties;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;

public class CalculatorTest {

@BeforeClass
public static void setUp() throws Exception {
Properties properties = new Properties();
properties.setProperty("openejb.embedded.remotable", "true");
//properties.setProperty("httpejbd.print", "true");
//properties.setProperty("httpejbd.indent.xml", "true");
EJBContainer.createEJBContainer(properties);
}

@Test
public void outParams() throws Exception {
final Service calculatorService = Service.create(
new URL("http://127.0.0.1:4204/Calculator?wsdl"),
new QName("http://superbiz.org/wsdl", "CalculatorService"));

assertNotNull(calculatorService);

final CalculatorWs calculator = calculatorService.getPort(CalculatorWs.class);

final Holder<Integer> sum = new Holder<Integer>();
final Holder<Integer> multiply = new Holder<Integer>();

calculator.sumAndMultiply(4, 6, sum, multiply);

assertEquals(10, (int) sum.value);
assertEquals(24, (int) multiply.value);
}
}
----

== Analisando as mensagens

A execução acima resulta na seguinte mensagem SOAP.

=== requisição cliente SOAP sumAndMultiply

[source,xml]
----
<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<ns1:sumAndMultiply xmlns:ns1="http://superbiz.org/wsdl">
<arg0>4</arg0>
<arg1>6</arg1>
</ns1:sumAndMultiply>
</soap:Body>
</soap:Envelope>
----

=== resposta do servidor SOAP sumAndMultiplyResponse

[source,xml]
----
<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<ns1:sumAndMultiplyResponse xmlns:ns1="http://superbiz.org/wsdl">
<sum>10</sum>
<multiply>24</multiply>
</ns1:sumAndMultiplyResponse>
</soap:Body>
</soap:Envelope>
----
86 changes: 86 additions & 0 deletions examples/webservice-ws-with-resources-config/README_pt.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
:index-group: Webservice
:jbake-type: page
:jbake-status: published
= Webservice JAX-WS - Configuração de Recursos

TomEE conta com o Apache CXF para JAX-RS (RESTful Services) e JAX-WS (Web Services). Este é um exemplo de como desenvolver EJB webservices graças a implementação CXF.

== openejb-jar.xml Configuração
Você pode usar (http://tomee.apache.org/details-on-openejb-jar.html[openejb-jar.xml]) para configurar seu webservice.

CXF API é reutilizável mas além disso você pode configurar os interceptadores através do `openejb-jar.xml`(localizados na WEB-INF).
Como um rápido lembrete, a configuração no `openejb-jar.xml`, você pode utilizar uma configuração parecida a esta, com o seu próximo EJB:

[source,xml]
----

<openejb-jar xmlns="http://www.openejb.org/openejb-jar/1.1">
<ejb-deployment ejb-name="CalculatorBean"> <!-- configurar os valores do bean, no resources.xml -->
<properties>
cxf.jaxws.in-interceptors = wss4j
</properties>
</ejb-deployment>
</openejb-jar>
----
Para um webservice Pojo é da mesma forma, mas usando o pojo-deployment em vez do ejb-deployment.

Então uma vez que fez sua seleção de prefixo, e conhece onde é para escrever a configuração, basta utilizar as seguintes entradas:

* *properties*: propriedades da fábrica servidora

* *features*: recursos CXF

* *in-interceptors*: interceptadores de entrada do CXF

* *out-interceptors*: interceptadores de saída do CXF

* *in-fault-interceptors*: interceptadores de entrada do CXF para tratamento de erros

* *out-fault-interceptors*: interceptadores de saída do CXF para tratamento de erros

* *databinding*: servidor de vinculação de dados

* *providers (somente para endpoint JAX-RS)*: lista de provedores JAX-RS

* *skip-provider-scanning (somente para JAX-RS)*: utilizar ou não um provedor de varredura (por padrão true)

Para características e interceptadores, a regra é a mesma: lista de valores separados por vírgula. Cada valor da lista, é um nome de classe qualificado ou um id de serviço, é um ou o outro, no resources.xml.

== Exemplo para JAX-WS
Para configurar o WSS4J no EJB `CalculatorBean` para adicionar uma instância no openejb-jar.xml:

[source,xml]
----

<resources>
<!-- os interceptadores -->
<Service id="wss4j1" class-name="org.apache.openejb.server.cxf.config.WSS4JInInterceptorFactory" factory-name="create">
action = UsernameToken
passwordType = PasswordText
passwordCallbackClass = org.superbiz.ws.security.PasswordCallbackHandler
</Service>
</resources>
----
== passwordCallbackClass

`passwordCallbackClass` é uma propriedade do `WSS4JInInterceptorFactory` e seu valor é a classe `PasswordCallbackHandler`.

`PasswordCallbackHandler` utiliza `org.apache.wss4j.common.ext.WSPasswordCallback` para prover senhas no mecanismo de callback.


==== Exemplo

Exemplo completo pode ser encontrado https://github.com/apache/tomee/blob/master/examples/webservice-ws-with-resources-config/src/main/java/org/superbiz/ws/security/PasswordCallbackHandler.java[aqui]:


=== Executando os testes

Exemplo de projeto completo pode ser encontrado https://github.com/apache/tomee/tree/master/examples/webservice-ws-with-resources-config[aqui].
Este é um projeto maven, e todos os testes pode ser executados rodando o comando `mvn clean test`.

mvn clean test

```
[INFO] Resultados:
[INFO]
[INFO] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0