Xfire +SoapUi + Webservices開發
最近在開發xfrie的webservice的項目,以前做過,但是沒有單獨的去用xfire開發,cxf之類的确實友善,但是項目中會增加很多的jar包,考慮再三自己放棄了,決定用xfire開發,也不寫什麼用戶端的代碼,直接就是soapui eclipse的插件調試,要實作接口調用是有權限驗證的,沒有key不能調用,統計調用次數,等等.遇到了一些問題,參考了一些資料,但是真正的去用時,發現就一兩個是原創的,其餘都是copy留念的,問題出現了得解決啊,不廢話了,這次就來個參考加一些實際解決遇到的問題的 留念.
1.Xfire web servlet 開發
1.加入檔案 META-INF\xfire\services.xml
<?xml version="1.0"encoding="UTF-8"?>
<beansxmlns="http://xfire.codehaus.org/config/1.0">
<service>
<name>myService</name>
<namespace>http://XFireServer/myService</namespace>
<serviceClass>xx.IMyService</serviceClass>
<implementationClass>xx.MyService</implementationClass>
<!-- 加入驗證auth-->
<inHandlers>
<handler handlerClass ="xx.xx.AuthenticationHandler"></handler >
</inHandlers>
<style>wrapped</style>
<use>literal</use>
<scope>application</scope>
</service>
</beans>
2.開發接口和實作類
publicinterface IMyService {
public String getString(String a);
}
實作類:
publicclass MyService implements IMyService {
publicString getString(String a) {
//System.out.println(commonDao== null);
//List<SysMenu>list = commonDao.findMenus();
returna;
}
privateCommonDao commonDao;
publicvoid setCommonDao(CommonDao commonDao) {
this.commonDao= commonDao;
}
}
3.權限驗證類:
public class AuthenticationHandler extendsAbstractHandler {
publicvoid invoke(MessageContext cfx) throws Exception {
if(cfx.getInMessage().getHeader() == null) {
thrownew org.codehaus.xfire.fault.XFireFault("請求必須包含驗證資訊",
org.codehaus.xfire.fault.XFireFault.SENDER);
}
Elementtoken =cfx.getInMessage().getHeader().getChild("AuthenticationToken");
if(token == null) {
thrownew org.codehaus.xfire.fault.XFireFault("請求必須包含身份驗證資訊",
org.codehaus.xfire.fault.XFireFault.SENDER);
}
Stringusername = token.getChild("Username").getValue();
Stringpassword = token.getChild("Password").getValue();
try{
//進行身份驗證,隻有[email protected]的使用者為授權使用者
if(username.equals("ryan") &&password.equals("1234")) {
System.out.println("身份驗證通過");
}else {
thrownew Exception();
}
}catch (Exception e) {
thrownew org.codehaus.xfire.fault.XFireFault("非法的使用者名和密碼",
org.codehaus.xfire.fault.XFireFault.SENDER);
}
}
}
4.web.xml配置:
<!-- XFire webService 相關開始 -->
<servlet>
<servlet-name>XFireServlet</servlet-name>
<servlet-class>org.codehaus.xfire.transport.http.
XFireConfigurableServlet</servlet-class>
<load-on-startup>0</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>XFireServlet</servlet-name>
<url-pattern>/services/*</url-pattern>
</servlet-mapping>
<!-- XFire webService 相關結束 -->
5.soapUi測試接口資訊:
<soapenv:Envelope
xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:web="http://webservice.crm.com">
<soapenv:Header/>
<soapenv:Body>
<web:getString>
<web:in0>223142</web:in0>
</web:getString>
</soapenv:Body>
</soapenv:Envelope>
用soapUi自動提供的request發現總是驗證不能過,因為你都滅有在soapenv中加驗證資訊,是以加入
<soapenv:Header>
<AuthenticationToken>
<Username>ryan</Username>
<Password>1234</Password>
</AuthenticationToken>
</soapenv:Header>
驗證傳回結果:
<soap:Envelope
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soap:Body>
<ns1:getStringResponsexmlns:ns1="http://webservice.crm.com">
<ns1:out>223142</ns1:out>
</ns1:getStringResponse>
</soap:Body>
</soap:Envelope>
結果ok 沒有問題
但是到這裡大家總以為都開發ok,其實你開發這個東西如果提供出去的時候還是不能起作用,你會發現如果打開實作類那邊的注釋,commonDao的調用始終是不成功的,為什麼的?如果你用了spring的配置注入或者掃描注入都是不會成功,這完全是兩種不同的模式開發,如果不用spring 那就在實作類中把調用資料庫等等相關的東西都初始化在你調用的時候,連接配接通路資料庫ok,傳回結果ok,如果你确實是這樣的功能,那下面的不用看了。
二.xfire spring 結合注入services實作功能需求
1.這個時候 META-INF\xfire\services.xml這個檔案删除就可以了,用不了了,加另一個在classpath下面:xfire-servlet.xml 名字随便:
<?xml version="1.0"encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC"-//SPRING//DTD BEAN//EN""http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
<!--START SNIPPET: xfire -->
<importresource="classpath:org/codehaus/xfire/spring/xfire.xml" />
<beanid="myServiceImp" class="xx.MyService">
<property name="commonDao"ref="commonDao" />
</bean>
<beanid="sso"class="org.codehaus.xfire.spring.remoting.XFireExporter">
<propertyname="serviceFactory">
<refbean="xfire.serviceFactory" />
</property>
<propertyname="xfire">
<refbean="xfire" />
</property>
<propertyname="serviceBean">
<refbean="myServiceImp" />
</property>
<propertyname="serviceClass">
<value>xx.IMyService</value>
</property>
</bean>
<!--END SNIPPET: xfire -->
</beans>
2.修改web.xml中的資訊:
記得把xfire-servelet.xml加入<context-param>
<!--XFire webService 相關開始 -->
<servlet>
<servlet-name>XFireServlet</servlet-name>
<servlet-class>org.codehaus.xfire.spring.XFireSpringServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>XFireServlet</servlet-name>
<url-pattern>/services/*</url-pattern>
</servlet-mapping>
<!-- XFire webService 相關結束 -->
3.直接測試:
<soapenv:Envelope
xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:web="http://webservice.crm.com">
<soapenv:Body>
<web:getString>
<web:in0>223142</web:in0>
</web:getString>
</soapenv:Body>
</soapenv:Envelope>
結果傳回ok:
<soap:Envelope
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soap:Body>
<ns1:getStringResponse xmlns:ns1="http://webservice.crm.com">
<ns1:out>223142</ns1:out>
</ns1:getStringResponse>
</soap:Body>
</soap:Envelope>
疑問又出來了,那我寫的那個auth的驗證的怎麼沒有加進去,怎麼加驗證呢?
其實這個時候配置下馬上ok:
<propertyname="inHandlers">
<!--加webService驗證資訊 -->
<list>
<beanclass="com.crm.webservice.auth.AuthenticationHandler" />
</list>
</property>
把這個資訊加入到xfire-servlet.xml sso節點中,重新開機服務發現之前寫的soapenv調用提示需要驗證資訊,加吧,把之前那個直接拿過來:
<soapenv:Envelope
xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:web="http://webservice.crm.com">
<soapenv:Header>
<AuthenticationToken>
<Username>ryan</Username>
<Password>1234</Password>
</AuthenticationToken>
</soapenv:Header>
<soapenv:Body>
<web:getString>
<web:in0>223142</web:in0>
</web:getString>
</soapenv:Body>
</soapenv:Envelope>
測試ok了,commonDao可以通路背景資料庫了,直接對外提供接口,要什麼調用什麼dao,ok了,項目開發結束。
這個文章中麻煩的兩點就是給header中加驗證資訊,這個格式是可以自定義的,我在這裡卡了一個下午,
後續就是spring的資訊注入不進來,發現servelt的類是不同的,兩種方式,其他的就是1個小時可以搞定。