eclipse使用CXF3.1.*创建webservice服务端客户端以及客户端手机APP(二)

接上篇博客,本篇博客主要包含两个内容:

4.使用Android studio创建webservice客户端APP访问服务端。

5.开发过程中可能出现的一些错误。

闲话少叙,直奔主题。

4.使用Android studio创建webservice 客户端APP访问服务端

先介绍操作,再介绍原理。

手机端运行时,必须和电脑端在同一局域网下。

使用Android studio创建一个项目,使用这个下载链接 https://storage.googleapis.com/google-code-archive-downloads/v2/code.google.com/ksoap2-android/ksoap2-android-assembly-2.4-jar-with-dependencies.jar 下载soap的jar包。

在AndroidManifest.xml中加入网络访问权限代码:

  1. <!-- 访问网络的权限 -->
  2. <uses-permission android:name="android.permission.INTERNET" />

左边列表使用project,项目名称-----app----libs,然后把上面地址下载的jar包复制进去,在jar包上右击,选择下面的add as library即可导入包。

这是我的项目目录结构图,

下面依然粘贴代码:

界面代码Activity_main.xml,只有一个输入框,一个显示textView,一个按钮,

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <LinearLayout
  3.     xmlns:android="http://schemas.android.com/apk/res/android"
  4.     xmlns:app="http://schemas.android.com/apk/res-auto"
  5.     xmlns:tools="http://schemas.android.com/tools"
  6.     android:layout_width="match_parent"
  7.     android:layout_height="match_parent"
  8.     tools:context="com.dyf.sharedpsclient.MainActivity">
  9.  
  10.     <EditText
  11.         android:id="@+id/id_et_input"
  12.         android:layout_width="148dp"
  13.         android:layout_height="wrap_content"
  14.         android:ems="10"
  15.         android:inputType="textPersonName"
  16.         />
  17.  
  18.     <TextView
  19.         android:id="@+id/id_tv_show"
  20.         android:layout_width="wrap_content"
  21.         android:layout_height="wrap_content"
  22.         android:text="Hello World!"
  23.         app:layout_constraintBottom_toBottomOf="parent"
  24.         app:layout_constraintLeft_toLeftOf="parent"
  25.         app:layout_constraintRight_toRightOf="parent"
  26.         app:layout_constraintTop_toTopOf="parent"/>
  27.  
  28.     <Button
  29.         android:id="@+id/id_btn_get"
  30.         android:layout_width="wrap_content"
  31.         android:layout_height="wrap_content"
  32.         android:text="获取信息"
  33.         tools:layout_editor_absoluteX="147dp"
  34.         tools:layout_editor_absoluteY="321dp"/>
  35.  
  36. </LinearLayout>

