服务器端(spring+struts2+hibernate+cxf)
0.需要的jar包
cxf-2.5.11.jar geronimo-annotation_1.0_spec-1.1.1.jar geronimo-jaxws_2.2_spec-1.1.jar geronimo-stax-api_1.0_spec-1.0.1.jar geronimo-ws-metadata_2.0_spec-1.1.3.jar jaxb-api-2.2.5.jar jaxb-impl-2.2.5.1.jar jaxws-rt-2.1.7.jar neethi-3.0.2.jar stax2-api-2.9.9-1.jar(客户端调用时会用到,如果服务器端缺少此包会报错Could not initialize class org.apache.cxf.staxutils.StaxUtils) wsdl4j-1.6.3.jar
1.web.xml的配置
<!--cxfSerlet-->
<servlet> <servlet-name>CXFServlet</servlet-name> <servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>CXFServlet</servlet-name> <url-pattern>/ws/*</url-pattern> </servlet-mapping>
<!--struts自定义拦截器-->
<filter> <filter-name>struts2</filter-name> <filter-class>cn.ac.wti.web.interceptor.ExtendStrutsFilter</filter-class> </filter> <filter-mapping> <filter-name>struts2</filter-name> <url-pattern>/*</url-pattern> <dispatcher>REQUEST</dispatcher> <dispatcher>FORWARD</dispatcher> </filter-mapping> <listener>
2.struts2自定义拦截器
import java.io.IOException; import javax.servlet.FilterChain; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; import org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter; public class ExtendStrutsFilter extends StrutsPrepareAndExecuteFilter{ public void doFilter(ServletRequest req, ServletResponse res,FilterChain chain) throws IOException, ServletException { HttpServletRequest request = (HttpServletRequest) req; //不过滤的url,可以自行添加 if (request.getRequestURI().contains("/ws")) { //System.out.println("使用自定义的过滤器"); chain.doFilter(req, res); }else{ //System.out.println("使用默认的过滤器"); super.doFilter(request, res, chain); } } }
3.webservice接口和实现类
//接口类
package cn.cxf.demo; import javax.jws.WebService; @WebService public interface Demo { String sayHi(String text); }
//实现类
package cn.cxf.demo.impl; import javax.jws.WebService; import cn.cxf.demo.Demo; @WebService(endpointInterface="cn.cxf.demo.Demo", serviceName="DemoService", targetNamespace="http://demo.cxf.cn/") public class DemoImpl implements Demo { @Override public String sayHi(String text) { return "Hi ! " + text; } }
4.接口发布
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jaxws="http://cxf.apache.org/jaxws" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd"> <import resource="classpath:META-INF/cxf/cxf.xml" /> <import resource="classpath:META-INF/cxf/cxf-extension-soap.xml" /> <import resource="classpath:META-INF/cxf/cxf-servlet.xml" /> <!-- 接口发布 --> <jaxws:endpoint id="demoService" implementor="cn.cxf.demo.impl.DemoImpl" address="/DemoService" /> </beans>
5.测试
http://localhost:8080/项目名称/ws
注意:可能需要配置包的扫描,此处没有测试
客户端
方式一
使用myeclipse的工具生成客户端
生成的客户端如下
编写测试代码:
import org.apache.cxf.endpoint.Client; import org.apache.cxf.jaxws.endpoint.dynamic.JaxWsDynamicClientFactory; public class CXFWSTest { public static void main(String[] args) throws Exception { Demo demoImplPort = new DemoService().getDemoImplPort(); System.out.println(demoImplPort.sayHi("nihao"));; }
}
方式二
public class CXFWSTest { public static void main(String[] args) throws Exception { JaxWsDynamicClientFactory factory = JaxWsDynamicClientFactory.newInstance(); Client client = factory.createClient("http://localhost:8080/项目名称/ws/DemoService?wsdl"); Object[] objs = client.invoke("sayHi", "阿福"); System.out.println(objs[0].toString()); } }
其它异常
1.Failed to import bean definitions from relative location [applicationContext-webService.xml] 原因:缺包
2.Caused by: javax.xml.ws.WebServiceException: javax.xml.ws.WebServiceException: Attributes portName, serviceName and endpointInterface are not allowed in the @WebService annotation of an SEI.
解决方案:实现类的endpointInterface应该写的是接口的地址