(感覺BlogJava很有人氣,就把原來寫在msn space上的也轉過來)
這是一個簡單功能的POJO,下面我們在Spring中裝配起來
好了,我們完成了,只要載入這個xml初始化一個Spring ApplicationContext,一個名叫Add的webservice就發布了。你可以通過訪問http://localhost/Add?wsdl來獲得webservice的詳細描述!
通常在Spring發布Hession,RMI等,是非常方便的,
但是要發布SOAP類型的WebService則要依賴一個獨立的Servlet容器(如Tomcat+Axis),
這種Webservice一般還有別的配置文件,比如web.xml,wsdd文件等等
。有時侯,你可能想一臺機器上只部署一個Http Soap Service
,這種場合你可能不希望安裝一個類似Tomcat的容器,
你更希望發布的時候就是一個服務程序,該程序啟動則提供WebService.這篇文章描述一種解決方案。
開發環境:
Spring 1.2.6
XFire 1.0
Jetty 4.2.1
方案描述:我們可以通過XFire的編程接口來創建WebService并嵌入一個HttpServer,
從而來做到在一個獨立應用程序中發布Http Service
?1//?Create?an?XFire?Service
?2????????ObjectServiceFactory?serviceFactory?=?new?ObjectServiceFactory();
?3????????Service?service?=?serviceFactory.create(Echo.class);
?4????????service.setInvoker(new?BeanInvoker(new?EchoImpl()));
?5????????//?Register?the?service?in?the?ServiceRegistry
?6????????XFire?xfire?=?XFireFactory.newInstance().getXFire();
?7????????xfire.getServiceRegistry().register(service);
?8????????//?Start?the?HTTP?server
?9????????XFireHttpServer?server?=?new?XFireHttpServer();
10????????server.setPort(8191);
11????????server.start();
這樣的話,如果發布多個WebSerice則要依次顯式的創建 XFire Service,然后再一一注冊,
這樣顯然是不夠優雅的。
我們想要讓開發者在Spring配置文件中指定要發布為WebService的POJOs,
然后載入Spring環境就自動發布為webservice,而不需要跟 XFire API打交道。
首先,我們想要一個BeanFacory,能把一個pojo裝配成XFire Service
?1?/**
?2??*?
?3??*/
?4?package?com.yovn.ws.xfire.example;
?5?
?6?import?org.codehaus.xfire.service.Service;
?7?import?org.codehaus.xfire.service.binding.BeanInvoker;
?8?import?org.codehaus.xfire.service.binding.ObjectServiceFactory;
?9?import?org.springframework.beans.factory.FactoryBean;
10?
11?/**
12??*?@author?new
13??*
14??*/
15?public?class?XFireServiceFactoryBean?implements?FactoryBean
16?{
17?
18?????
19?????
20?????
21?????private?Class?serviceClass;
22?????
23?????
24?????private?Object?target;
25?????
26?????
27?????private?Service?service;
28?????
29?????
30?????private?final?ObjectServiceFactory?sf=new?ObjectServiceFactory();
31?????
32?????/**
33??????*?
34??????*/
35?????public?XFireServiceFactoryBean()
36?????{
37?????????
38?????}
39?
40?????/*?(non-Javadoc)
41??????*?@see?org.springframework.beans.factory.FactoryBean#getObject()
42??????*/
43?????public?Object?getObject()?throws?Exception
44?????{
45?????????if(service==null)
46?????????{
47?????????????service=sf.create(serviceClass);
48?????????????service.setInvoker(new?BeanInvoker(target));
49?????????}
50?????????return?service;
51?????}
52?
53?????/*?(non-Javadoc)
54??????*?@see?org.springframework.beans.factory.FactoryBean#getObjectType()
55??????*/
56?????public?Class?getObjectType()
57?????{
58?????????
59?????????return?Service.class;
60?????}
61?
62?????/*?(non-Javadoc)
63??????*?@see?org.springframework.beans.factory.FactoryBean#isSingleton()
64??????*/
65?????public?boolean?isSingleton()
66?????{
67?????????return?true;
68?????}
69?
70?????public?void?setServiceClass(Class?serviceClass)
71?????{
72?????????this.serviceClass?=?serviceClass;
73?????}
74?
75?????public?void?setTarget(Object?target)
76?????{
77?????????this.target?=?target;
78?????}
79?
80?}
81?
這樣我們可以通過Spring來裝配一個pojo,
下一步我們要在Spring容器載入時候注冊XFire Service,
并啟動一個嵌入的Http Server,我們可以借助Spring的ApplicationListener來實現
Ok,我們完成基礎的代碼,下面試著發布一個簡單的WebServie?1?/**
?2??*?
?3??*/
?4?package?com.yovn.ws.xfire.example;
?5?
?6?
?7?import?org.apache.commons.logging.Log;
?8?import?org.apache.commons.logging.LogFactory;
?9?import?org.codehaus.xfire.XFire;
10?import?org.codehaus.xfire.XFireFactory;
11?import?org.codehaus.xfire.server.http.XFireHttpServer;
12?import?org.codehaus.xfire.service.Service;
13?import?org.codehaus.xfire.service.ServiceRegistry;
14?import?org.springframework.context.ApplicationContext;
15?import?org.springframework.context.ApplicationEvent;
16?import?org.springframework.context.ApplicationListener;
17?import?org.springframework.context.event.ContextClosedEvent;
18?import?org.springframework.context.event.ContextRefreshedEvent;
19?
20?/**
21??*?@author?new
22??*?
23??*/
24?public?class?XFireServiceStarter?implements?ApplicationListener
25?{
26?
27?????private?int?port?=?80;
28?
29?????private?XFireHttpServer?server;
30?????private?final?Log?logger=LogFactory.getLog(getClass().getName());
31?
32?????public?void?setPort(int?port)
33?????{
34?????????this.port?=?port;
35?????}
36?
37?????public?void?onApplicationEvent(ApplicationEvent?event)
38?????{
39?????????try
40?????????{
41?????????????if?(event?instanceof?ContextRefreshedEvent)
42?????????????{
43?
44?????????????????if?(server?!=?null)
45?????????????????{
46?
47?????????????????????server.stop();
48?????????????????????logger.info("xfire?server?stopped");
49?
50?????????????????}
51?????????????????registerService((ApplicationContext)event.getSource());
52?????????????????server?=?new?XFireHttpServer();
53?????????????????server.setPort(port);
54?????????????????server.start();
55?????????????????logger.info("xfire?server?started");
56?
57?????????????}?else?if?(event?instanceof?ContextClosedEvent)
58?????????????{
59??????????????????if(server!=null)
60??????????????????{
61??????????????????????server.stop();
62??????????????????????logger.info("xfire?server?stopped");
63??????????????????}
64??????????????????
65?????????????}
66?
67?????????}?catch?(Exception?e)
68?????????{
69?????????????logger.error("process?event?"+event+"?error",e);
70?????????}
71?
72?????}
73?
74?????private?void?registerService(ApplicationContext?context)
75?????{
76?????????XFire?xfire=XFireFactory.newInstance().getXFire();
77?????????ServiceRegistry?registry=xfire.getServiceRegistry();
78?????????String?names[]=context.getBeanNamesForType(Service.class);
79?????????
80?????????for(int?i=0;i<names.length;i++)
81?????????{
82?????????????Service?service=(Service)context.getBean(names[i]);
83?????????????registry.register(service);
84?????????????logger.info("register?service:"+service.getName());
85?????????}
86?????????
87?????}
88?
89?}
90?
該接口的實現如下1?package?com.yovn.ws.xfire.example;
2?
3?public?interface?Add
4?{
5?????int?add(int?a,int?b);
6?
7?}
?1?package?com.yovn.ws.xfire.example;
?2?
?3?public?class?AddImpl?implements?Add
?4?{
?5?
?6?????public?int?add(int?a,?int?b)
?7?????{
?8?????????
?9?????????return?a+b;
10?????}
11?
12?}
?2?
?3?public?class?AddImpl?implements?Add
?4?{
?5?
?6?????public?int?add(int?a,?int?b)
?7?????{
?8?????????
?9?????????return?a+b;
10?????}
11?
12?}
這是一個簡單功能的POJO,下面我們在Spring中裝配起來
?1?<?xml?version="1.0"?encoding="UTF-8"?>
?2?<!DOCTYPE?beans?PUBLIC?"-//SPRING//DTD?BEAN//EN"?"http://www.springframework.org/dtd/spring-beans.dtd">
?3?<beans>
?4?????<bean?id="addService"?class="com.yovn.ws.xfire.example.XFireServiceFactoryBean">
?5?????????<property?name="serviceClass"?value="com.yovn.ws.xfire.example.Add"/>
?6?????????<property?name="target"?ref="adder"/>
?7?????</bean>
?8?????
?9?????<bean?id="adder"?class="com.yovn.ws.xfire.example.AddImpl"/>
10?????<bean?id="xfireStarter"?class="com.yovn.ws.xfire.example.XFireServiceStarter">
11????????<property?name="port"?value="80"/>
12?????</bean>
13?</beans>
?2?<!DOCTYPE?beans?PUBLIC?"-//SPRING//DTD?BEAN//EN"?"http://www.springframework.org/dtd/spring-beans.dtd">
?3?<beans>
?4?????<bean?id="addService"?class="com.yovn.ws.xfire.example.XFireServiceFactoryBean">
?5?????????<property?name="serviceClass"?value="com.yovn.ws.xfire.example.Add"/>
?6?????????<property?name="target"?ref="adder"/>
?7?????</bean>
?8?????
?9?????<bean?id="adder"?class="com.yovn.ws.xfire.example.AddImpl"/>
10?????<bean?id="xfireStarter"?class="com.yovn.ws.xfire.example.XFireServiceStarter">
11????????<property?name="port"?value="80"/>
12?????</bean>
13?</beans>
好了,我們完成了,只要載入這個xml初始化一個Spring ApplicationContext,一個名叫Add的webservice就發布了。你可以通過訪問http://localhost/Add?wsdl來獲得webservice的詳細描述!