操作代码MainActivity.java,主要包括初始化控件,按钮的点击操作,开启新线程发送webservice请求,接收返回结果,使用Handler修改界面信息。

  1. package com.dyf.sharedpsclient;
  2.  
  3. import android.app.Activity;
  4. import android.os.Bundle;
  5. import android.os.Handler;
  6. import android.os.Message;
  7. import android.util.Log;
  8. import android.view.View;
  9. import android.widget.Button;
  10. import android.widget.EditText;
  11. import android.widget.TextView;
  12.  
  13. import org.ksoap2.SoapEnvelope;
  14. import org.ksoap2.serialization.SoapObject;
  15. import org.ksoap2.serialization.SoapSerializationEnvelope;
  16. import org.ksoap2.transport.HttpTransportSE;
  17.  
  18. public class MainActivity extends Activity implements View.OnClickListener
  19. {
  20.     private TextView tv = null;
  21.     private Button btn_Get = null;
  22.     private EditText et_Input = null;
  23.  
  24.     @Override
  25.     protected void onCreate(Bundle savedInstanceState)
  26.     {
  27.         super.onCreate(savedInstanceState);
  28.         setContentView(R.layout.activity_main);
  29.         tv = (TextView) findViewById(R.id.id_tv_show);
  30.         btn_Get = (Button) findViewById(R.id.id_btn_get);
  31.         et_Input = (EditText) findViewById(R.id.id_et_input);
  32.         //直接调用webservice中的getParklotName方法
  33.         btn_Get.setOnClickListener(this);
  34.     }
  35.  
  36.     private String callService()
  37.     {
  38.         //命名空间
  39.         String nameSpace = "http://dao.diy.com";
  40.         //serviceURL
  41.         String serviceURL = "http://10.201.23.77:8080/webservice";
  42.         //调用的方法名称
  43.         String methodName = "sayHello";
  44.         //创建HttpTransportSE传输对象
  45.         HttpTransportSE transport = new HttpTransportSE(serviceURL);
  46.         //transport.debug = true;
  47.  
  48.         //使用Soap1.1创建SoapSerializationEnvelope对象
  49.         SoapSerializationEnvelope envelop = new SoapSerializationEnvelope(SoapEnvelope.VER11);
  50.         //实例化SoapObject对象
  51.         SoapObject request = new SoapObject(nameSpace, methodName);
  52.         String soapAction = nameSpace +"/"+ methodName;
  53.         String inputText = et_Input.getText().toString();
  54.         Log.i("inputText:",inputText);
  55.         request.addProperty("arg0", inputText);
  56.         envelop.dotNet = true;
  57.         envelop.bodyOut = request;
  58.         envelop.setOutputSoapObject(request);
  59.         envelop.encodingStyle = "UTF-8";
  60.         //调用webservice
  61.         try
  62.         {
  63.             transport.call(soapAction, envelop);
  64.             Log.i("envelop.getresponse:", envelop.getResponse().toString());
  65.             if (envelop.getResponse().toString() != null)
  66.             {
  67.                 SoapObject result = (SoapObject) envelop.bodyIn;
  68.                 String word = result.getProperty(0).toString();
  69.                 return word;
  70.                 //tv.setText(word);
  71.             }
  72.         } catch (Exception e)
  73.         {
  74.             Log.i("调用webservice出错:",e.toString());
  75.             e.printStackTrace();
  76.             return "no";
  77.         }
  78.         return null;
  79.     }
  80.  
  81.     //定义Handler对象
  82.     private Handler handler = new Handler(){
  83.  
  84.         @Override
  85.         public void handleMessage(Message msg)
  86.         {
  87.             String str= null;
  88.             switch (msg.what)
  89.             {
  90.                 case 1:
  91.                     str = msg.obj.toString();
  92.                     tv.setText(str);
  93.             }
  94.         }
  95.     };
  96.  
  97.     /**
  98.      * Called when a view has been clicked.
  99.      *
  100.      * @param v The view that was clicked.
  101.      */
  102.     @Override
  103.     public void onClick(View v)
  104.     {
  105.         switch (v.getId())
  106.         {
  107.             case R.id.id_btn_get:
  108.                 new Thread() {
  109.                     @Override
  110.                     public void run() {
  111.                         // 你要执行的方法
  112.                         Log.i("tag","new thread");
  113.                         Message message = new Message();
  114.                         message.what = 1;
  115.                         message.obj = callService();
  116.                         Log.i("message.what", String.valueOf(message.what));
  117.                         Log.i("message.obj",message.obj.toString());
  118.                         // 执行完毕后给handler发送消息
  119.                         handler.sendMessage(message);
  120.                     }
  121.                 }.start();
  122.                 break;
  123.         }
  124.     }
  125. }

运行之后的结果:左边是软件一进入的界面,右边是输入框输入之后,点击获取信息按钮,然后显示服务端返回的内容。

下面介绍一下这个程序中的代码。

按照程序流程一步步进行,首先是103行的点击按钮的click事件,定义一个Message对象,接收返回结果使用,115行的message.obj = callService();使用callService方法,得到服务端返回结果,然后由handler发送消息,82行判断之后,修改主界面信息。其中callService方法是一个主要过程,下面重点说明一下。

