1        总体介绍

WebService是一种基于SOAP协议的远程调用标准。通过WebService可以将不同操作系统平台,不同语言、不同技术整合到一起。

在Android SDK中并没有提供调用WebService的库,可以通过HttpPost将基于soap协议的xml发送给远程服务器端,在客户端通过解析返回的xml文件进行处理,也可以通过第三方类库来调用WebService。

PC版本的WebService库非常丰富,但这些对Android来说过于庞大。适合手机的WebService客户端的SDK比较常用的是KSOAP2。本文将主要描述基于ksoap2 android来调用远程服务,最后也会给出一个用HttpPost方式调用WebService方式供参考。

 

在Android平台调用Web Service需要依赖于第三方类库ksoap2,它是一个SOAP Web service客户端开发包,主要用于资源受限制的Java环境如Applets或J2ME应用程序。在Android平台中我们使用ksoap2 android。KSoap2Android 是Android平台上一个高效、轻量级的SOAP开发包。

 

ksoap2 android当前的最新版本为ksoap2-android-assembly-2.5.6-jar-with-dependencies.jar

下载地址:http://code.google.com/p/ksoap2-android/

注:2011.7.6 ksoap2-android 发布了新的2.5.7jar,包和类发生了极大的改变,以下测试皆在2.5.6版本下使用,2.5.7已无法按下述使用。

2        开发环境

2.1       远程Web Service准备

既然要调用WebService,那就要先有Web Service。本文Android系统测试调用的Web Service,是在TOMCAT6下的Web应用中发布的三个服务方法。

远程服务器Web Service接口文件如下图:

各接收一个字符串参数,分别返回字符串对象、用户对象、用户的列表对象

 

服务端的WebService开发与平台和语言无关,也不是本文所述重点,故不详细描述。

 

2.2       创建Android工程

创建工程项目后,引入下载的ksoap2-android类库

 

在Android工程项目中,本文中使用的模拟器环境是android 1.6 level4。

在项目中除了使用自动创建AndroidWSActivity.java文件外,别外还创建了四个Activity 文件,其中AndroidWSActivity.java文件中定义了一个输入框和四个按钮,四个按钮通过加上监听事件分别调用WSActivity1.java,WSActivity2.java,WSActivity3.java,HCActivity1.java。在这四个文件中,前三个通过ksoap2 android来调用服务,最后一个通过HttpPost方式来调用服务。

项目总体目录如下图:

2.3       配置添加访问网络的权限

打开AndroidManifest.xml文件,加上访问网络权限,如下图:

3        Android调用Web Service

Android系统在调用Web Service的方法中,按以下过程调用

3.1       指定 WebService 的命名空间和方法

// 命名空间,在WebService描述文件WSDL文件中会给出nameSpace

StringnameSpace = "http://manager.ws.heluo.com/";

// 方法名称

StringmethodName = "sayHi";

// 指定调用WebService的命名空间和调用的方法名

SoapObjectrequest = new SoapObject(nameSpace, methodName);

3.2       设置调用方法的参数值, 如果没有参数,可以省略

// 添加参数

request.addProperty("arg0", inputValue);

addProperty方法中的参数名要按照WebService描述文档WSDL中的描述进行设置。

有的资料说该参数值并不一定与服务端的WebService类中的方法参数名一致,只要设置参数的顺序一致即可。但经本次测试,参数名不一致,服务端并不能取到参数值。

3.3       生成调用WebService方法的SOAP请求信息及版本信息

// 生成调用WebService方法的SOAP请求信息,并指定SOAP的版本

SoapSerializationEnvelope envelope=

new SoapSerializationEnvelope(SoapEnvelope.VER11);

//设置SoapSerializationEnvelope类的bodyOut属性,

//该属性的值就是在3.1中创建的SoapObject对象。;

envelope.bodyOut= request;

// 设置是否调用的是dotNet开发的WebService

envelope.dotNet = false;

3.4       创建HttpTransportSE传输对象

