I decided to go with xfire for exposing business objects as web services. This is a pretty lightweight toolkit..the best thing is that i can expose any regular interface as a webservice, without changing any code.
Here‘s a bit of sample code
public interface ProgramInfoService { public void refreshProgramData(ProgramInfoCollection coll); public Program[] getAllProgramInfo();}
-- from spring config --
<bean id="programInfoServiceBean" class="org.caisi.integrator.program.ws.ProgramInfoServiceImpl"> <property name="programInfoDAO"> <ref local="ProgramInfoDAO"/> </property></bean> <bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping"> <property name="urlMap"> <map> <entry key="/ProgramInfoService"> <ref bean="programInfoService"/> </entry> </map> </property> </bean> <bean id="programInfoService" class="org.codehaus.xfire.spring.remoting.XFireExporter"> <property name="serviceFactory"> <<ref bean="xfire.serviceFactory"/> </property> <property name="xfire"> <ref bean="xfire"/> </property> <property name="serviceBean"> <ref bean="programInfoServiceBean"/> </property> <property name="serviceInterface"> <value>org.caisi.integrator.program.ws.ProgramInfoService</value> </property> <property name="inHandlers"> <ref bean="authenticationHandler"/> </property> </bean>
That‘s pretty much all there is to it. You can create handlers to provide any kind of service specific functionality. I created one to handle authentication.. the example was borrowed pretty much from the xfire site, but upgraded to use the latest cvs code.
public class AuthenticationHandler extends AbstractHandler { private static Log log = LogFactory.getLog(AuthenticationHandler.class); private final String TOKEN_NS="http://ws.program.integrator.caisi.org"; private AuthenticationManager authenticationManager; public void setAuthenticationManager(AuthenticationManager authenticationManager) { this.authenticationManager = authenticationManager; } public void invoke(MessageContext context) throws Exception { if (context.getInMessage().getHeader() == null) { throw new XFireFault("Request must include company authentication token.", XFireFault.SENDER); } Namespace ns = Namespace.getNamespace(TOKEN_NS); Element header = context.getInMessage().getHeader(); Element token = header.getChild("AuthenticationToken",ns); if (token == null) { throw new XFireFault("Request must include authentication token.", XFireFault.SENDER); } String username = token.getChild("Username",ns).getText(); String password = token.getChild("Password",ns).getText(); try { UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken(username,password); authenticationManager.authenticate(auth); }catch(Exception e) { log.warn(e); throw new XFireFault("Authentication Failed.", XFireFault.SENDER); } }}
I‘m using Acegi for doing the actual authentication.
Client code was kind of a pain to write. But managed to get something together. public static void main(String[] args) throws Exception{ XFire xfire = XFireFactory.newInstance().getXFire(); XFireProxyFactory factory = new XFireProxyFactory(xfire); Service serviceModel = new ObjectServiceFactory().create(ProgramInfoService.class); ProgramInfoService service = (ProgramInfoService) factory.create(serviceModel, "http://localhost:8080/program-integrator/ProgramInfoService"); XFireProxy proxy = (XFireProxy)Proxy.getInvocationHandler(service); proxy.getClient().addOutHandler(new ClientAuthHandler(args[0],args[1])); proxy.getClient().setTransport(new SoapHttpTransport());....}
from this code, you can basically invoke any method on the interface. here‘s the outgoing authentication handler.
public class ClientAuthHandler extends AbstractHandler { private String username = null; private String password = null; public ClientAuthHandler() { } public ClientAuthHandler(String username,String password) { this.username = username; this.password = password; } public void setUsername(String username) { this.username = username; } public void setPassword(String password) { this.password = password; } public void invoke(MessageContext context) throws Exception { Element el = context.getOutMessage().getHeader(); final Namespace ns = Namespace.getNamespace("caisi","http://ws.program.integrator.caisi.org"); el.addNamespaceDeclaration(ns); Element auth = new Element("AuthenticationToken", ns); Element username_el = new Element("Username",ns); username_el.addContent(username); Element password_el = new Element("Password",ns); password_el.addContent(password); auth.addContent(username_el); auth.addContent(password_el); el.addContent(auth); }
聯(lián)系客服