首先39行声明命名空间nameSpace,值就是服务器端提供服务接口所在包倒写,最后不加 "/" ,否则下面运行时eclipse服务端会报 下面这个错误,(主要看第二行,楼主就在这个地方坑了两天)

  1. 警告: Interceptor for {http://dao.diy.com}SayHelloService#{http://dao.diy.com}sayHello has thrown exception, unwinding now
  2. org.apache.cxf.interceptor.Fault: Unexpected wrapper element {http://dao.diy.com/}sayHello found. Expected {http://dao.diy.com}sayHello.
  3.    at org.apache.cxf.wsdl.interceptors.DocLiteralInInterceptor.handleMessage(DocLiteralInInterceptor.java:107)
  4.    at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:308)
  5.    at org.apache.cxf.transport.ChainInitiationObserver.onMessage(ChainInitiationObserver.java:121)
  6.    at org.apache.cxf.transport.http.AbstractHTTPDestination.invoke(AbstractHTTPDestination.java:267)
  7.    at org.apache.cxf.transport.http_jetty.JettyHTTPDestination.doService(JettyHTTPDestination.java:234)
  8.    at org.apache.cxf.transport.http_jetty.JettyHTTPHandler.handle(JettyHTTPHandler.java:76)
  9.    at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1129)
  10.    at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1065)
  11.    at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141)
  12.    at org.eclipse.jetty.server.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:215)
  13.    at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:97)
  14.    at org.eclipse.jetty.server.Server.handle(Server.java:499)
  15.    at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:311)
  16.    at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:258)
  17.    at org.eclipse.jetty.io.AbstractConnection$2.run(AbstractConnection.java:544)
  18.    at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:635)
  19.    at org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:555)
  20.    at java.lang.Thread.run(Thread.java:745)

然后41行定义服务访问的serviceURL,值就是服务端发布时的发布地址,结尾不要加 "/" ,不加 "?wsdl"。

43行定义调用的方法名称,注意名称和大小写别写错。

52行的soapAction ,注意是nameSpace+"/"+methodName,别忘了这个 "/" ,如果没有,服务端控制台那里报错,会打出这个soapaction,自己一看就明白了。

55行的request.addProperty(key ,value),这句是添加参数的,因为上面的sayHello方法只有一个参数,所以这里写了一次,如果有多个参数,则这里写对应个数的参数即可。

63行发起请求。

65行判断返回值不为空的情况,在67行可能会出现一个问题,使用SoapObject类时,Android studio控制台可能会报

java.lang.ClassCastException: org.ksoap2.serialization.SoapPrimitive cannot be cast to org.ksoap2.serialization.SoapObject , 类转换错误,出现这个错误的话,把SoapObject改为Object就可以了,网上有人说是版本的问题,楼主也不是很清楚,但是如果出现这个错误,改为Object就可以了。

另外67行还有一个坑,有的使用envelop.getResponse() 的时候,也可能会报错,改为使用 envelop.bodyIn即可。

上面就是Android studio主要代码中的一些说明了。

下面是项目中,可能会遇到的一些错误。

5.开发过程中可能会出现的一些错误

(1)java.lang.ClassCastException: org.ksoap2.serialization.SoapPrimitive,类转换错误。

参考: https://www.cnblogs.com/gushandujian/p/3495191.html

http://blog.csdn.net/whybiang/article/details/6533051 ,解释很详细,感谢作者。

在服务器端返回值是String类型的数值的时候使用SoapObject soapObject = (SoapObject) envelope.getResponse();和 SoapObject result = (SoapObject)envelope.bodyIn;这两种方法来接受值都会报出 java.lang.ClassCastException: org.ksoap2.serialization.SoapPrimitive这样的错误。 我们可以使用 Object object = (Object)envelope.getResponse();就可以解决这种错误。

(2)org.apache.cxf.interceptor.Fault: The given SOAPAction http://wsservice.abc.com/icService does not match an operation. 或者是 org.apache.cxf.interceptor.Fault: Unexpected wrapper element {http://wsservice.abc.com}icService found. Expected {http://wsservice.abc.com/}icService.

参考: http://www.yyjjssnn.cn/articles/706.html ,解释很详细,感谢作者。

这两种错误都是因为服务端编写时,没有在服务和方法上加入或者编写注解不对导致的,请详细查看注解是否正确,以及网页中的wsdl 描述的soapaction是否正确,详细可以查看我的上一篇博客,查看webservice服务端代码如何编写。

新增demo源码下载地址:链接:https://pan.baidu.com/s/1sm1w3ud  密码:0n40,链接失效的话,请评论区留言个人百度账号,给你分享一下。

由于编者水平有限,文章中如有不妥之处或者有什么疑问,可直接在下面评论指出,不胜感激。

