1.WebService服务器端程序搭建
(1)WebService建立的过程
右键new->Dynamic Web Project程序写完后,将项目发布成WebService具体步骤如下
1)在java程序右键选择new->other->Webservices>webservice
2)进入WebServices页面,配置Service implementation(选择对应工程的包名),点击下面的Public the Web service,点击next
3)进入web service java bean identity,点击next按键
4)按照相应的提示进行操作,最后finish
WebService建立的过程参考http://www.docin.com/p-247903693.html
(2)android WebService 上传图片的服务器Web程序如下
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import sun.misc.BASE64Decoder;
public class UploadWS {
public String updateImage(String filename,String image){
FileOutputStream fos = null;
try{
String toDir = "D:\\images";
byte[] buffer = new BASE64Decoder().decodeBuffer(image);
File destDir = new File(toDir);
if(!destDir.exists())
destDir.mkdir();
System.out.println(buffer.length);
fos = new FileOutputStream(new File(destDir,filename));
fos.write(buffer);
fos.flush();
fos.close();
return "上传图片成功!" +"图片路径为:"+toDir;
}catch(Exception e){
e.printStackTrace();
}
return "上传图片失败!";
}
}
按照(1)中生成wsdl文档,其中wsdl文档在工程文件WebContent中的wsdl文件中生成。将wsdl文档中<wsdlsoap:address location=">的http://localhost:8080/UpLoadWS/services/UploadWS?wsdl复制到浏览器观察会显示
具体的函数wsdl说明文档。
对上面程序的知识点补充一下:
filename为上传图片的名字,image为上传图片传送的数据流
FileInputStream和FileOutputStream这是一对继承于InputStream和OutputStream的类,用于本地文件读写
(二进制格式读写并且是顺序读写,读和写要分别创建出不同的文件流对象);
本地文件读写编程的基本过程为:
① 生成文件流对象(对文件读操作时应该为FileInputStream类,而文件写应该为FileOutputStream类);
② 调用FileInputStream或FileOutputStream类中的功能函数如read()、write(int b)等)读写文件内容;
③ 关闭文件(close())。
关于文件流的操作见文章http://www.cnblogs.com/jjtech/archive/2011/04/17/2019210.html
Base64编码的作用:由于某些系统中只能使用ASCII字符。Base64就是用来将非ASCII字符的数据转换成ASCII字符的一种方法。它使用下面表中所使用的字符与编码。
而且base64特别适合在http,mime协议下快速传输数据。
关于Base64编码详见http://www.cnblogs.com/zjypp/archive/2009/12/23/2319372.html和http://blog.csdn.net/anhuixiaozi/article/details/6219337
(3)Android客户端获取WebService服务器的图片
public void uploadTest(){
try{
String srcUrl = "/mnt/sdcard/"; //路径
String fileName = "aa.jpg"; //文件名
FileInputStream fis = new FileInputStream(srcUrl+fileName);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] buffer = new byte[8192];
int count = 0;
while((count = fis.read(buffer))>=0){
baos.write(buffer,0,count);
}
String uploadBuffer = new String(Base64.encode(baos.toByteArray()));
ConnectWebService(fileName,uploadBuffer);
Log.i("bupt_uploadTest","start");
fis.close();
}catch(FileNotFoundException e){
e.printStackTrace();
}catch(IOException e){
e.printStackTrace();
}
}
1)InputStream的read方法
① int read (byte[] b) 读入一个字节数组,并且返回实际读入的字节数,或者在碰到流的结尾时返回-1,这个read方法最多读入b.length个字节
②int read(byte[]b,int off,int len)读入一个字节数组,这个read方法返回实际读入的字节数,或者在碰到流的结尾时返回-1。b代表数据读入的数组,off第一个读入字节应该被放置的位置在b中的偏移量,len 读入字节的最大数量
2)outputstream write方法
①void write(byte[]b)及void write(byte[]b,int off ,int len)
从字节数组读取出数据到对应的输出流中,其中b表示字节数组,off表示读取的起始位置,表示读取长度为len的字节进入到输出流中
3)ByteArrayOutputStream 读取字节数组到输出流,ByteArrayInputStream读取字节数组数据的输入流到对应的字节数组或者字符类型的容器中
java中输入流和输出流在分别调用read和write两个方法时需要定义两个不同的流对象
关于输入流和输出流比较好的定义位于http://www.cnblogs.com/springcsc/archive/2009/12/03/1616187.html
4)String类的定义
String(); 构造一个空字符串对象
String(byte[] bytes); 通过byte数组构造字符串对象
String(byte[] bytes,int offset,int length);通过byte数组,从offset开始,总共length长的字节构造字符串对象
String(char[] value); 通过char数组构造字符串对象
String(byte[] char,int offset,int length);通过char数组,从offset开始,总共length长的字节构造字符串对象
String(String original); 构造一个original的副本,拷贝一个original
String(StringBuffer buffer);通过StringBuffer数组构造字符串对象
如// 实例一个String对象
String str = new String("str abcd");
参考文档http://blog.csdn.net/qq594979397/article/details/6492894
public boolean ConnectWebService(String fileName,String imgBuffer) {
String Uri = "http://10.110.6.118:8080/UpLoadWS/services/UploadWS";
String namespace ="http://bupt.org";
String methodName = "updateImage";
SoapObject request = new SoapObject(namespace,methodName);
request.addProperty("fileName",fileName);
request.addProperty("image",imgBuffer);
SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
envelope.bodyOut=request;
envelope.dotNet = false;
envelope.setOutputSoapObject(request);
envelope.encodingStyle="UTF-8";
HttpTransportSE aht = new HttpTransportSE(Uri);
try{
String SOAP_ACTION = "";
//此步容易出现网络连接错误:一个manifest中是否给予权限,另一方面就是查看网络方面是不是通的,能不能连接到外网或者ip地址是否正确等等
aht.call(SOAP_ACTION,envelope);
SoapObject response = (SoapObject)envelope.bodyIn;
System.out.print("objectStr:"+response.toString());
String result = "返回的结果:"+ response.getProperty("updateImageReturn").toString();
// Toast.makeText(this, response.toString(), Toast.LENGTH_LONG).show();
}catch(Exception e){
e.printStackTrace();
}
return false;
}
}
WebService的大致流程
a.)下载ksoap2-android项目的ksoap的jar包,将对应的包添加到android工程项目中
b)首先创建SoapObject对象,创建该对象时需要传入所要调用的命名空间和WebService的方法名
c)如果有参数要传给WebService服务器端,调用SoapObject对象的addProperty(String name,Object value)方法来设置参数,该方法的name参数指定参数名;value参数指定参数值。
d)调用SoapSerializationEnvelope的setOutputSoapObject()方法,或者直接对bodyOut属性赋值,将前两步创建的SoapObject对象设置为SoapSerializationEnvelope的传出SOAP消息体
e)创建HttpTransportSE对象,该操作用于调用WebService时信息的载体,客户端需要传入的参数通过SoapSerializationEnvelope对象的bodyOut属性传给服务器,服务器响应生产的SOAP消息也通过这个对象的bodyIn属性来获取
f)调用HttpTransportSE的call方法,并且以SoapSerializationEnvelope的对象作为参数调用远程WebService
g)调用完成后,访问bodyIn方法,返回一个SoapObject对象,该对象代表了WebService的返回消息。解析该对象,就可以获取WebService的返回值
(4)Android客户端程序正常运行后,在PC机D:/images文件下面就会出现android 中/mnt/sdcard的对应的图片。
(5)调试过程中经常遇到一个
1)创建webservice是出现下面的错误
警告: Unable to find required classes (javax.activation.DataHandler and javax.mail.internet.MimeMultipart). Attachment support is disabled.
2011-5-3 14:47:09 org.apache.axis.InternalException <init>
严重: Exception:
java.lang.Exception: Couldn't find a matching Java operation for WSDD operation "updateImage" (2 args)
at org.apache.axis.InternalException.<init>(InternalException.java:71)
at org.apache.axis.description.JavaServiceDesc.loadServiceDescByIntrospection(JavaServiceDesc.java:902)
at org.apache.axis.providers.java.JavaProvider.initServiceDesc(JavaProvider.java:477)
解决方法:定义Web端UpdateImage方法的首字母不能大写,必须为小写,修改为updateImage就可以了~
2)客户端出现下面错误
java.lang.ClassCastException: org.ksoap2.serialization.SoapPrimitive和
INFO/System.out(2185): SoapFault - faultcode: 'soapenv:Server.userException' faultstring: 'java.lang.NullPointerException' faultactor: 'null' detail: org.kxml2.kdom.Node@40662450解决放法:将SoapObject soapObject = (SoapObject) envelope.getResponse();
修改为:SoapObject result = (SoapObject)envelope.bodyIn或者
Object object = envelope.getResponse();SoapObject result = (SoapObject)
envelope.bodyIn;进行尝试
参考文章:http://blog.csdn.net/fxtxz2/article/details/7556592
(一)WebService实现图片的上传(写的很好)
http://blog.csdn.net/baolong47/article/details/6702542
(二)拍照WebService上传图片
http://blog.csdn.net/yu491290710/article/details/7900830
(三)Xfile框架实现图片上传及下载
http://blog.csdn.net/haha_mingg/article/details/6347588
(四)WebService图片下载
http://www.eoeandroid.com/thread-193882-1-1.html