android webservice 及附件下载

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;
    }


  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值