// 服务端点, 在WebService描述文件WSDL文件中描述的endPoint

String endPoint= "http://10.0.2.2:8888/mini-web/ws/Manager";

// 通过构造方法创建传输对象

HttpTransportSE transport= new HttpTransportSE(endPoint);

注意:本例中访问的IP是10.0.2.2,因为所访问WebService.是在模拟器所在PC上发布的。

Android模拟器(simulator)把它自己作为了localhost,也就是说,代码中使用localhost或者127.0.0.1来访问,都是访问模拟器自己!若你想在模拟器simulator上面访问你的电脑,那么就使用android内置的IP: 10.0.0.2,10.0.0.2是模拟器设定的特定IP,是你电脑的别名,在模拟器上用10.0.0.2 就能成功访问你的电脑本机。

3.5       使用call方法调用WebService方法

// 调用WebService,第一个参数是命名空间+调用方法名称

transport.call(namespace+methodName, envelope);

3.6       获得返回的数据

ksoap2能够将返回的xml转换成SoapObject对象,然后我们就可以通过操作对象的方式来获取需要的数据。Ksoap2包装的SoapObject对象以类拟JSON键值对的形式返回,如果只返回一个单值,ksoap2包装成SoapPrimitive对象;如果返回的是对象,ksoap2将每个属性值都包装成SoapPrimitive对象,组成一个SoapObject对象返回;而对于返回数组对象,则以Vector<SoapObject>形式返回。

以下是调用三个测试服务方法的返回数据处理:

一.返回简单字符串

// 若返回值是单个值,用SoapPrimitive取

SoapPrimitive saopPrimitive=

(SoapPrimitive)envelope.getResponse();

// 获取返回的结果

Stringresult = saopPrimitive.toString();

二.返回一个User对象

//返回SoapObject.toString()内容:anyType{age=18; id=2; name=周杰伦;}

SoapObjectresponseSO = (SoapObject)envelope.getResponse();

// 通过responseSO.getProperty()取对象属性值,其返回对象是 SoapPrimitive

String name= responseSO.getProperty("name").toString();

// 也可以通过下标取值,下标是从0开始

String id =responseSO.getProperty(0).toString();

三.返回的是List<User>对象

Vector<SoapObject>responseVector =

(Vector<SoapObject>)envelope.getResponse();

Iterator<SoapObject>it = responseVector.iterator();

while (it.hasNext()) {

SoapObject soapObject = (SoapObject)it.next();

String name = soapObject.getProperty("name").toString();

}

另一种方式得到返回数据

通过使用 bodyIn 及 getProperty方式,返回的内容中有所不同,取值方式类似。

// 使用envelope.bodyIn得到返回的SoapOjbect对象

SoapObjectsoapObject = (SoapObject) envelope.bodyIn;

soapObject.getProperty(0).toString();

两种方式调用第一个WebService时返回内容对比

Ø  envelope.bodyIn方式返回的SoapObject内容:

sayHiResponse{return=Hellogongwie; }

sayHiResponse 是WSDL中描述的返回结果的方法,如果取值,以

responseSO.getProperty(0)

Ø  envelope.getResponse方式返回的SoapPrimitive内容

Hellogongwie

4        通过HttpPost调用WebService及下载附件

4.1     android客户端调用下载附件 WebService

用HTTP方式可以调用WebService,并且可以传输附件。

注:Ksoap-android2.5.6传输附件似乎不支持,经使用Ksoap-android2.5.6测试返回经Base64编码的XML文件中会带上“UUID:XXX”一串值,是个不合法的XML,而SoapObject解析此XML出错。

// 定义待请求的URL,Endpoint+MethodName

String url = "http://10.0.2.2:8888/mini-web/ws/Manager/sayHi";

// 创建HttpClient实例

HttpClient httpclient = newDefaultHttpClient();

