参考网站:http://www.blogjava.net/zhuyongjp/archive/2009/02/23/256296.html(webservice大讲堂)
参考:http://www.cnblogs.com/linjiqin/archive/2011/07/05/2098316.html
services.xml详解http://paggywong.iteye.com/blog/1350448
axis2+spring集成
1、新建一个web project项目,最终工程目录如下:
2、添加所需1.4.1jar
1.5.6jar需要的jar包 。最好用这个版本,1.4.1和1.6.2集成在web项目里,项目会出现内存溢出情况(甚至启动的时候就会溢出)
activation-1.1.jar ,
axiom-api-1.2.12.jar,
axiom-impl-1.2.12.jar,
axis2-adb-1.5.6.jar,
axis2-adb-codegen-1.5.6.jar,
axis2-kernel-1.5.6.jar
axis2-spring-1.5.6.jar,
axis2-transport-http-1.5.6.jar,
axis2-transport-local-1.5.6.jar,
commons-codec-1.3.jar,
commons-httpclient-3.1.jar
httpcore-4.0.jar,
httpcore-4.0.jar,
neethi-2.0.5.jar,
woden-api-1.0M8.jar,
woden-api-1.0M8.jar,
wsdl4j-1.6.2.jar,
wstx-asl-3.2.9.jar
XmlSchema-1.4.3.jar
3、接口HelloWorld
package com.ljq.service;public interface HelloWorld { public String greeting(String name); public String print();}//@WebParam(name = "datatype") String datatype//当访问service地址时,浏览器显示的方法参数默认不是项目指定的名字,是axi2自动给生成的参数名,例如(arg0,arg1),//给接口参数加上这个注解就会显示定义的参数名
4、接口实现类HelloWorldBean
package com.ljq.service; public class HelloWorldBean implements HelloWorld { public String greeting(String name) { return " 你好 " + name; } public String print() { return " 我叫林计钦 " ; } }
5、webservice类HelloWorldWebService
package com.ljq.service; import org.apache.axis2.AxisFault; import org.apache.axis2.ServiceObjectSupplier; import org.apache.axis2.description.AxisService; import org.apache.axis2.description.Parameter; import org.apache.axis2.i18n.Messages; import org.springframework.beans.BeansException; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; /** * 可能出现Axis2 spring bean not found 或者 Spring applicationContext not found。 * * 解决办法:构建自己的ServiceObjectSupplier,实现接口ServiceObjectSupplier,同时也实现Spring的ApplicationContextAware接口 * * * @author Administrator * */ public class HelloWorldWebService implements ServiceObjectSupplier, ApplicationContextAware { private static ApplicationContext ctx; public Object getServiceObject(AxisService axisService) throws AxisFault { Parameter springBeanName = axisService.getParameter( " SpringBeanName " ); String beanName = ((String) springBeanName.getValue()).trim(); if (beanName != null ) { if (ctx == null ) throw new AxisFault( " applicationContext is NULL! " ); if (ctx.getBean(beanName) == null ) throw new AxisFault( " Axis2 Can't find Spring Bean: " + beanName); return ctx.getBean(beanName); } else { throw new AxisFault(Messages.getMessage( " paramIsNotSpecified " , " SERVICE_SPRING_BEANNAME " )); } } public void setApplicationContext(ApplicationContext ctx) throws BeansException { this .ctx = ctx; } }
6、配置web.xml文件
<? xml version="1.0" encoding="UTF-8" ?> < web-app version ="2.5" xmlns ="http://java.sun.com/xml/ns/javaee" xmlns:xsi ="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation ="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" > <!-- 添加spring监听器 --> < listener > < listener-class > org.springframework.web.context.ContextLoaderListener </ listener-class > </ listener > <!-- 加载spring的配置文件 --> < context-param > < param-name > contextConfigLocation </ param-name > < param-value > /WEB-INF/applicationContext.xml </ param-value > </ context-param > <!-- 注册axis2的servlet --> < servlet > < servlet-name > AxisServlet </ servlet-name > < servlet-class > org.apache.axis2.transport.http.AxisServlet </ servlet-class > < load-on-startup > 1 </ load-on-startup > </ servlet > < servlet-mapping > < servlet-name > AxisServlet </ servlet-name > < url-pattern > /services/* </ url-pattern > </ servlet-mapping > < welcome-file-list > < welcome-file > index.jsp </ welcome-file > </ welcome-file-list > </ web-app >
7、在WEB-INF目录下配置applicationContext.xml(不存在则自己创建)
<? xml version="1.0" encoding="UTF-8" ?> <! DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd" > < beans > < bean id ="applicationContext" class ="org.apache.axis2.extensions.spring.receivers.ApplicationContextHolder" /> < bean id ="helloWorld" class ="com.ljq.service.HelloWorldBean" ></ bean > </ beans >
8、在WEB-INF\services\axis\META-INF\目录下配置services.xml(不存在则自己创建,(META-INF名字最好一样))
<? xml version="1.0" encoding="UTF-8" ?> < service name ="hwWebService" > < description > axis2与spring集成案例 </ description ><!-- <parameter name="ServiceClass"> com.roiland.cms.pxd.audiService</parameter> 接口类,这个不写也可以,但是客户端根据地址编译的时候会少一个类报错 --> <!-- 通过ServiceObjectSupplier参数指定SpringServletContextObjectSupplier类来获得Spring的ApplicationContext对象 --> < parameter name ="ServiceObjectSupplier" > org.apache.axis2.extensions.spring.receivers.SpringAppContextAwareObjectSupplier </ parameter > <!-- SpringBeanName固定的不能改 helloWorld是spring中注册的实现类得id --> < parameter name ="SpringBeanName" > helloWorld </ parameter > <!-- 在这里最值得注意的是<messageReceivers>元素,该元素用于设置处理WebService方法的处理器。 例如,getGreeting方法有一个返回值,因此,需要使用可处理输入输出的RPCMessageReceiver类, 而update方法没有返回值,因此,需要使用只能处理输入的RPCInOnlyMessageReceiver类。 --> < messageReceivers > < messageReceiver mep ="http://www.w3.org/2004/08/wsdl/in-only" class ="org.apache.axis2.rpc.receivers.RPCInOnlyMessageReceiver" /> < messageReceiver mep ="http://www.w3.org/2004/08/wsdl/in-out" class ="org.apache.axis2.rpc.receivers.RPCMessageReceiver" /> </ messageReceivers > </ service >
9、同时创建两个接口地址
<?xml version="1.0" encoding="UTF-8"?> <serviceGroup> <service name="AudiWebService"> <description>axis2与spring集成案例</description> <!-- <parameter name="ServiceClass"> com.roiland.cms.pxd.audiService</parameter> 接口类 --> <!-- 通过ServiceObjectSupplier参数指定SpringServletContextObjectSupplier类来获得Spring的ApplicationContext对象 --> <parameter name="ServiceObjectSupplier"> org.apache.axis2.extensions.spring.receivers.SpringAppContextAwareObjectSupplier </parameter> <!-- audiserviceimpl是spring中注册的实现类得id --> <parameter name="SpringBeanName">audiserviceimpl</parameter> <!-- 在这里最值得注意的是<messageReceivers>元素,该元素用于设置处理WebService方法的处理器。 例如,getGreeting方法有一个返回值,因此,需要使用可处理输入输出的RPCMessageReceiver类, 而update方法没有返回值,因此,需要使用只能处理输入的RPCInOnlyMessageReceiver类。 --> <messageReceivers> <messageReceiver mep="http://www.w3.org/2004/08/wsdl/in-only" class="org.apache.axis2.rpc.receivers.RPCInOnlyMessageReceiver" /> <messageReceiver mep="http://www.w3.org/2004/08/wsdl/in-out" class="org.apache.axis2.rpc.receivers.RPCMessageReceiver" /> </messageReceivers> </service> <service name="AudiWapService"> <description>axis2与spring集成案例</description> <!-- <parameter name="ServiceClass"> com.roiland.cms.pxd.audiService</parameter> 接口类 --> <!-- 通过ServiceObjectSupplier参数指定SpringServletContextObjectSupplier类来获得Spring的ApplicationContext对象 --> <parameter name="ServiceObjectSupplier"> org.apache.axis2.extensions.spring.receivers.SpringAppContextAwareObjectSupplier </parameter> <!-- audiserviceimpl是spring中注册的实现类得id --> <parameter name="SpringBeanName">audiserviceimpl</parameter> <!-- 在这里最值得注意的是<messageReceivers>元素,该元素用于设置处理WebService方法的处理器。 例如,getGreeting方法有一个返回值,因此,需要使用可处理输入输出的RPCMessageReceiver类, 而update方法没有返回值,因此,需要使用只能处理输入的RPCInOnlyMessageReceiver类。 --> <messageReceivers> <messageReceiver mep="http://www.w3.org/2004/08/wsdl/in-only" class="org.apache.axis2.rpc.receivers.RPCInOnlyMessageReceiver" /> <messageReceiver mep="http://www.w3.org/2004/08/wsdl/in-out" class="org.apache.axis2.rpc.receivers.RPCMessageReceiver" /> </messageReceivers> </service> </serviceGroup>
axis2+spring集成到此已经开发完成,接下把工程部署到tomcat,
然后通过http://localhost:8083/axis2spring/services/hwWebService?wsdl访问
=========================================
在webroot根下新建一个JSP:/项目名/WebRoot(webapp)/axis2-web/listServices.jsp(目录)
- <%@
- page contentType="text/html;charset=UTF-8" language="java"
- %><%@
- page import="org.apache.axis2.Constants,
- org.apache.axis2.description.AxisOperation,
- org.apache.axis2.description.AxisService,
- java.util.Collection,
- java.util.HashMap,
- java.util.Iterator"
- %><html>
- <head><title>List Services</title>
- <style>
- h2{margin:20 0 5 0;}
- ul{margin-top:5;}
- </style>
- </head>
- <body>
- <h1>Available services</h1>
- <%
- HashMap serviceMap = (HashMap) request.getSession().getAttribute(Constants.SERVICE_MAP);
- Collection servicecol = serviceMap.values();
- if(servicecol.size()==0){%>Available services is Empty.<%}
- for (Iterator iterator = servicecol.iterator(); iterator.hasNext();) {
- AxisService axisService = (AxisService) iterator.next();
- Iterator opItr = axisService.getOperations();
- String serviceName = axisService.getName();
- %>
- <h2><font color="blue"><a href="<%=serviceName %>?wsdl" target="_blank"><%=serviceName%></a></font></h2>
- <i>Available Operations</i>
- <ul>
- <%
- while (opItr.hasNext()) {
- AxisOperation axisOperation = (AxisOperation) opItr.next();
- %><li><%=axisOperation.getName().getLocalPart()%></li><%
- }
- %>
- </ul>
- <%
- }
- %>
- </body>
- </html>
部署至tomcat,然后访问:
http://localhost:8080/ws-sample/services/listServices
如果不出差错的话,可以看到发布的接口名称
String url = "http://192.168.203.131:8080/serviceapp/services/tokenService?wsdl";
// 使用RPC方式调用WebService
RPCServiceClient serviceClient = new RPCServiceClient();
// 指定调用WebService的URL
EndpointReference targetEPR = new EndpointReference(url);
Options options = serviceClient.getOptions();
//确定目标服务地址
options.setTo(targetEPR);
//确定调用方法 ,update是方法名
options.setAction("urn:update");
/**
* 指定要调用的getPrice方法及WSDL文件的命名空间
* 如果 webservice 服务端由axis2编写
* 命名空间 不一致导致的问题
* org.apache.axis2.AxisFault: java.lang.RuntimeException: Unexpected subelement arg0
*/
//此处的 第一个参数就是访问http://192.168.203.131:8080/serviceapp/services/tokenService?wsdl时,
//最上面显示的targetNamespace里的东西,targetNamespace="http://service.serviceapp.roiland.com"
//第二个参数就是方法名称,跟上面的一样
QName qname = new QName("http://service.serviceapp.roiland.com", "update");
// 指定getPrice方法的参数值
//如果没有参数,就给空,有几个参数就写几个
Object[] parameters = new Object[] {"liu","23"};
// 指定getPrice方法返回值的数据类型的Class对象
// 如果反回的不是实体类,那么返回什么类型,就写什么类型.class
// 返回实体类型,就实体类.class
Class[] returnTypes = new Class[] {String.class};
// 调用方法一 传递参数,调用服务,获取服务返回结果集
/* OMElement element = serviceClient.invokeBlocking(qname, parameters);
//值得注意的是,返回结果就是一段由OMElement对象封装的xml字符串。
//我们可以对之灵活应用,下面我取第一个元素值,并打印之。因为调用的方法返回一个结果
String result = element.getFirstElement().getText();
System.out.println(result); */
// 调用方法二 getPrice方法并输出该方法的返回值
Object[] response = serviceClient.invokeBlocking(qname, parameters, returnTypes);
String r = (String) response[0];
// RoilandCmsTopicAndModel r = (RoilandCmsTopicAndModel) response[0];
System.out.println(r);
serviceClient.cleanupTransport();//释放资源必须有
<span style="white-space:pre"> </span>