Java WebService 教程系列之 Spring 整合 CXF
Java WebService 教程系列之 Spring 整合 CXF
一、引入 jar 包
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-frontend-jaxws</artifactId>
<version>3.1.8</version>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-transports-http</artifactId>
<version>3.1.8</version>
</dependency>
二、创建服务器端程序
1.1 创建接口
@WebService
public interface HelloWebService {
String sayHello();
String sayWait();
}
1.2 接口实现类
@WebService(endpointInterface= "com.github.binarylei.webservice.test1.HelloWebService", serviceName="HelloWebService")
public class HelloWebServiceImpl implements HelloWebService {
@Override
public String sayHello() {
System.out.println("hello world!");
return "hello, binarylei";
}
@Override
public String sayWait() {
try {
Thread.sleep(1000 * 10);
} catch (InterruptedException e) {
e.printStackTrace();
}
return "please, wait me";
}
}
1.3 Spring 配置文件 spring-context-cxf.xml
<?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-2.5.xsd
http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd">
<bean id="jaxWsServiceFactoryBean" class="org.apache.cxf.jaxws.support.JaxWsServiceFactoryBean">
<property name="wrapped" value="true" />
</bean>
<jaxws:endpoint id="serviceimpl" address="/HelloWebService"
implementor="com.github.binarylei.webservice.test1.HelloWebServiceImpl">
<jaxws:serviceFactory>
<ref bean="jaxWsServiceFactoryBean" />
</jaxws:serviceFactory>
</jaxws:endpoint>
</beans>
1.4 配制 web.xml
在 web.xml 中添加如下配制:
<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>/service/*</url-pattern>
</servlet-mapping>
1.4 启动 web 工程
访问 http://localhost:8080/service/ 时,这时浏览器页面会出现:

三、创建客户端程序
public static void main(String[] args) {
JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean();
factory.setServiceClass(MyWebService.class);
factory.setAddress("http://localhost:8080/service/MyWebService");
MyWebService service = (MyWebService)factory.create();
// 返回 "hello, binarylei"
System.out.println(service.sayHello());
}
若服务无法访问,会抛出 javax.xml.ws.WebServiceException 的异常。
四、客户端超时设置
在使用网络服务时,通常需要为客户端设置请求超时时间,以避免长时间的去连接不可用的服务器。在 CXF 环境中,客户端可以通过两个参数配置超时限制。
下面主要介绍 CXF WebService 客户端如何设置超时时间,以及相关参数的介绍。
public static void main(String[] args) {
JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean();
factory.setServiceClass(MyWebService.class);
factory.setAddress("http://localhost:8080/service/MyWebService");
MyWebService service = (MyWebService)factory.create();
// 设置客户端的配置信息,超时等.
Client client = ClientProxy.getClient(service);
HTTPConduit http = (HTTPConduit) client.getConduit();
HTTPClientPolicy policy = new HTTPClientPolicy();
policy.setConnectionTimeout(10000); // 连接超时时间
policy.setReceiveTimeout(5000); // 请求超时时间.
http.setClient(policy);
long startTime = System.currentTimeMillis();
try {
service.sayHello();
} catch (Exception e) {
System.out.println(e.getClass().getName());
if (e.getCause() instanceof SocketTimeoutException) {
System.out.println("响应超时");
} else if (e.getCause() instanceof ConnectException) {
System.out.println("不能连接");
} else {
System.out.println("未知错误");
}
}
System.out.println(System.currentTimeMillis() - startTime);
}
超时主要有两个配置:
ConnectionTimeout: WebService 是基于 TCP 连接的,因此这个属性可以理解为设置 TCP 握手时间,若超出这个时间就认为连接超时。默认的时间单位是毫秒,默认设置是 30000 毫秒,即30秒。ReceiveTimeout: 这个属性表示发送 WebService 请求后所等待响应的时间,若超过设置的时间则认为超时。默认的时间单位是毫秒,默认设置是 60000 毫秒,即60秒。
五、踩过的坑
5.1 No bean named 'cxf' is defined
javax.servlet.ServletException: Servlet.init() for servlet [CXFServlet] threw exception
org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:478)
org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:81)
org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:650)
org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:342)
org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:803)
org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:868)
org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1459)
org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
java.lang.Thread.run(Thread.java:745)
Root Cause
org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'cxf' is defined
org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeanDefinition(DefaultListableBeanFactory.java:698)
org.springframework.beans.factory.support.AbstractBeanFactory.getMergedLocalBeanDefinition(AbstractBeanFactory.java:1175)
org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:284)
org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202)
org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1060)
org.apache.cxf.transport.servlet.CXFServlet.loadBus(CXFServlet.java:80)
org.apache.cxf.transport.servlet.CXFNonSpringServlet.init(CXFNonSpringServlet.java:77)
org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:478)
org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:81)
org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:650)
org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:342)
org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:803)
org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:868)
org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1459)
org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
java.lang.Thread.run(Thread.java:745)
最后发现没有在 web.xml 中加载 spring-context-cxf.xml ,真是自己坑了自己。
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring-context.xml</param-value>
</context-param>
5.2 java.lang.AbstractMethodError: org.apache.xerces.dom.DeferredDocumentImpl.setXmlStandalone
方法具体的服务(http://localhost:8080/service/HelloWebService?wsdl)时报以下 bug:
javax.servlet.ServletException: Servlet execution threw an exception
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
Root Cause
java.lang.AbstractMethodError: org.apache.xerces.dom.DeferredDocumentImpl.setXmlStandalone(Z)V
org.apache.cxf.frontend.WSDLGetUtils.updateDoc(WSDLGetUtils.java:301)
org.apache.cxf.frontend.WSDLGetUtils.writeWSDLDocument(WSDLGetUtils.java:674)
org.apache.cxf.frontend.WSDLGetUtils.getDocument(WSDLGetUtils.java:149)
org.apache.cxf.frontend.WSDLGetInterceptor.getDocument(WSDLGetInterceptor.java:129)
org.apache.cxf.frontend.WSDLGetInterceptor.handleMessage(WSDLGetInterceptor.java:77)
org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:308)
org.apache.cxf.transport.ChainInitiationObserver.onMessage(ChainInitiationObserver.java:121)
org.apache.cxf.transport.http.AbstractHTTPDestination.invoke(AbstractHTTPDestination.java:252)
org.apache.cxf.transport.servlet.ServletController.invokeDestination(ServletController.java:234)
org.apache.cxf.transport.servlet.ServletController.invoke(ServletController.java:208)
org.apache.cxf.transport.servlet.ServletController.invoke(ServletController.java:160)
org.apache.cxf.transport.servlet.CXFNonSpringServlet.invoke(CXFNonSpringServlet.java:180)
org.apache.cxf.transport.servlet.AbstractHTTPServlet.handleRequest(AbstractHTTPServlet.java:299)
org.apache.cxf.transport.servlet.AbstractHTTPServlet.doGet(AbstractHTTPServlet.java:223)
javax.servlet.http.HttpServlet.service(HttpServlet.java:635)
org.apache.cxf.transport.servlet.AbstractHTTPServlet.service(AbstractHTTPServlet.java:274)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
xerces jar 包冲突,我的项目中将之前想入的 xerces 注释的可以正常访问了。
<dependency>
<groupId>xerces</groupId>
<artifactId>xerces</artifactId>
<version>2.4.0</version>
</dependency>
参考:
CXF 超时设置: http://blog.csdn.net/bruce_6/article/details/48048153
CXF WebService 搭建: http://blog.csdn.net/dongdong9223/article/details/53169020
Java WebService 教程系列之 Spring 整合 CXF的更多相关文章
- Spring整合CXF,发布RSETful 风格WebService(转)
Spring整合CXF,发布RSETful 风格WebService 这篇文章是承接之前CXF整合Spring的这个项目示例的延伸,所以有很大一部分都是一样的.关于发布CXF WebServer和Sp ...
- Spring整合CXF,发布RSETful 风格WebService
原文地址:http://www.cnblogs.com/hoojo/archive/2012/07/23/2605219.html 这篇文章是承接之前CXF整合Spring的这个项目示例的延伸,所以有 ...
- Spring整合CXF之发布WebService服务
今天我们来讲下如何用Spring来整合CXF,来发布WebService服务: 给下官方文档地址:http://cxf.apache.org/docs/writing-a-service-with-s ...
- Spring整合CXF步骤,Spring实现webService,spring整合WebService
Spring整合CXF步骤 Spring实现webService, spring整合WebService >>>>>>>>>>>> ...
- Spring整合CXF webservice restful 实例
webservice restful接口跟soap协议的接口实现大同小异,只是在提供服务的类/接口的注解上存在差异,具体看下面的代码,然后自己对比下就可以了. 用到的基础类 User.java @Xm ...
- So easy Webservice 8.spring整合CXF 发布WS
1.添加jar包(cxf的jar包中包含了spring的jar包),添加spring配置文件 2.web.xml中配置CXFServlet,过滤WS服务的地址 <!-- 配置CXFServlet ...
- 浅谈WebService之JAX-RS与spring整合
背景:首先谈一下webservice: 1.Web service是一个平台独立的,低耦合的,自包含的.基于可编程的web的应用程序, 可使用开放的XML(标准通用标记语言下的一个子集)标准来描述.发 ...
- Java开发学习(十四)----Spring整合Mybatis及Junit
一.Spring整合Mybatis思路分析 1.1 环境准备 步骤1:准备数据库表 Mybatis是来操作数据库表,所以先创建一个数据库及表 create database spring_db cha ...
- 【SSH框架】系列之 Spring 整合 Hibernate 框架
1.SSH 三大框架整合原理 Spring 与 Struts2 的整合就是将 Action 对象交给 Spring 容器来负责创建. Spring 与 Hibernate 的整合就是将 Session ...
随机推荐
- java开发-问题清单
本人是做Java开发的,这是我参加58,搜狐,搜狗,新浪微博,百度,腾讯文学,网易以及其他一些小的创业型公司的面试常被问的问题,当然有重复,弄清楚这些 1. junit用法,before,before ...
- selenium+python自动化90-unittest多线程执行用例
前言 假设执行一条脚本(.py)用例一分钟,那么100个脚本需要100分钟,当你的用例达到一千条时需要1000分钟,也就是16个多小时... 那么如何并行运行多个.py的脚本,节省时间呢?这就用到多线 ...
- VisualSVN:强制必须填写日志信息
上回将到怎么修改已提交的版本日志信息,而开发项目过程中团队中总是有人忘记添加日志信息注释直接提交,这样会后期维护带来不便. 现在先演示一下效果 当直接提交一个空白日志信息时 有填写日志信息时 那怎么实 ...
- 机器学习入门-概率阈值的逻辑回归对准确度和召回率的影响 lr.predict_proba(获得预测样本的概率值)
1.lr.predict_proba(under_text_x) 获得的是正负的概率值 在sklearn逻辑回归的计算过程中,使用的是大于0.5的是正值,小于0.5的是负值,我们使用使用不同的概率结 ...
- Simple2D-18(音乐播放器)使用 bass 音频库
BASS 简介 BASS是一个在多个平台上用于软件的音频库.其目的是为开发人员提供功能强大且高效的示例流(MP3,MP2,MP1,OGG,WAV,AIFF),MOD 音乐(XM,IT,S3M,MOD ...
- fiddler 修改request请求
例:在request url后追加&test=1参数 在OnBeforeRequest函数中添加以下代码 if(oSession.uriContains("www.bing.com/ ...
- XML学习记录1-复习SAX,DOM和JAXB
对xml文档的解析常见的有JDK中的sax,dom,jaxb,stax和JAVA类库JDOM和DOM4J,下面先说说前三个. Java中解析XML的工具很多,像JDOM,DOM4J等,但Java标准库 ...
- Eclipse中Ctrl+Shift+f快捷键无效的解决方式
某天突然发现idea非常重要的快捷键ctrl+shift+f无效了,网上搜了很多都说是qq快捷键冲突,但是找了下qq快捷键却没有解决,现在给大家一个解决快捷键冲突的思路: 1.查看QQ快捷键--> ...
- 迷你MVVM框架 avalonjs 1.4.1发布
以后有关avalon的版本升级消息,全部改放到这里 重构parseHTML,让其支持xhtml 强化 ms-duplex-number拦截器 添加data-duplex-number辅助指令 值为st ...
- 迷你MVVM框架 avalonjs 学习教程14、事件绑定
之前的章节许多示例代码也或多或少地展示了如何使用ms-click来绑定事件了.能直接在模板上绑定是事件,这也是静态模板与动态绑定的一大区别.ms-click不是简单的onclick的别名,它在内部屏蔽 ...