try {

// 将请求内容包装成基于SOAP协议的XML文件,其中inputValue是参数值

StringBuildersb = new StringBuilder("");

sb.append("<?xml version=\"1.0\"encoding=\"UTF-8\"?>");

sb.append("<soapenv:Envelope");

sb.append(" xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\"");

sb.append(" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"");

sb.append(" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">");

sb.append(" <soapenv:Body>");

sb.append("    <sayHixmlns=\"http://manager.ws.heluo.com/\">");

sb.append("     <arg0 xmlns=\"\">").append(inputValue).append("</arg0>");

sb.append("   </sayHi>");

sb.append(" </soapenv:Body>");

sb.append("</soapenv:Envelope>");

StringSOAPRequestXML = sb.toString();

// 根据URL创建HttpPost实例

HttpPost httppost = newHttpPost(url);

httppost.setHeader("Content-Type","application/soap+xml;charset=UTF-8");

// 设置编码

StringEntity se = newStringEntity(SOAPRequestXML,HTTP.UTF_8);

se.setContentType("text/xml");

httppost.setEntity(se);

// 如果需要传递参数,设置参数

//List<NameValuePair> params= new ArrayList<NameValuePair>();

//params.add(newBasicNameValuePair("arg0", inputValue));

//httppost.setEntity(newUrlEncodedFormEntity(params));

// 发送请求并获取反馈

BasicHttpResponse httpresponse= (BasicHttpResponse)httpclient.execute(httppost);

// 取得返回结果

BasicHttpResponse httpresponse = (BasicHttpResponse)httpclient.execute(httppost);
 String result = EntityUtils.toString(httpresponse.getEntity());

// 以下只是用简单方式取数据,正常情况应用SAX解析XML
            int start = result.indexOf("<return>");
            int end  = result.indexOf("</return>");
            String image = result.substring(start+7,end);
            
            // 如果WS返回的是经Base64编码的图片信息,则按以下操作
            //Base64.decodeBase64("");//不可用
            //byte[] buffer = new BASE64Decoder().decodeBuffer(image);//不可用
            byte[] buffer = Base64.decode(image,0);//android2.2版可用
          
            Bitmap bm = BitmapFactory.decodeByteArray(buffer,0, buffer.length);

//在ImageView中显示图片信息

//imageView.setImageBitmap(bm);

//写文件到本地保存
            //FileOutputStream outStream = this.openFileOutput("gongwei.jpg", Context.MODE_PRIVATE);
            //outStream.write(buffer);
            //outStream.close();

} catch (Exception e) {

e.printStackTrace();

}

 4.2 web service服务端(下载图片方法)

@Override
    public String downImage(String imageName) {
        
        System.out.println("web service invoke>>>>>>>>>>>>>>imageName="+imageName);
        String imageBuffer = "nono";
        FileInputStream imageFile = null;
        try {
            
            imageFile = new FileInputStream("D:/xx.jpg");
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            byte[] buffer = new byte[8192];
            int count = 0;
            while ((count = imageFile.read(buffer)) >= 0) {
                baos.write(buffer, 0, count);
            }
            imageBuffer = new String(Base64.encodeBase64(baos.toByteArray())); 
            
        } catch (IOException e) {
            e.printStackTrace();
            System.out.println("error--"+e.getMessage());
            
        }finally{
            try{
                imageFile.close();
            }catch(IOException e){
                e.printStackTrace();
            }
        }        
        return imageBuffer;
    }

android webservice 及附件下载相关推荐

  1. 安卓Android 微信 附件下载跳转至QQ浏览器后 无法显示(二次跳转)的问题

    vue 项目里遇到了 在微信里下载附件(非apk)的问题 如 txt/pdf/Excel/doc/docx 等 先分析 区分ios和安卓 苹果/ios/ ios 系统 无法下载 会直接打开pdf ex ...

  2. Android 入门eclipse+ADT配置,bug处理及附件下载(一)

    Android 入门eclipse+ADT配置,bug处理及附件下载(一) 由于时代的变化科技的发展手机也发生了飞跃的变换,从以前的只能音频通话的"大哥大"到现在流行的3G手机:具 ...

  3. android 信息添加附件功能,网易邮箱Android新版 添加附件可直接预览

    网易邮箱Android客户端近日发布了新版本V2.3,新版安卓客户端对附件处理做出较大改进.用户转发邮件附件时,不需要下载到本地实现直接转发,更加方便:写信时,添加附件由原先的列表形式变成预览图形式, ...

  4. android phone电脑驱动下载,全机型Android Phone驱动及安装教程(XP,Vista,Win7).pdf

    全机型Android Phone驱动及安装教程(XP,Vista,Win7) HTC Android( ) Android Phone 安卓 全机型 驱动及安 装教程(XP,Vista,Win7 ) ...

  5. Android WebService 客户端 之 andriod ksoap2 WebService 复杂对象参数

    关于WebService的话题,作为一个Java屌丝,我想也不用多说了.只要读者是做"码农"这行的基本手到擒来.那么做为一个对Android不是很了解的屌丝"攻城狮&qu ...

  6. silverlight 类似百度的图片浏览器,视频播放,附件下载功能,全部后台程序。...

    #region =========图片点击按钮================String[] nr = new String[7] { "房屋照片", "房屋所有权证& ...

  7. Android webservice的用法详细讲解

    Android webservice的用法详细讲解 看到有很多朋友对WebService还不是很了解,在此就详细的讲讲WebService,争取说得明白吧.此文章采用的项目是我毕业设计的webserv ...

  8. Struts2.0实现的文件上传(单附件和多附件)以及附件下载功能

    --------------------------------------------------单附件上传:-------------------------------------------- ...

  9. 使用javaMail收邮件 支持附件下载

    http://haohaoxuexi.iteye.com/blog/1162044 使用javaMail收邮件主要有两种协议,一种是pop3,一种是imap.这两种协议都可以用来收邮件,但是在其中的处 ...

最新文章

  1. 跨平台图表控件TeeChart使用教程:导入XML数据
  2. IPv6扩展头部 (一) 扩展头部格式、类型与扩展选项
  3. Thymeleaf中使用select进行消息回显时提示:Exception evaluaating SpringEL expression
  4. Qt Quick 中 QML 与 C++ 混合编程详解
  5. Spring Boot实践——基础和常用配置
  6. python ide: pycharm
  7. Sql Server RowNumber和表变量分页性能优化小计
  8. 如何使用Docker在GitLab上设置CI
  9. java 虚拟打印机_打印作业提交给打印机,使用虚拟打印机但不是真正的打印机 . Java的...
  10. deque iterator not dereferencable 问题
  11. 多种系统负载100%方法(高可用测试、性能压测用)
  12. Java中final、finally、finalize的理解
  13. eclipse配置xml的自动提示
  14. 2D纹理与3D模型共存时的渲染问题
  15. 中小型软件产品解决方案模板
  16. 山东大学_网络攻击与防范(林)_名词解释
  17. 符号检验和置信区间R代码
  18. win8访问不了服务器共享文件夹,如何解决Win8局域网无法访问共享文件夹的问题...
  19. Android中的颜色设置和常见RGB颜色表
  20. Vert.x(vertx) 创建HTTP服务

热门文章

  1. 设置php的环境变量
  2. 小程序服务器缴费,小程序高速快速缴费了解一下?
  3. diskgenius调整分区时报错“您选择的分区不支持无损调整容量“
  4. 数据告诉你:那些成功出道的男团女团,现在怎么样了
  5. SpringBoot整合Redis+Redis缓存应用+Redis实现Session共享+...
  6. Promise.any 的作用,如何自己实现一个 Promise.any
  7. Vue2.x 源码 - render 函数生成 VNode
  8. laravel 阿里云短信验证码
  9. 获取Url地址中参数的3种方法
  10. 内网升级“高效安全”利器!统信软件发布私有化更新管理平台