import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;
import android.content.Context;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.util.Log;
public class Webservice {
private static final String CATEGORIA = "WebService";
private static int CONNECTION_TIMEOUT = 3750;
private static int SOCKET_TIMEOUT = 5000;
private static String ENCODING = "UTF-8";
private HttpClient cliente = null;
private HttpPost post = null;
private HttpResponse resposta = null;
private HttpEntity entity = null;
private HttpParams httpParameters = null;
private Context context = null;
public Webservice(Context context, String URL){
this.context = context;
httpParameters = new BasicHttpParams();
HttpConnectionParams.setConnectionTimeout(httpParameters, CONNECTION_TIMEOUT);
HttpConnectionParams.setSoTimeout(httpParameters, SOCKET_TIMEOUT);
cliente = new DefaultHttpClient(httpParameters);
post = new HttpPost(URL);
post.setHeader("SOAPAction", "urn:execute"); //No meu caso usei este HEADER!
}
/**
*
* @param xml, XML que deverá ser enviado ao WS.
* @return mensagem de retorno do WS.
* @throws Exception
*/
public String consumirWebService(String xml) throws Exception {
String retorno = "";
try {
entity = consumir(xml);
if (entity != null) {
retorno = entityToString(entity);
//Pode ser tratado de várias maneiras aqui, usando DocumentBuilder
}
return retorno;
} catch (Exception e) {
Log.d(CATEGORIA, e.getMessage());
throw new Exception(e.getMessage());
}
}
private HttpEntity consumir(String xml) throws Exception {
try {
isConnected();
entity = new StringEntity(xml, ENCODING);
post.setEntity(entity);
resposta = cliente.execute(post);
return resposta.getEntity();
} catch (UnsupportedEncodingException e) {
Log.e(CATEGORIA, "[3] " + e.getMessage());
throw new Exception("Erro no arquivo XML.");
} catch (ClientProtocolException e) {
Log.e(CATEGORIA, "[2] " + e.getMessage());
throw new Exception("Erro no protocolo.");
} catch (IOException e) {
Log.e(CATEGORIA, "[1] " + e.getMessage());
throw new Exception("Erro ao baixar dados do Servidor.\nVerifique sua conexão com a Internet.");
}
}
public void isConnected() throws Exception {
NetworkInfo info = null;
info = ((ConnectivityManager) this.context.getSystemService(Context.CONNECTIVITY_SERVICE)).getActiveNetworkInfo();
if (info == null || !info.isConnected()) {
throw new Exception("Verifique sua conexão com a Internet.");
}
if (info.isRoaming()) {
throw new Exception("Verifique sua conexão com a Internet.");
}
}
private String entityToString(HttpEntity entity) throws Exception {
try {
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
entity.writeTo(byteArrayOutputStream);
return byteArrayOutputStream.toString();
} catch (IOException e) {
Log.d(CATEGORIA, e.getMessage());
throw new Exception("Erro ao efetuar download.");
}
}
}
Devido a dúvidas, colocarei um exemplo de XML para consumir um Webservice SOAP, portanto estes métodos permitem que você consuma sim um serviço SOAP:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns="http://exemplo.com.br/WebService/SOAP">
<soapenv:Header/>
<soapenv:Body>
<ns:execute>
!! OS DADOS PARA O SEU WEBSERVICE !!</ns:execute>
</soapenv:Body>
</soapenv:Envelope>
Este código foi uma adaptação rápida do que eu uso, qualquer dúvida ou erros comentem, espero ajudar em algo. O código permite consultar WS somente com as API e recursos nativos do Android.
Dante poderia me passar como instanciar a classe e passar os parâmetros, sou novo com java e android.
ResponderExcluirObs.: se puder passar um exemplo com a chamada de um webserver em c# seria ótimo.
Excelente post!!!
Obrigado,
Olá Cecilia, primeiramente você deve estar rodando a IDE com o Android SDK instalado e criado um projeto Android, correto?
ResponderExcluirPulando isso, para ter uma instância da classe "webservice", basta chamar o construtor e passar os respectivos parâmetros da assinatura do método.
Exemplo de código:
Webservice ws = new Webservice(this, "http://www.endereco.com.br/CalculadoraWS");
ws.consumir(xml);
Infelizmente no momento não poderei postar em C#, estou usando Linux e não tenho instalado os recursos necessários para fazer o exemplo.
Espero ter ajudado, qualquer dúvida pode comentar.
* Corrigi o nome da classe para iniciar com maiuscúla.
Dante
ResponderExcluirEm primeiro lugar, parabéns pela iniciativa.
Sou novo em Java e Netbeans. Já consegui criar um WS e consegui consumir usando um cliente em Java ( o velho exemplo do Calculator e Hello World), usando o Netbeans.
Estou há dias tentando criar um cliente de Webservice no Android. Cara.. estou penando... já visitei uma centena de sites em inglês e português... mas nada. Estou usando o Netbeans 7 beta.
Ainda não ficou claro para mim os parâmetros que você está usando. Por exemplo, no meu caso eu tenho:
Meu WSDL:
"http://192.168.0.103:8080/axis2/services/HelloAxisWorld?wsdl"
Meu Web Service (tenho dois métodos: ADD e HELLO), chamando desta forma:
Método Hello:
http://localhost:8080/axis2/services/HelloAxisWorld/hello?name=XYZ
Método Add:
http://localhost:8080/axis2/services/HelloAxisWorld/add?x=2&y=3
Minha pergunta é: como monto os parâmetros de chamada na sua aplicação, considerando o meu webservice?
Muito obrigado pela ajuda.
Marcelo
Marcelo, vendo por cima e rápido, vi que seu webservice tem dois parametros inteiro correto?
ResponderExcluirEu mostrei um exemplo onde o Webservice recebe uma String, onde a string seria o XML.
Isso permite que eu com apenas um método do webservice receba vários formatos de XML e trate-os de forma adequada.
Verei se tem como utilizar o meu método com um WS com dois parametros, assim que puder irei postar ou responde-lo aqui.
Atenciosamente.
Marcelo, outro detalhe importante que não havia considerado é que o seu Webservice é SOAP, e o exemplo que usei é do tipo RESTFUL.
ResponderExcluirMaiores detalhes em:
http://netbeans.org/kb/docs/websvc/intro-ws.html
Continuarei lendo e pesquisando para tentar achar uma solução para seu problema.
Dante
ResponderExcluirRealmente, estou usando SOAP (ou tentando...). Fiz vários exemplos... crio o Webservice do lado do servidor sem problemas; crio o cliente Java sem problemas também... mas não consigo no Android.
Estou usando as libs KSOAP2 para Android. Mas sempre recebo a mensagem: "... application has stopped unexpectedly".
Por favor, avise-me caso você consiga algum avanço.
Seguinte, o KSOAP tem um segredo! Não use a versão JME para android, usa a versão JSE... faça o teste!
ResponderExcluirVou fazer um tutorial demonstrando um WS Restful com o meu fonte e um WS SOAP com KSOAP!
Eu já usei o KSOAP no android e rodou perfeitamente, porém o restful achei mais rápido e leve de trabalhar, mas perde-se segurança...
Dante, não sei se é um problema do netbeans, então... adicionei a lib ksoap2-j2se-full-2.1.2.jar (removi a anterior do KSOAP2), rodei e deu o mesmo erro...
ResponderExcluirVocê testou no Netbeans?
Valeu.
Não, usei somente o Eclipse para desenvolver APP para o Android.
ResponderExcluirDante, uma pergunta: um cliente RESTFUL pode consumir Webservice de um servidor SOAP?
ResponderExcluirMeu amigo, este pergunta estou curioso para responder também!
ResponderExcluirEU, sem procurar nada sem pesquisar acredito que seja possível sim, a questão seria como?
Estarei investigando isso, vou montar mais WS o quanto antes, BEM BEM simples para fazer os testes.
* Acredito que sim por que são conexão HTTP, mas preciso checar a informação.
Olha, seguinte como eu imaginava:
ResponderExcluir"SOAP: protocolo-padrão para transmissão de dados dentro da arquitetura de WS proposta pelo W3C. O SOAP é um protocolo baseado no XML e segue o modelo "RESQUEST-RESPONSE" do HTTP."
SOAP: Simple Object Access Protocol.
Bem lendo agora vi que são coisas um tanto diferentes, mas tenho a impressão que SOAP é um REST ou RESTFULL (HTTP) com um PROTOCOLO sobre eles. Ou seja até seria possível fazer, mas é o custo de fazer isso?
Sobre o KSOAP, dê uma olhada nisso:
http://portalandroid.org/comunidade/viewtopic.php?f=5&t=8666&sid=4755d4661d198c08a5aba9f7e6f72753&p=69774#p69774
Fala Dante
ResponderExcluirÉ impressionante, cara, nem com esta lib, o Webservice cliente do Android roda no Netbeans (roda no cliente Java, mas não no Netbeans).
Quando você tiver algum tempo, veja se este código roda no teu Eclipse:
CLIENTE WS Cliente Android:
----------------------------
package org.me.androidapplication1;
import android.app.Activity;
import android.os.Bundle;
/**
*
* @author br05db
*/
import org.ksoap2.SoapEnvelope;
import org.ksoap2.serialization.SoapObject;
import org.ksoap2.serialization.SoapSerializationEnvelope;
import org.ksoap2.transport.HttpTransportSE;
import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;
public class MainActivity extends Activity {
private String METHOD_NAME = "add"; // our webservice method name
private String SOAP_ACTION = "http://example.web.org/" + METHOD_NAME; // here your package name in webservice but in reverse order + method name
private String NAMESPACE = "http://axishello"; // Here package name in webservice with reverse order.
private static final String URL = "http://localhost:8080/axis2/services/HelloAxisWorld?wsdl"; // you must use ipaddress here, don’t use Hostname or localhost
@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
setContentView(R.layout.main);
((TextView) findViewById(R.id.txtsearch)).setText("Hello");
try {
SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME);
request.addProperty("i", 5);
request.addProperty("j", 15);
SoapSerializationEnvelope
envelope = new SoapSerializationEnvelope
(SoapEnvelope.VER11);
envelope.dotNet = true;
envelope.setOutputSoapObject
(request);
//AndroidHttpTransport androidHttpTransport = new AndroidHttpTransport(URL);
HttpTransportSE androidHttpTransport = new HttpTransportSE(URL);
androidHttpTransport.call(SOAP_ACTION,envelope);
Object result = envelope.getResponse();
System.out.println("Result : " + result.toString());
((TextView) findViewById(R.id.txtsearch)).setText(result.toString());
}
catch (Exception E) {
((TextView) findViewById(R.id.txtsearch)).setText("ERROR:"+ E.getClass().getName()
+ ": " + E.getMessage());
}
}
}
CLIENTE WS NO LADO DO SERVIDOR:
----------------------------------
package axishello;
/**
*
* @author BR05db
*/
public class HelloAxisWorld {
/** Sample method
*/
public String hello(String name) {
return "Hello World and "+name;
}
public int add(int x, int y) {
return x+y;
}
}
Valeu!
IMportante: quando coloco o código em comentário, ou faço o debug, vejo que ele morre sempre na linha:
ResponderExcluirSoapObject request = new SoapObject(NAMESPACE, METHOD_NAME);
Já troquei o NAMESPACE E METHOD por várias outras opções (na verdade ele sai do WSDL)... e nada...
Fala Dante
ResponderExcluirÉ impressionante, cara, nem com esta lib, o Webservice cliente do Android roda no Netbeans (roda no cliente Java, mas não no Netbeans).
Quando você tiver algum tempo, veja se este código roda no teu Eclipse:
CLIENTE WS Cliente Android:
----------------------------
package org.me.androidapplication1;
import android.app.Activity;
import android.os.Bundle;
/**
*
* @author br05db
*/
import org.ksoap2.SoapEnvelope;
import org.ksoap2.serialization.SoapObject;
import org.ksoap2.serialization.SoapSerializationEnvelope;
import org.ksoap2.transport.HttpTransportSE;
import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;
public class MainActivity extends Activity {
private String METHOD_NAME = "add"; // our webservice method name
private String SOAP_ACTION = "http://example.web.org/" + METHOD_NAME; // here your package name in webservice but in reverse order + method name
private String NAMESPACE = "http://axishello"; // Here package name in webservice with reverse order.
private static final String URL = "http://localhost:8080/axis2/services/HelloAxisWorld?wsdl"; // you must use ipaddress here, don’t use Hostname or localhost
@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
setContentView(R.layout.main);
((TextView) findViewById(R.id.txtsearch)).setText("Hello");
try {
SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME);
request.addProperty("i", 5);
request.addProperty("j", 15);
SoapSerializationEnvelope
envelope = new SoapSerializationEnvelope
(SoapEnvelope.VER11);
envelope.dotNet = true;
envelope.setOutputSoapObject
(request);
//AndroidHttpTransport androidHttpTransport = new AndroidHttpTransport(URL);
HttpTransportSE androidHttpTransport = new HttpTransportSE(URL);
androidHttpTransport.call(SOAP_ACTION,envelope);
Object result = envelope.getResponse();
System.out.println("Result : " + result.toString());
((TextView) findViewById(R.id.txtsearch)).setText(result.toString());
}
catch (Exception E) {
((TextView) findViewById(R.id.txtsearch)).setText("ERROR:"+ E.getClass().getName()
+ ": " + E.getMessage());
}
}
}
CLIENTE WS NO LADO DO SERVIDOR:
----------------------------------
package axishello;
/**
*
* @author BR05db
*/
public class HelloAxisWorld {
/** Sample method
*/
public String hello(String name) {
return "Hello World and "+name;
}
public int add(int x, int y) {
return x+y;
}
}
Valeu!
Irei verificar, verei também para escrever algo sobre o KSOAP!
ResponderExcluirMarcelo no final do Post coloquei uma atualização que pode ser muito útil para você.
ResponderExcluirAtenciosamente
Marcelo, conseguiu entender a questão do SOAP?
ResponderExcluirFala Dante
ResponderExcluirCara, na verdade, agradeceria se você me desse uma dica de como passar os parâmetros no meu caso.
Veja meu Webservice (Servidor) abaixo:
package axishello;
/**
*
* @author BR05db
*/
public class HelloAxisWorld {
/** Sample method
*/
public String hello(String name) {
return "Hello World and "+name;
}
public int add(int x, int y) {
return x+y;
}
}
Agradeceria se você pudesse me dizer como montar os parâmetros; e mais, o teu xml entra como parâmetro do método "consumir"? se for, como você pretende montar o XMLna montagem do código?
Valeu.
Fala Dante,
ResponderExcluirSou novato tb em android e to precisando fazer uma aplicação consumir um web services que foi desenvolvida em C#. Essa listagem apresentada serve tb para consumir web services em outras linguagens?
Este comentário foi removido pelo autor.
ResponderExcluirOlá Flavio,
ResponderExcluirOlha, em teoria estou consumindo webservices sem utilização de APIs, portanto seria a forma mais nativa de se acessar um WS. Acredito que não haveria problemas em consumir o serviço!
Basta cuidar com relação a segurança SSL e codificação do WS (UTF-8 e etc).
Se você utilziar o KSOAP, que prometi colocar um post sobre ele, você também pode consumir WS da plataforma Microsoft, basta setar um atributo do Objeto para dizer que o WS é .NET ou algo assim.
O conceito de WS surgiu justamente para integração de diferentes aplicações com diferentes tecnologias e ainda para soluções distribuidas, pois é um padrão que todas tecnologias podem implementar.
Olá Dante,
ResponderExcluirPois é!!
Não tive sucesso com o ksoap2!! e acabei desistindo ai achei o seu post e ja avancei muito com ele, porém quando a linha:
resposta = cliente.execute(post);
o sistema gera uma ioexception e o getMessage dele é o host do WS. e não executa.
Estou usando o eclipse e o sdk 2.3.1.
Mande e-mail para mim, pega o MSN/email neste link:
ResponderExcluirhttp://www.blogger.com/profile/17325211535924785096
mandei o invite no msn.
ResponderExcluirFala Dante, venho seguindo o seu posts, desde outros sites, onde você começaba falando que tinha implementado o web service com EJB. Mas eu so acho jeitos de comunicarme com o webservice via jndi, como eu faço para obter a url do web service? Voce pode postar um exemplo simple do lado do webservice com ejb3?
ResponderExcluirDisponibiliza o projeto para download
ResponderExcluirE ai Dante, tudo joia?
ResponderExcluirEstive tentando utilizar o ksoap2 mas só tive sucesso com tipos primitivos. Não consegui enviar e nem receber um tipo complexo com ele.
Com esse seu artigo eu consigo trabalhar com qualquer WebService? Eu precisaria montar o arquivo XML na mão?
Obrigado