eclipse使用CXF3.1.*创建webservice服务端客户端以及客户端手机APP(二)的更多相关文章

  1. eclipse使用CXF3.1.*创建webservice服务端客户端以及客户端手机APP(一)

    eclipse使用CXF3.1.*创建webservice服务端客户端以及客户端手机APP(一) 本篇博客主要包含五个内容: 1.CXF换将搭建以及eclipse配置CXF. 2.eclipse创建w ...

  2. MyEclipse创建WebService服务端和客户端

    1.新建立一个javaWeb项目,一个java类,如图: 2.接下来我们就要将项目中的TestService的这个类生成WebService服务端,选择new Web Service,如图: Next ...

  3. IDEA创建WebService服务端与客户端

    创建服务端 一.file–>new–>project 二.点击next后输入服务端名,点击finish,生成目录如下 三.在 HelloWorld.Java 文件中右击,选 Tools 的 ...

  4. idea创建WebService服务端和客户端

    创建服务端 1.file–>new–>project 2.点击next后输入服务端名,点击finish,生成目录如下 3.在 HelloWorld.Java 文件中右击,选 WebServ ...

  5. 通过jaxws-ri创建webservice服务端和客户端

    1. 获得开发包 当然是到 SUN 的开发网站下载 JAX-WS RI,或者下载我的网盘备份 ,下载下来的只是一个jar包,参考官网上的方法在命令行调用:java -jar JAXWS2.1.2-20 ...

  6. 用cxf创建webservice服务端

    用cxf创建webservice 1:在eclipse里面创建动态web工程,注意,Dynamic web module version取2.5,3.0未测试过待验证: 2:下载cxf相关的jar包, ...

  7. DelphiXE7中创建WebService(服务端+客户端)

    相关资料: http://www.2ccc.com/news/Html/?1507.html http://www.dfwlt.com/forum.php?mod=viewthread&tid ...

  8. DelphiXE7中创建WebService(服务端+客户端) good

    相关资料:http://www.2ccc.com/news/Html/?1507.html DelphiXE7新建WebService具体操作:1.打开“DelphiXE7”->“File”-& ...

  9. Axis2创建WebService服务端接口+SoupUI以及Client端demo测试调用

    第一步:引入axis2相关jar包,如果是pom项目,直接在pom文件中引入依赖就好 <dependency> <groupId>org.apache.axis2</gr ...

随机推荐

  1. linux 常用命令集合-命令导图

    这几天画了几张导图,自己熟悉命令,并记录总结一下,还有很多没写上去,在慢慢完善把. 1.帮助命令 2.文件搜索命令 3.用户管理 4.权限管理 5.文件处理类 6.压缩解压 7.网络配置类 8.关机重 ...

  2. [转]Cordova Android 返回键拦截(backbutton)和退出(再点击一次跳出)

    本文转自:https://blog.csdn.net/aierJun/article/details/53944061 在Android原生webview里重写onBackPressed()就可以.@ ...

  3. [转]php hash_pbkdf2 和 node.js crypto.pbkdf2

    http://php.net/manual/en/function.hash-pbkdf2.php https://nodejs.org/api/crypto.html#crypto_crypto_p ...

  4. 第一册:lesson twenty seven。

    原文 :Mrs.smith's living room. Mrs.smith's living room is large. There is a television in the room. Th ...

  5. .net 模拟登陆 post https 请求跳转页面

    AllowAutoRedirect property is true, the Referer property is set automatically when the request is re ...

  6. aspx 页面中 js 引用与页面后台的数据交互 --【 js 调后台】

    后台调用 js 方法 前台调用后台方法与变量:  后台被调用的方法必须是public 或 protected 后台被调用的方法必须是静态的static 方法一:通过WebService来实现 步骤: ...

  7. Java爬虫框架Jsoup学习记录

    Jsoup的作用 当你想获得某网页的内容,可以使用此框架做个爬虫程序,爬某图片网站的图片(先获得图片地址,之后再借助其他工具下载图片)或者是小说网站的小说内容 我使用Jsoup写出的一款小说下载器,小 ...

  8. WORLD F4快捷重复上一步操作

    只需做一次动作,后面就直接按F4即可重复上一次操作.

  9. frontpage 2010.2003绿色版

    基本简介 frontpage网页设计软件是微软公司出品的一款网站制作入门级软件.frontpage制作网站软件使用方便简单,会用Word就能做网页,微软在2006年年底前将停止提供FrontPage软 ...

  10. Ehcache配置详解及CacheManager使用

    <?xml version="1.0" encoding="UTF-8"?><ehcache xmlns:xsi="http://w ...