CXF 暴露WebService的思路,以在Jetty为Web Container为例来描述。
Demo 代码
public static void main(String[] args) {
// Create our service implementation
HelloWorldImpl helloWorldImpl = new HelloWorldImpl();
// Create our Server
ServerFactoryBean svrFactory = new ServerFactoryBean();
svrFactory.setServiceClass(HelloWorld.class);
svrFactory.setAddress("http://localhost:9000/Hello");
svrFactory.setServiceBean(helloWorldImpl);
svrFactory.create();
}
步骤:
1. ServerFactoryBean创建server,这个不是运行的server,可以成Server端Service
public Server create() {
ClassLoader orig = Thread.currentThread().getContextClassLoader();
try {
try {
if (bus != null) {
ClassLoader loader = bus.getExtension(ClassLoader.class);
if (loader != null) {
Thread.currentThread().setContextClassLoader(loader);
}
}
if (getServiceFactory().getProperties() == null) {
getServiceFactory().setProperties(getProperties());
} else if (getProperties() != null) {
getServiceFactory().getProperties().putAll(getProperties());
}
if (serviceBean != null && getServiceClass() == null) {
setServiceClass(ClassHelper.getRealClass(serviceBean));
}
if (invoker != null) {
getServiceFactory().setInvoker(invoker);
} else if (serviceBean != null) {
invoker = createInvoker();
getServiceFactory().setInvoker(invoker);
}
Endpoint ep = createEndpoint();
server = new ServerImpl(getBus(),
ep,
getDestinationFactory(),
getBindingFactory());
if (ep.getService().getInvoker() == null) {
if (invoker == null) {
ep.getService().setInvoker(createInvoker());
} else {
ep.getService().setInvoker(invoker);
}
}
} catch (EndpointException e) {
throw new ServiceConstructionException(e);
} catch (BusException e) {
throw new ServiceConstructionException(e);
} catch (IOException e) {
throw new ServiceConstructionException(e);
}
if (serviceBean != null) {
Class<?> cls = ClassHelper.getRealClass(getServiceBean());
if (getServiceClass() == null || cls.equals(getServiceClass())) {
initializeAnnotationInterceptors(server.getEndpoint(), cls);
} else {
initializeAnnotationInterceptors(server.getEndpoint(), cls, getServiceClass());
}
} else if (getServiceClass() != null) {
initializeAnnotationInterceptors(server.getEndpoint(), getServiceClass());
}
applyFeatures();
getServiceFactory().sendEvent(FactoryBeanListener.Event.SERVER_CREATED, server, serviceBean,
serviceBean == null
? getServiceClass() == null
? getServiceFactory().getServiceClass()
: getServiceClass()
: getServiceClass() == null
? ClassHelper.getRealClass(getServiceBean())
: getServiceClass());
if (start) {
server.start();
}
return server;
} finally {
Thread.currentThread().setContextClassLoader(orig);
}
}
2.Server启动
public void start() {
if (!stopped) {
return;
}
LOG.fine("Server is starting.");
if (messageObserver != null) {
destination.setMessageObserver(messageObserver);
} else {
bindingFactory.addListener(destination, endpoint);
}
// register the active server to run
if (null != serverRegistry) {
LOG.fine("register the server to serverRegistry ");
serverRegistry.register(this);
}
if (slcMgr != null) {
slcMgr.startServer(this);
}
stopped = false;
}
3.SoapBindingFactory加入Listener
public synchronized void addListener(Destination d, Endpoint e) {
MessageObserver mo = d.getMessageObserver();
if (mo == null) {
super.addListener(d, e);
return;
}
3.SoapBindingFactory加入Listener
public synchronized void addListener(Destination d, Endpoint e) {
MessageObserver mo = d.getMessageObserver();
if (mo == null) {
super.addListener(d, e);
return;
}
4. AbstractBindingFactory 为Destination设置observer
public void addListener(Destination d, Endpoint e) {
ChainInitiationObserver observer = new ChainInitiationObserver(e, bus);
d.setMessageObserver(observer);
}
5.JettyHTTPDestination设置observer
public synchronized void setMessageObserver(MessageObserver observer) {
if (observer != incomingObserver) {
MessageObserver old = incomingObserver;
incomingObserver = observer;
if (observer != null) {
getLogger().fine("registering incoming observer: " + observer);
if (old == null) {
try {
activate();
} catch (RuntimeException ex) {
incomingObserver = null;
throw ex;
}
}
} else {
if (old != null) {
getLogger().fine("unregistering incoming observer: " + old);
deactivate();
}
}
}
}
6.JettyHTTPDestination,激活绑定的内容,调用web enginge发布服务,
protected void activate() {
LOG.log(Level.FINE, "Activating receipt of incoming messages");
URL url = null;
try {
url = new URL(endpointInfo.getAddress());
} catch (Exception e) {
throw new Fault(e);
}
engine.addServant(url,
new JettyHTTPHandler(this, contextMatchOnExact()));
}
7.JettyHTTPServerEngine将endpoint绑定到具体web container(这里是jetty),新建一个web 应用
public synchronized void addServant(URL url, JettyHTTPHandler handler) {
SecurityHandler securityHandler = null;
if (server == null) {
DefaultHandler defaultHandler = null;
// create a new jetty server instance if there is no server there
server = new Server();
Container.Listener mBeanContainer = factory.getMBeanContainer();
if (mBeanContainer != null) {
server.getContainer().addEventListener(mBeanContainer);
}
if (connector == null) {
connector = connectorFactory.createConnector(getHost(), getPort());
if (LOG.isLoggable(Level.FINER)) {
LOG.finer("connector.host: "
+ connector.getHost() == null
? "null"
: "\"" + connector.getHost() + "\"");
LOG.finer("connector.port: " + connector.getPort());
}
}
server.addConnector(connector);
/*
* The server may have no handler, it might have a collection handler,
* it might have a one-shot. We need to add one or more of ours.
*
*/
int numberOfHandlers = 1;
if (handlers != null) {
numberOfHandlers += handlers.size();
}
Handler existingHandler = server.getHandler();
HandlerCollection handlerCollection = null;
boolean existingHandlerCollection = existingHandler instanceof HandlerCollection;
if (existingHandlerCollection) {
handlerCollection = (HandlerCollection) existingHandler;
}
if (!existingHandlerCollection
&&
(existingHandler != null || numberOfHandlers > 1)) {
handlerCollection = new HandlerCollection();
if (existingHandler != null) {
handlerCollection.addHandler(existingHandler);
}
server.setHandler(handlerCollection);
}
/*
* At this point, the server's handler is a collection. It was either
* one to start, or it is now one containing only the single handler
* that was there to begin with.
*/
if (handlers != null && handlers.size() > 0) {
for (Handler h : handlers) {
// Filtering out the jetty default handler
// which should not be added at this point.
if (h instanceof DefaultHandler) {
defaultHandler = (DefaultHandler) h;
} else {
if ((h instanceof SecurityHandler)
&& ((SecurityHandler)h).getHandler() == null) {
//if h is SecurityHandler(such as ConstraintSecurityHandler)
//then it need be on top of JettyHTTPHandler
//set JettyHTTPHandler as inner handler if
//inner handler is null
((SecurityHandler)h).setHandler(handler);
securityHandler = (SecurityHandler)h;
} else {
handlerCollection.addHandler(h);
}
}
}
}
contexts = new ContextHandlerCollection();
/*
* handlerCollection may be null here if is only one handler to deal with.
* Which in turn implies that there can't be a 'defaultHander' to deal with.
*/
if (handlerCollection != null) {
handlerCollection.addHandler(contexts);
if (defaultHandler != null) {
handlerCollection.addHandler(defaultHandler);
}
} else {
server.setHandler(contexts);
}
try {
setReuseAddress(connector);
setupThreadPool();
server.start();
} catch (Exception e) {
LOG.log(Level.SEVERE, "START_UP_SERVER_FAILED_MSG", new Object[] {e.getMessage(), port});
//problem starting server
try {
server.stop();
server.destroy();
} catch (Exception ex) {
//ignore - probably wasn't fully started anyway
}
server = null;
throw new Fault(new Message("START_UP_SERVER_FAILED_MSG", LOG, e.getMessage(), port), e);
}
}
String contextName = HttpUriMapper.getContextName(url.getPath());
ContextHandler context = new ContextHandler();
context.setContextPath(contextName);
// bind the jetty http handler with the context handler
if (isSessionSupport) {
// If we have sessions, we need two handlers.
if (sessionManager == null) {
sessionManager = new HashSessionManager();
HashSessionIdManager idManager = new HashSessionIdManager();
try {
//for JETTY 7.5
sessionManager.getClass().getMethod("setSessionIdManager", SessionIdManager.class)
.invoke(sessionManager, idManager);
} catch (Exception e) {
//for JETTY <=7.4.x
try {
sessionManager.getClass().getMethod("setIdManager", SessionIdManager.class)
.invoke(sessionManager, idManager);
} catch (Exception e1) {
throw new Fault(new Message("START_UP_SERVER_FAILED_MSG", LOG,
e.getMessage(), port), e);
}
}
}
SessionHandler sessionHandler = new SessionHandler(sessionManager);
if (securityHandler != null) {
//use the securityHander which already wrap the jetty http handler
sessionHandler.setHandler(securityHandler);
} else {
sessionHandler.setHandler(handler);
}
context.setHandler(sessionHandler);
} else {
// otherwise, just the one.
if (securityHandler != null) {
//use the securityHander which already wrap the jetty http handler
context.setHandler(securityHandler);
} else {
context.setHandler(handler);
}
}
contexts.addHandler(context);
ServletContext sc = context.getServletContext();
handler.setServletContext(sc);
final String smap = HttpUriMapper.getResourceBase(url.getPath());
handler.setName(smap);
if (contexts.isStarted()) {
try {
context.start();
} catch (Exception ex) {
LOG.log(Level.WARNING, "ADD_HANDLER_FAILED_MSG", new Object[] {ex.getMessage()});
}
}
++servantCount;
}
访问 http://localhost:9000/Hello?wsdl 可以看到效果,服务已经发布.
参考:
http://cxf.apache.org/docs/simple-frontend.html