CXF超时配备

CXF超时配置

       前段时间需要配置CXF的超时设置,看到一篇不错的文章

       Web 服务都是使用HTTP 作为传输协议,这个端口用于配置服务端、客户端在调用Web 服务时的HTTP 的相关设置,例如:超时时间,SSL 相关设置、是否启用缓存等。
(1.)客户端调用:
<http-conf:conduit name="*.http-conduit">
<http-conf:client ConnectionTimeout="5000" ReceiveTimeout="10000" />
</http-conf:conduit>
这里的*.http-conduit 是指对所有的Web 服务调用起作用,如果你想对一部分起作用,可以使用{targetNamespace}serviceName.http-conduit 来设置。http-conf:conduit 是客户端配置的*元素,它有如下几个子元素:

 元素  描述
 http-conf:client  指定HTTP 的超时时间、是否启用持续连接、ContentType 等信息
 http-conf:authorization  指定HTTP 基本验证方式的相关配置
 http-conf:proxyAuthorization  指定HTTP 基本验证方式时使用的代理服务器配置
 http-conf:tlsClientParameters  指定SSL/TLS 连接方式的配置
 http-conf:basicAuthSupplier  指定HTTP 基本验证方式的提供者信息
 http-conf:trustDecider  指定HTTP 连接的信任机制配置
上面我们配置的是客户端连接Web 服务、接收返回值的超时时间设置,CXF 的默认设置为30000ms 和60000ms。
(2.)服务端调用:
<http-conf:destination name="*.http-destination">
<http-conf:server ReceiveTimeout="10000" />
</http-conf:destination>
这里的*.http-destination 是指对所有的Web 服务发布起作用,如果你想对一部分起作用,可以使用{targetNamespace}serviceName.http-destination 来设置。http-conf:destination 是客户端配置的*元素,它有如下几个子元素:
 元素  描述
 http-conf:server  指定HTTP 的连接设置信息
 http-conf:contextMatchStrategy  指定上下文匹配策略
 http-conf:fixedParameterOrder  指定是否固定参数拍学

(3.)Java Code 调用:
如果你不使用Spring,那么使用Java Code,那么你需要借助CXF 的Front End 的API 操作。
服务端:
import org.apache.cxf.endpoint.Server;
import org.apache.cxf.frontend.ServerFactoryBean;
import org.apache.cxf.transport.http_jetty.JettyHTTPDestination;
import org.apache.cxf.transports.http.configuration.HTTPServerPolicy;
public class SoapServer {
public static void main(String[] args) {
ServerFactoryBean serverFactoryBean = new ServerFactoryBean();
serverFactoryBean.setAddress("http://127.0.0.1:8080/ws/services/helloService");
serverFactoryBean.setServiceClass(HelloServiceImpl.class);
Server server = serverFactoryBean.create();
JettyHTTPDestination destination = (JettyHTTPDestination) server.getDestination();
HTTPServerPolicy httpServerPolicy = new HTTPServerPolicy();
httpServerPolicy.setReceiveTimeout(32000);
destination.setServer(httpServerPolicy);
}
}
客户端:
import java.net.MalformedURLException;
import java.net.URL;
import java.text.ParseException;
import javax.xml.namespace.QName;
import org.apache.cxf.endpoint.Client;
import org.apache.cxf.frontend.ClientProxy;
import org.apache.cxf.transport.http.HTTPConduit;
import org.apache.cxf.transports.http.configuration.HTTPClientPolicy;
public class SoapClient {
public static void main(String[] args) throws ParseException,
HelloException, MalformedURLException {
QName qName = new QName("http://server.soap.ilkj.net/","HelloServiceImpl");
HelloServiceImplService helloServiceImplService = newHelloServiceImplService(newURL("http://127.0.0.1:8080/ws/services/helloService?wsdl"),qName);
IHelloService helloService = helloServiceImplService.getPort(IHelloService.class);
Client client = ClientProxy.getClient(helloService);
HTTPConduit http = (HTTPConduit) client.getConduit();
HTTPClientPolicy httpClientPolicy = new HTTPClientPolicy();
httpClientPolicy.setConnectionTimeout(36000);
httpClientPolicy.setReceiveTimeout(32000);
http.setClient(httpClientPolicy);
// helloService.***
}
}
使用CXF的Front End的API,你可以调用更多的方法,但是你也看到操作起来也是最繁琐的,所以除非你有必要使用CXF的这么多特性,否则不要使用这种方式来操作JAX-WS。


