Tutorial de Instalação e Uso do OWLS Composer com

Propaganda
INSTALAÇÃO E USO DO GOOGLE APP ENGINE PLUGIN
utilizando o Eclipse Galileo
Desenvolvido por: Fabrício Alves e Daniela Claro
contato: [email protected], [email protected]
Requisitos de Ambiente:
− Java 1.6 http://java.sun.com/javase/downloads/widget/jdk6.jsp
− Google App engine Plugin http://code.google.com/intl/pt-BR/eclipse/docs/download.html
Sumário:
A partir da versão 1.4.2 do Google App Engine é possível utilizar java.soap.xml e JAX-B
para desenvolver um servidor SOAP. Este tutorial visa construir uma simples aplicação que
recebe como parâmetro uma temperatura medida em Farenheit e devolve se este tempo é
considerado Frio ou Quente.
1. Abra o Wizard de Criação de novo projeto, clicando no botão “Google Service and
Development Tools” que se encontra na Barra de Ferramentas.
Figura 1: Criando um novo Projeto de Aplicação web do
App Engine
Dê ao projeto o nome WeatherSOAPServer e insira o valor com.example no campo Package.
Desmarque a opção “Use Google Web Toolkit”.
Figura 2: Nomeando o Serviço
Perceba que a classe WeatherSOAPServerServlet.java foi criada automaticamente. Esta
classe será importante futuramente, pois gerencia as requisições feitas ao servidor.
2.
Crie dentro do pacote com.example a classe ClimaInfo, clicando com o botão direito sobre
o pacote e escolhendo a opção New > Class.
Figura 3: Criação de Classe
Nós vamos manter esta classe muito simples. Ela terá apenas o método comoEstaOTempo:
package com.example;
public class ClimaInfo {
public String comoEstaOTempo(int temperatura){
if(temperatura > 30){
return "Quente";
}
else if(temperatura < 15){
return "Frio";
}
else{
return "Agradavel";
}
}
}
3.
Adicione as anotações de WebService, presentes no pacote javax.jws.WebMethod. Tais
anotações serão levadas em consideração no momento de criação do WSDL.
package com.example;
import javax.jws.WebMethod;
import javax.jws.WebService;
@WebService
public class ClimaInfo {
@WebMethod
public String comoEstaOTempo(int temperatura){
if(temperatura > 30){
return "Quente";
}
else if(temperatura < 15){
return "Frio";
}
else{
return "Agradavel";
}
}
}
Apesar do Google App Engine não suportar a utilização de JAX-WS no SOAP Server, iremos
utilizá-lo para criar o arquivo wsdl automaticamente.
4.
Vamos utilizar o wsgen, programa contigo no java JDK (à partir da versão 1.6), que gera
wsdl a partir de anotações feitas no código. Além disso, o wsgen gera os POJOS, que são as
classes que serão responsáveis pelo request e response.
Entre na interface de comandos, acesse o diretório do projeto criado
(workspace/WeatherSOAPServer/) e cole o seguinte comando:
wsgen -cp ".\war\WEB-INF\classes" -wsdl -keep -r ".\war" -d ".\war\WEB-INF\classes" -s
".\src" com.example.ClimaInfo
Este comando é explicado da seguinte forma:

A opção -cp indica onde o wsgen irá encontrar o arquivo ClimaInfo.class para gerar o WSDL.

A opção -r indica onde o wsdl será gerado.

A opção -d indica onde serão colocados os arquivos .class gerados.

A opção -s indica onde serão colocados os arquivos fontes dos POJOS gerados.

