eclipse使用CXF3.1.*创建webservice服务端客户端以及客户端手机APP(二)
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中加入网络访问权限代码:
- <!-- 访问网络的权限 -->
- <uses-permission android:name="android.permission.INTERNET" />
左边列表使用project,项目名称-----app----libs,然后把上面地址下载的jar包复制进去,在jar包上右击,选择下面的add as library即可导入包。
这是我的项目目录结构图,
下面依然粘贴代码:
界面代码Activity_main.xml,只有一个输入框,一个显示textView,一个按钮,
- <?xml version="1.0" encoding="utf-8"?>
- <LinearLayout
- xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:app="http://schemas.android.com/apk/res-auto"
- xmlns:tools="http://schemas.android.com/tools"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- tools:context="com.dyf.sharedpsclient.MainActivity">
- <EditText
- android:id="@+id/id_et_input"
- android:layout_width="148dp"
- android:layout_height="wrap_content"
- android:ems="10"
- android:inputType="textPersonName"
- />
- <TextView
- android:id="@+id/id_tv_show"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="Hello World!"
- app:layout_constraintBottom_toBottomOf="parent"
- app:layout_constraintLeft_toLeftOf="parent"
- app:layout_constraintRight_toRightOf="parent"
- app:layout_constraintTop_toTopOf="parent"/>
- <Button
- android:id="@+id/id_btn_get"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="获取信息"
- tools:layout_editor_absoluteX="147dp"
- tools:layout_editor_absoluteY="321dp"/>
- </LinearLayout>
操作代码MainActivity.java,主要包括初始化控件,按钮的点击操作,开启新线程发送webservice请求,接收返回结果,使用Handler修改界面信息。
- package com.dyf.sharedpsclient;
- import android.app.Activity;
- import android.os.Bundle;
- import android.os.Handler;
- import android.os.Message;
- import android.util.Log;
- import android.view.View;
- import android.widget.Button;
- import android.widget.EditText;
- import android.widget.TextView;
- import org.ksoap2.SoapEnvelope;
- import org.ksoap2.serialization.SoapObject;
- import org.ksoap2.serialization.SoapSerializationEnvelope;
- import org.ksoap2.transport.HttpTransportSE;
- public class MainActivity extends Activity implements View.OnClickListener
- {
- private TextView tv = null;
- private Button btn_Get = null;
- private EditText et_Input = null;
- @Override
- protected void onCreate(Bundle savedInstanceState)
- {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
- tv = (TextView) findViewById(R.id.id_tv_show);
- btn_Get = (Button) findViewById(R.id.id_btn_get);
- et_Input = (EditText) findViewById(R.id.id_et_input);
- //直接调用webservice中的getParklotName方法
- btn_Get.setOnClickListener(this);
- }
- private String callService()
- {
- //命名空间
- String nameSpace = "http://dao.diy.com";
- //serviceURL
- String serviceURL = "http://10.201.23.77:8080/webservice";
- //调用的方法名称
- String methodName = "sayHello";
- //创建HttpTransportSE传输对象
- HttpTransportSE transport = new HttpTransportSE(serviceURL);
- //transport.debug = true;
- //使用Soap1.1创建SoapSerializationEnvelope对象
- SoapSerializationEnvelope envelop = new SoapSerializationEnvelope(SoapEnvelope.VER11);
- //实例化SoapObject对象
- SoapObject request = new SoapObject(nameSpace, methodName);
- String soapAction = nameSpace +"/"+ methodName;
- String inputText = et_Input.getText().toString();
- Log.i("inputText:",inputText);
- request.addProperty("arg0", inputText);
- envelop.dotNet = true;
- envelop.bodyOut = request;
- envelop.setOutputSoapObject(request);
- envelop.encodingStyle = "UTF-8";
- //调用webservice
- try
- {
- transport.call(soapAction, envelop);
- Log.i("envelop.getresponse:", envelop.getResponse().toString());
- if (envelop.getResponse().toString() != null)
- {
- SoapObject result = (SoapObject) envelop.bodyIn;
- String word = result.getProperty(0).toString();
- return word;
- //tv.setText(word);
- }
- } catch (Exception e)
- {
- Log.i("调用webservice出错:",e.toString());
- e.printStackTrace();
- return "no";
- }
- return null;
- }
- //定义Handler对象
- private Handler handler = new Handler(){
- @Override
- public void handleMessage(Message msg)
- {
- String str= null;
- switch (msg.what)
- {
- case 1:
- str = msg.obj.toString();
- tv.setText(str);
- }
- }
- };
- /**
- * Called when a view has been clicked.
- *
- * @param v The view that was clicked.
- */
- @Override
- public void onClick(View v)
- {
- switch (v.getId())
- {
- case R.id.id_btn_get:
- new Thread() {
- @Override
- public void run() {
- // 你要执行的方法
- Log.i("tag","new thread");
- Message message = new Message();
- message.what = 1;
- message.obj = callService();
- Log.i("message.what", String.valueOf(message.what));
- Log.i("message.obj",message.obj.toString());
- // 执行完毕后给handler发送消息
- handler.sendMessage(message);
- }
- }.start();
- break;
- }
- }
- }
运行之后的结果:左边是软件一进入的界面,右边是输入框输入之后,点击获取信息按钮,然后显示服务端返回的内容。
下面介绍一下这个程序中的代码。
按照程序流程一步步进行,首先是103行的点击按钮的click事件,定义一个Message对象,接收返回结果使用,115行的message.obj = callService();使用callService方法,得到服务端返回结果,然后由handler发送消息,82行判断之后,修改主界面信息。其中callService方法是一个主要过程,下面重点说明一下。
首先39行声明命名空间nameSpace,值就是服务器端提供服务接口所在包倒写,最后不加 "/" ,否则下面运行时eclipse服务端会报 下面这个错误,(主要看第二行,楼主就在这个地方坑了两天)
- 警告: Interceptor for {http://dao.diy.com}SayHelloService#{http://dao.diy.com}sayHello has thrown exception, unwinding now
- org.apache.cxf.interceptor.Fault: Unexpected wrapper element {http://dao.diy.com/}sayHello found. Expected {http://dao.diy.com}sayHello.
- at org.apache.cxf.wsdl.interceptors.DocLiteralInInterceptor.handleMessage(DocLiteralInInterceptor.java:107)
- at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:308)
- at org.apache.cxf.transport.ChainInitiationObserver.onMessage(ChainInitiationObserver.java:121)
- at org.apache.cxf.transport.http.AbstractHTTPDestination.invoke(AbstractHTTPDestination.java:267)
- at org.apache.cxf.transport.http_jetty.JettyHTTPDestination.doService(JettyHTTPDestination.java:234)
- at org.apache.cxf.transport.http_jetty.JettyHTTPHandler.handle(JettyHTTPHandler.java:76)
- at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1129)
- at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1065)
- at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141)
- at org.eclipse.jetty.server.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:215)
- at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:97)
- at org.eclipse.jetty.server.Server.handle(Server.java:499)
- at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:311)
- at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:258)
- at org.eclipse.jetty.io.AbstractConnection$2.run(AbstractConnection.java:544)
- at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:635)
- at org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:555)
- 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(二)的更多相关文章
- eclipse使用CXF3.1.*创建webservice服务端客户端以及客户端手机APP(一)
eclipse使用CXF3.1.*创建webservice服务端客户端以及客户端手机APP(一) 本篇博客主要包含五个内容: 1.CXF换将搭建以及eclipse配置CXF. 2.eclipse创建w ...
- MyEclipse创建WebService服务端和客户端
1.新建立一个javaWeb项目,一个java类,如图: 2.接下来我们就要将项目中的TestService的这个类生成WebService服务端,选择new Web Service,如图: Next ...
- IDEA创建WebService服务端与客户端
创建服务端 一.file–>new–>project 二.点击next后输入服务端名,点击finish,生成目录如下 三.在 HelloWorld.Java 文件中右击,选 Tools 的 ...
- idea创建WebService服务端和客户端
创建服务端 1.file–>new–>project 2.点击next后输入服务端名,点击finish,生成目录如下 3.在 HelloWorld.Java 文件中右击,选 WebServ ...
- 通过jaxws-ri创建webservice服务端和客户端
1. 获得开发包 当然是到 SUN 的开发网站下载 JAX-WS RI,或者下载我的网盘备份 ,下载下来的只是一个jar包,参考官网上的方法在命令行调用:java -jar JAXWS2.1.2-20 ...
- 用cxf创建webservice服务端
用cxf创建webservice 1:在eclipse里面创建动态web工程,注意,Dynamic web module version取2.5,3.0未测试过待验证: 2:下载cxf相关的jar包, ...
- DelphiXE7中创建WebService(服务端+客户端)
相关资料: http://www.2ccc.com/news/Html/?1507.html http://www.dfwlt.com/forum.php?mod=viewthread&tid ...
- DelphiXE7中创建WebService(服务端+客户端) good
相关资料:http://www.2ccc.com/news/Html/?1507.html DelphiXE7新建WebService具体操作:1.打开“DelphiXE7”->“File”-& ...
- Axis2创建WebService服务端接口+SoupUI以及Client端demo测试调用
第一步:引入axis2相关jar包,如果是pom项目,直接在pom文件中引入依赖就好 <dependency> <groupId>org.apache.axis2</gr ...
随机推荐
- 南大算法设计与分析课程OJ答案代码(1)中位数附近2k+1个数、任意两数之和是否等于给定数
问题1 用来测试的,就不说了 问题2:中位数附近2k+1个数 给出一串整型数 a1,a2,...,an 以及一个较小的常数 k,找出这串数的中位数 m 和最接近 m 的小于等于 m 的 k 个数,以及 ...
- 在go modules中使用replace替换无法直接获取的package(golang.org/x/...)
上一篇里我们介绍了使用go get进行包管理. 不过因为某些未知原因,并不是所有的包都能直接用go get获取到,这时我们就需要使用go modules的replace功能了.(当然大部分问题挂个梯子 ...
- PHP开发中bcscale timezone charset的设定
关于php的开发,有几个细节设定,需要知悉下:在项目的init.php 或 index.php 或 api.php 1. bcscale(18); 表示bc函数,默认小数点位数. 没有设定的话,默认为 ...
- 【转载】C#常用数据库Sqlserver中DATEPART() 函数
在Sqlserver数据库中,DATEPART() 函数用于返回日期/时间的单独部分,比如年.月.日.小时.分钟等等.DatePart()函数的语法为: DATEPART(datepart,date) ...
- 【转载】ASP.NET工具类:文件夹目录Directory操作工具类
在ASP.NET开发网站的过程中,有时候会涉及到文件夹相关操作,如判断文件夹目录是否存在.删除文件夹目录.创建文件.删除文件.复制文件夹等等.这一批有关文件目录的操作可以通过Directory类.Fi ...
- sql server查询语句条件判断字段值是否为NULL
判断字段是否为null select * from table where c is null select * from table where c is not null 判断字段是否为空 ...
- C# 使用 PerformanceCounter 获取 CPU 和 硬盘的使用率
C# 使用 PerformanceCounter 获取 CPU 和 硬盘的使用率: 先看界面: 建一个 Windows Form 桌面程序,代码如下: using System; using Sys ...
- 3. 原子变量-CAS算法
1. 是什么 ? 2. CAS算法模拟 package com.gf.demo03; public class TestCompareAndSwap { public static void main ...
- 【转】消除代码中的 if-else/switch-case
在很多时候,我们代码中会有很多分支,而且分支下面的代码又有一些复杂的逻辑,相信很多人都喜欢用 if-else/switch-case 去实现.做的不好的会直接把实现的代码放在 if-else/swit ...
- 递归 + OS模块
''' 递归调用 :一个函数,调用了自身,称为递归调用 递归函数:一个会调用自身的函数称为递归函数 凡是循环能干的事,递归都能干 ''' ''' 方式: 1.写出临界条件 2.找这一次和上一次的关系 ...