6.CXF的拦截器特征机制:
CXF通过拦截器(Interceptor)和特征(Feature)扩展自己的功能,例如:WS-Addressing功能使用Feature实现,日志、WS-Security使用Interceptor实现。我们也可以编写自己的拦截器注册到CXF中完成特定的功能。CXF中的所有拦截器都要实现org.apache.cxf.inrerceptor.Interceptor<T extends org.apache.cxf.message.Message>接口,Message 接口可以获得SOAP 消息的相关信息。通过查看CXF 的API 文档,你会看到CXF已经实现了很多种拦截器,很多已经在发布、访问Web 服务时已经默认添加到拦截器链。
一般情况下, 我们自己的拦截器只要继承AbstractPhaseInterceptor<T extends org.apache.cxf.message.Message>类即可,这个类可以指定继承它的拦截器在什么阶段被启用,阶段属性可以通过org.apache.cxf.phase.Phase 中的常量指定值。
例:
package net.ilkj.soap.server.interceptor;
import org.apache.cxf.interceptor.Fault;
import org.apache.cxf.message.Message;
import org.apache.cxf.phase.AbstractPhaseInterceptor;
import org.apache.cxf.phase.Phase;
public class HelloInInterceptor extends
AbstractPhaseInterceptor<Message> {
public HelloInInterceptor(String phase) {
super(phase);
}
public HelloInInterceptor() {
super(Phase.RECEIVE);//这个拦截器只在接收阶段有效
}
@Override
public void handleMessage(Message message) throws Fault {
System.out.println("*****************");
}
}
你要注意CXF 中的拦截器编写时不要只针对服务端或者客户端,应该是两者均可使用,另外名字要见名知意。例如:使用In、Out 标注这是一个输入时起作用还是输出时起作用的拦截器。上面的HelloInInterceptor 由于在构造方法中指定在接收消息阶段有效,所以即使你把它注册到OutInterceptor 的集合中也是无效的。具体关于CXF 中拦截器的内容需要时请参看
http://cwiki.apache.org/CXF20DOC/interceptors.html。
同样, 我们也可以通过继承AbstractFeature 类来实现一个新的特征, 只需要覆盖initializeProvider 方法即可。其实Feature 就是将一组拦截器放在其中,然后一并注册使用。
例:
package net.ilkj.soap.server.feature;
import org.apache.cxf.Bus;
import org.apache.cxf.feature.AbstractFeature;
import org.apache.cxf.interceptor.InterceptorProvider;
import org.apache.cxf.interceptor.LoggingInInterceptor;
import org.apache.cxf.interceptor.LoggingOutInterceptor;
public class HelloFeature extends AbstractFeature {
@Override
protected void initializeProvider(InterceptorProvider provider, Bus bus) {
provider.getInInterceptors().add(new LoggingInInterceptor());
provider.getOutInterceptors().add(new LoggingOutInterceptor());
}
}
这个特征类将日志拦截器捆绑在一起,你就可以将它注册到你要使用的地方,而不必一个一个拦截器的注册使用。
CXF 除了允许在Spring 中的配置文件、硬编码注册拦截器和特征类,也允许你是用其自带的注解@InInterceptors、@OutInterceptors、@InFaultInterceptors、@OutFaultInterceptors、@Features 来直接注册到SEI,但是不推荐你这么做,因为这样你的类中就耦合和CXF 这个
具体的JAX-WS 实现的API。

 

本文转载自:http://poorboy030103.blog.163.com/blog/static/54635147201081451324893/

 

PS: 目前通配形式的超时设置已经成功,但是仍然不知道怎么配置具体某一个webService的超时设置,希望知道的朋友告知一声,呵呵,在此谢过!