Por fim, a última opção indica qual será a classe que será transformada em Serviço Web.
Selecione o projeto e pressione a tecla “f5”, para que os arquivos gerados sejam vistos dentro do Eclipse.
5.
Coloque a URL de request do serviço dentro do WSDL. Abra o WSDL gerado, dentro do
diretório war, e veja que o campo location, possui o valor REPLACE_WITH_ACTUAL_URI. Tal
URI é o ponto de acesso para o serviço, ou seja, a URI da sua aplicação no Google App Engine.
Geralmente esta URI é formada por <application-id>.appspot.com .
<service name="ClimaInfoService">
<port name="ClimaInfoPort" binding="tns:ClimaInfoPortBinding">
<soap:address location="http://<application-id>.appspot.com/weathersoapserver"/>
</port>
</service>
6.
Codificar um Adapatador que faça a ligação entre os POJOS gerados e a o verdadeiro
código do Serviço Web. Obs: arquivo fonte presente em
http://homes.dcc.ufba.br/~fabufbc#tutorialOwls
package com.example;
import com.example.jaxws.ComoEstaOTempo;
import com.example.jaxws.ComoEstaOTempoResponse;
public class ClimaInfoAdaptador {
private ClimaInfo climaInfo = new ClimaInfo();
public ComoEstaOTempoResponse comoEstaOTempo(ComoEstaOTempo request){
int temperatura = request.getArg0();
String comoEstaOTempo = climaInfo.comoEstaOTempo(temperatura);
ComoEstaOTempoResponse response = new ComoEstaOTempoResponse();
response.setReturn(comoEstaOTempo);
return response;
}
}
7.
Criar um Gerenciador entre a requisição e o Adaptador. Quando a requisição SOAP é feita
para o servidor, a única coisa que é passada é um XML contendo o “soapBody”. Este soapBody
informa quais os argumentos e seus valores. No entanto, é necessário que haja uma classe que
recupere este XML e saiba qual serviço chamar. Caso o Google App Engine suportasse JAX-WS
ou AXIS, este passo não seria necessário. Obs: arquivo fonte presente em
http://homes.dcc.ufba.br/~fabufbc#tutorialOwls
package com.example;
import java.util.Iterator;
import javax.xml.bind.JAXB;
import javax.xml.namespace.QName;
import javax.xml.soap.MessageFactory;
import javax.xml.soap.SAAJResult;
import javax.xml.soap.SOAPBody;
import javax.xml.soap.SOAPElement;
import javax.xml.soap.SOAPException;
import javax.xml.soap.SOAPFault;
import javax.xml.soap.SOAPMessage;
import javax.xml.transform.dom.DOMSource;
import com.example.jaxws.ComoEstaOTempo;
public class ClimaInfoSoapHandler {
private static final String NAMESPACE_URI = "http://example.com/";
private static final QName COMO_ESTA_O_TEMPO_QNAME = new QName(NAMESPACE_URI, "comoEstaOTempo");
private MessageFactory messageFactory;
private ClimaInfoAdaptador climaInfoAdapter;
public ClimaInfoSoapHandler() throws SOAPException {
messageFactory = MessageFactory.newInstance();
climaInfoAdapter = new ClimaInfoAdaptador();
}
public SOAPMessage handleSOAPRequest(SOAPMessage request) throws SOAPException {
SOAPBody soapBody = request.getSOAPBody();
Iterator iterator = soapBody.getChildElements();
Object responsePojo = null;
while (iterator.hasNext()) {
Object next = iterator.next();
if (next instanceof SOAPElement) {
SOAPElement soapElement = (SOAPElement) next;
QName qname = soapElement.getElementQName();
if (COMO_ESTA_O_TEMPO_QNAME.equals(qname)) {
responsePojo = handleComoEstaOTempoRequest(soapElement);
break;
}
}
}
SOAPMessage soapResponse = messageFactory.createMessage();
soapBody = soapResponse.getSOAPBody();
if (responsePojo != null) {
JAXB.marshal(responsePojo, new SAAJResult(soapBody));
} else {
SOAPFault fault = soapBody.addFault();
fault.setFaultString("Unrecognized SOAP request.");
}
return soapResponse;
}
private Object handleComoEstaOTempoRequest(SOAPElement soapElement) {
ComoEstaOTempo comoEstaOTempoRequest = JAXB.unmarshal(new DOMSource(soapElement),
ComoEstaOTempo.class);
return climaInfoAdapter.comoEstaOTempo(comoEstaOTempoRequest);
}
}
8.
Informar ao Servlet o que fazer quando for uma requisição SOAP. Todas as requisições
feitas ao servidor são gerenciadas pelo Servlet. Logo, é necessário informá-lo que deverá
chamar o handler quando a requisição for SOAP. Sendo assim, dentro do servlet vamos criar
uma função doPost() que realizará esta chamada. Obs: arquivo fonte presente em
http://homes.dcc.ufba.br/~fabufbc#tutorialOwls
package com.example;
import
import
import
import
import
java.io.IOException;
java.io.InputStream;
java.io.OutputStream;
java.util.Enumeration;
java.util.StringTokenizer;
import
import
import
import
import
import
import
javax.servlet.http.HttpServlet;
javax.servlet.http.HttpServletRequest;
javax.servlet.http.HttpServletResponse;
javax.xml.soap.MessageFactory;
javax.xml.soap.MimeHeaders;
javax.xml.soap.SOAPException;
javax.xml.soap.SOAPMessage;
@SuppressWarnings("serial")
public class WeatherSOAPServerServlet extends HttpServlet {
static MessageFactory messageFactory;
static ClimaInfoSoapHandler soapHandler;
static {
try {
messageFactory = MessageFactory.newInstance();
soapHandler = new ClimaInfoSoapHandler();
} catch (Exception ex) {
throw new RuntimeException(ex);
}
}
public void doGet(HttpServletRequest req, HttpServletResponse resp)
throws IOException {
resp.setContentType("text/plain");
resp.getWriter().println("Hello, world");
}
@Override
public void doPost(HttpServletRequest req, HttpServletResponse resp)
throws IOException {
try {
// Get all the headers from the HTTP request
MimeHeaders headers = getHeaders(req);
// Construct a SOAPMessage from the XML in the request body
InputStream is = req.getInputStream();
SOAPMessage soapRequest = messageFactory.createMessage(headers, is);
// Handle soapReqest
SOAPMessage soapResponse = soapHandler
.handleSOAPRequest(soapRequest);
}
// Write to HttpServeltResponse
resp.setStatus(HttpServletResponse.SC_OK);
resp.setContentType("text/xml;charset=\"utf-8\"");
OutputStream os = resp.getOutputStream();
soapResponse.writeTo(os);
os.flush();
} catch (SOAPException e) {
throw new IOException("Exception while creating SOAP message.", e);
}
@SuppressWarnings("unchecked")
static MimeHeaders getHeaders(HttpServletRequest req) {
Enumeration headerNames = req.getHeaderNames();
MimeHeaders headers = new MimeHeaders();
while (headerNames.hasMoreElements()) {
String headerName = (String) headerNames.nextElement();
String headerValue = req.getHeader(headerName);
StringTokenizer values = new StringTokenizer(headerValue, ",");
while (values.hasMoreTokens()) {
headers.addHeader(headerName, values.nextToken().trim());
}
}
}
}
return headers;
9. Por fim, realizar a publicação no Google App Engine. Clique com o botão direito sobre o
projeto e escolha Google > App Engine Settings. No campo Application ID, vamos colocar o ID
da aplicação, criada anteriormente.
Referências:
[1] HOW TO: Build a SOAP Server and a SOAP Client on Google App Engine, disponível em:
http://code.google.com/intl/pt-BR/appengine/articles/soap.html , último acesso em 23/11/2011
Download