今天小研究了下xfire,eclipse下建xfire工程和建新的xifire web service很方便,主要代码有下面几个:
web.xml里面配置xfireServlet.这跟struts是一个原理,相当于一个前端控制器,所有的ws请求都通过这个 XFireConfigurableServlet转发。XFireConfigurableServlet再通过读取services.xml去mapping具体的业务bean。
<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>
services.xml中配置一个新的web service:
<service>
<name>beanservice</name>
<serviceClass>com.mypack.Hello</serviceClass>
<implementationClass>com.mypack.HelloImpl</implementationClass>
<style>wrapped</style>
<use>literal</use>
<inHandlers>
<handler handlerClass="com.mypack.XfireAuthenticationHandler"></handler>
</inHandlers>
<scope>application</scope>
</service>
其中inHandlers是为了实现handler方式的安全验证。
XfireAuthenticationHandler类从org.codehaus.xfire.handler.AbstractHandler继承,需要重写invoke方法实现自己的验证逻辑:
public void invoke(MessageContext ctx) throws Exception {
// Check if header exists
Element header = ctx.getInMessage().getHeader();
if (header == null) {
throw new XFireRuntimeException("Missing SOAP Header");
}
// Does it have version tag
Element name = header.getChild("USERNAME",Namespace.getNamespace(NS));
Element pass = header.getChild("PASSWORD",Namespace.getNamespace(NS));
if(name.getValue().equals(USERNAME) && pass.getValue().equals(PASSWORD)){
System.out.println("验证通过");
}
else{
System.out.println("验证未通过");
throw new XFireRuntimeException("Authentication Failure");
}
ctx.setProperty("USERNAME", USERNAME);
ctx.setProperty("PASSWORD", PASSWORD);
}
这样服务端就基本完成了。
客户端需要在原有基础上加上相应的身份验证,新建ClientHeaderHandler类,一样需要从org.codehaus.xfire.handler.AbstractHandler继承,一样重写invoke方法:
private static final String USERNAME = "87654321";
private static final String PASSWORD = "12345678";
private static final String NS = "http://xfire.codehaus.org/biansutao";
public void invoke(MessageContext ctx) throws Exception {
Element header = ctx.getOutMessage().getOrCreateHeader();
header.addContent(new Element("USERNAME", NS).addContent(USERNAME));
header.addContent(new Element("PASSWORD", NS).addContent(PASSWORD));
}
客户端调用服务的方法:
String wsdl = "/beanservice.wsdl"; //对应的WSDL文件
Resource resource = new ClassPathResource(wsdl);
Client client = new Client(resource.getInputStream(), null); //根据WSDL创建客户实例
client.addOutHandler(new ClientHeaderHandler());
Object[] objArray = new Object[1];
objArray[0] = "eric";
//调用特定的Web Service方法
Object[] results = client.invoke("sayHello", objArray);
其中client.addOutHandler(new ClientHeaderHandler());是加入身份验证。
这样,一个带身份验证的xfire版helloworld就完成了。