因为我把自己项目的名字换成了projectName 所以如果你要运行一下代码,必须注意!
最近有一个需求。我理解的意思是在已有的项目里面写一个webservice,然后供web端、安卓端调用(ios没条件,暂时不考虑)。最终历经八十一难,还是搞定了。
1、webservice(cxf3.0.1 + jdk1.6)项目环境是springmvc+sprng+spring data jpa
1.1、首先定义一个接口,@WebService注解的属性大多不知道是什么意思,不过targetNamespace属性在后面安卓调用时候确实有用到,
@WebParam(name="distance")参数的定义最好要写,因为wsdl文件的参数会根据name属性显示
@WebService(targetNamespace="http://com.study/ws")
public interface PsI {
@WebMethod
public String getPoints(@WebParam(name="distance")String distance);
}
1.2、然后写一些接口的实现,注意实现类的@WebService的endpointInterface属性,就是定义接口的路径
@WebService(endpointInterface="x.x.PsI",serviceName="peiSong",
name="peiSong", portName="peiSong", targetNamespace="http://com.ums.study/ws")
public class PsImp implements PsI{
@Autowired
private PsService psService;
@Override
@WebMethod
public String getPoints(@WebParam(name="distance")String distance) {
system.out.println("server: " + distance);
return "hello,client";
}
}
}
@WebParam 可以让你的参数名字在wsdl文件显示出来
1.3、web.xml配置 这个没什么好说的
<servlet>
<servlet-name>cxf</servlet-name>
<servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>cxf</servlet-name>
<url-pattern>/services/*</url-pattern>
</servlet-mapping>
1.4、spring相关配置
<import resource="classpath:META-INF/cxf/cxf.xml" />
<jaxws:endpoint id="psProcess"
implementor="#psImpl" address="/ws/ps"/>
<bean id="psImpl" class="x.x.PsImp" />
很多人不知道cxf.xml在哪里。cxf core包 META-INF目录下面,不是在package里面的
另外值得注意的两个地方
(1)、jaxws:endpoint 的implementor属性要加 "#"
(2)、jaxws:endpoint 的 adress属性的配置有两种:一种绝对路径,如"http://ip:port/ws/ps" 另外一种是相对路径,如"/ws/ps"
一开始我用的是绝对路径,自己写的javaproject 或者是 web project都可以用,但是用到项目里面就不行了。琢磨了好久,修改成相对路径才成功
1.5、如果你的项目里面有一些安全框架,例如 springsecurity、apacheshiro,或许你还要过滤调一些资源,毕竟,别人调用webservice的时候肯定
不希望去做登录的都工作。我的项目里面是用的springsecurity
<beans>节点下面加上
<http pattern="/services/ws/*" security="none" />
1.6、测试
到这里,服务端的基本上已经写好了
因为我的webservice是交给spring来管理,就没有在main方法里,写一个启动服务的代码。直接启动web服务器
在浏览器输入 http://ip:port/prijectName/services/ws/ps?wsdl 出现wsdl文件,说明成功了
2、安卓调用webservice
2.1、安卓访问webservice 需要 ksoap2-android-assembly-2.6.0.jar
package com.ums.demo;
import org.ksoap2.SoapEnvelope;
import org.ksoap2.serialization.SoapObject;
import org.ksoap2.serialization.SoapSerializationEnvelope;
import org.ksoap2.transport.HttpTransportSE;
public class HttpWS {
// 声明WS的命名空间,命名空间在WSDL的头部显示
private static final String NAMESPACE = "http://com.ums.study/ws";
// 设置WS的路径
private static String SERVICEURL = "http://10.0.2.2:8080/projectName/services/ws/ps?wsdl";
public String GetWS(String methodName, String[] parames, String[] paramesKey) {
System.out.println("########################start");
// SOAP Action
String soapAction = NAMESPACE +"/"+ methodName;
// 创建SoapObject对象,并指定WebService的命名空间和调用的方法名
SoapObject request = new SoapObject(NAMESPACE, methodName);
// 生成调用WebService方法的SOAP请求信息,并指定SOAP的版本
SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(
SoapEnvelope.VER11);
if (parames != null) {
for (int i = 0; i < parames.length; i++) {
System.out.println("key: "+ paramesKey[i] + " value: "+parames[i]);
request.addProperty(paramesKey[i], parames[i]);
}
}
// 上边的一句等价于下边的这句 将SoapObject对象赋给envelope对象
envelope.bodyOut = request;
// 当前开发的是Java WSen 这里需要不调用.net WS
envelope.dotNet = false;
String res = "";
HttpTransportSE ht = new HttpTransportSE(SERVICEURL);
try {
// 请求WSz
ht.call(null, envelope);
if (envelope.getResponse() != null) {
// 获得WS函数返回值信息
res = envelope.getResponse().toString();
}
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("########################end");
return res;
}
}
这是访问工具类的代码
private static final String NAMESPACE = "http://com.ums.study/ws";
这个是 webservice接口的实现类的 targetNamespace属性的值
如果用这个代码
private static String SERVICEURL = "http://10.0.2.2:8080/projectName/services/ws/ps?wsdl";
这个projectName 必须改成自己项目的路径,而且安卓localhost 为 10.0.2.2:8080
代码在这里,如果你正在写相关代码,并且在阅读这篇文章,祝你好运!
最近有一个需求。我理解的意思是在已有的项目里面写一个webservice,然后供web端、安卓端调用(ios没条件,暂时不考虑)。最终历经八十一难,还是搞定了。
1、webservice(cxf3.0.1 + jdk1.6)项目环境是springmvc+sprng+spring data jpa
1.1、首先定义一个接口,@WebService注解的属性大多不知道是什么意思,不过targetNamespace属性在后面安卓调用时候确实有用到,
@WebParam(name="distance")参数的定义最好要写,因为wsdl文件的参数会根据name属性显示
@WebService(targetNamespace="http://com.study/ws")
public interface PsI {
@WebMethod
public String getPoints(@WebParam(name="distance")String distance);
}
1.2、然后写一些接口的实现,注意实现类的@WebService的endpointInterface属性,就是定义接口的路径
@WebService(endpointInterface="x.x.PsI",serviceName="peiSong",
name="peiSong", portName="peiSong", targetNamespace="http://com.ums.study/ws")
public class PsImp implements PsI{
@Autowired
private PsService psService;
@Override
@WebMethod
public String getPoints(@WebParam(name="distance")String distance) {
system.out.println("server: " + distance);
return "hello,client";
}
}
}
@WebParam 可以让你的参数名字在wsdl文件显示出来
1.3、web.xml配置 这个没什么好说的
<servlet>
<servlet-name>cxf</servlet-name>
<servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>cxf</servlet-name>
<url-pattern>/services/*</url-pattern>
</servlet-mapping>
1.4、spring相关配置
<import resource="classpath:META-INF/cxf/cxf.xml" />
<jaxws:endpoint id="psProcess"
implementor="#psImpl" address="/ws/ps"/>
<bean id="psImpl" class="x.x.PsImp" />
很多人不知道cxf.xml在哪里。cxf core包 META-INF目录下面,不是在package里面的
另外值得注意的两个地方
(1)、jaxws:endpoint 的implementor属性要加 "#"
(2)、jaxws:endpoint 的 adress属性的配置有两种:一种绝对路径,如"http://ip:port/ws/ps" 另外一种是相对路径,如"/ws/ps"
一开始我用的是绝对路径,自己写的javaproject 或者是 web project都可以用,但是用到项目里面就不行了。琢磨了好久,修改成相对路径才成功
1.5、如果你的项目里面有一些安全框架,例如 springsecurity、apacheshiro,或许你还要过滤调一些资源,毕竟,别人调用webservice的时候肯定
不希望去做登录的都工作。我的项目里面是用的springsecurity
<beans>节点下面加上
<http pattern="/services/ws/*" security="none" />
1.6、测试
到这里,服务端的基本上已经写好了
因为我的webservice是交给spring来管理,就没有在main方法里,写一个启动服务的代码。直接启动web服务器
在浏览器输入 http://ip:port/prijectName/services/ws/ps?wsdl 出现wsdl文件,说明成功了
2、安卓调用webservice
2.1、安卓访问webservice 需要 ksoap2-android-assembly-2.6.0.jar
package com.ums.demo;
import org.ksoap2.SoapEnvelope;
import org.ksoap2.serialization.SoapObject;
import org.ksoap2.serialization.SoapSerializationEnvelope;
import org.ksoap2.transport.HttpTransportSE;
public class HttpWS {
// 声明WS的命名空间,命名空间在WSDL的头部显示
private static final String NAMESPACE = "http://com.ums.study/ws";
// 设置WS的路径
private static String SERVICEURL = "http://10.0.2.2:8080/projectName/services/ws/ps?wsdl";
public String GetWS(String methodName, String[] parames, String[] paramesKey) {
System.out.println("########################start");
// SOAP Action
String soapAction = NAMESPACE +"/"+ methodName;
// 创建SoapObject对象,并指定WebService的命名空间和调用的方法名
SoapObject request = new SoapObject(NAMESPACE, methodName);
// 生成调用WebService方法的SOAP请求信息,并指定SOAP的版本
SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(
SoapEnvelope.VER11);
if (parames != null) {
for (int i = 0; i < parames.length; i++) {
System.out.println("key: "+ paramesKey[i] + " value: "+parames[i]);
request.addProperty(paramesKey[i], parames[i]);
}
}
// 上边的一句等价于下边的这句 将SoapObject对象赋给envelope对象
envelope.bodyOut = request;
// 当前开发的是Java WSen 这里需要不调用.net WS
envelope.dotNet = false;
String res = "";
HttpTransportSE ht = new HttpTransportSE(SERVICEURL);
try {
// 请求WSz
ht.call(null, envelope);
if (envelope.getResponse() != null) {
// 获得WS函数返回值信息
res = envelope.getResponse().toString();
}
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("########################end");
return res;
}
}
这是访问工具类的代码
private static final String NAMESPACE = "http://com.ums.study/ws";
这个是 webservice接口的实现类的 targetNamespace属性的值
如果用这个代码
private static String SERVICEURL = "http://10.0.2.2:8080/projectName/services/ws/ps?wsdl";
这个projectName 必须改成自己项目的路径,而且安卓localhost 为 10.0.2.2:8080
代码在这里,如果你正在写相关代码,并且在阅读这篇文章,祝你好运!