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个小时可以搞定。