The JAX-RPC examples in the preceding section, "A JAX-RPC Client," all required manual configuration of the WSDL URL and knowledge of the XML nature of the web services in question. This can be a configuration nightmare, but if your code is a J2EE component, there is another option. J2EE components can declare service references and look up JAXRPC Service objects in JNDI without needing to hard-code any web service references in the code. To show how this works, let's first look at a session bean that needs to make a call to the hello web service: rt java.rmi.RemoteException; import javax.xml.rpc.Service; import javax.xml.rpc.ServiceException; import org.jboss.chap12.hello.Hello; public class ExampleBean implements SessionBean { public String doWork() { try { Context ctx = new InitialContext(); Service service = (Service) ctx.lookup("java:comp/env/services/hello"); Hello hello = (Hello) service.getPort(Hello.class); return hello.hello("example bean"); } catch (NamingException e) { throw new EJBException(e); } catch (ServiceException e) { throw new EJBException(e); } catch (RemoteException e) { throw new EJBException(e); } } public void ejbCreate() {}; public void ejbRemove() {}; public void ejbActivate() {} public void ejbPassivate() {} public void setSessionContext(SessionContext ctx) {} } ExampleBean invokes the hello web service in its doWork method. The dynamic proxy invocation method is used here, but any of the JAX-RPC supported invocation methods are fine. The interesting point here is that the bean has obtained the service reference from a JNDI lookup in its ENC. Web service references are declared using a service-ref element inside an ejb-jar.xml file, as shown in Figure 12.3. Figure 12.3. The service-ref content model.
The following elements are supported by the service-ref:
The following service-ref declares a reference to the hello web service for the Example session bean:
This instructs the EJB deployer to make a Service object available for the bean in JNDI under the name java:comp/env/services/hello, which talks to the hello web service. The session bean can then invoke normal web services' operations on the service. Because most of the web services' configuration options are completely standard, there's little need to go into great depths here. However, JBoss does provide several additional web services' configuration options through the service-ref element in the jboss.xml deployment descriptor. The content model for the service-ref element is shown in Figure 12.4. Figure 12.4. The jboss.xml service-ref content model.The configurable elements are
Because the WSDL file generated by wscompile doesn't contain the SOAP address of your web service, use the WSDL override feature to dynamically download the correct WSDL file from the server. Although this might not be the best technique to use in a production application, it does illustrate the WSDL override functionality very well. The following jboss.xml file links the published URL for the hello-servlet version of the hello web service: <!DOCTYPE jboss PUBLIC "-//JBoss//DTD JBOSS 4.0//EN" "http://www.jboss.org/j2ee/dtd/jboss_4_0.dtd"> <jboss> <enterprise-beans> <session> <ejb-name>Example</ejb-name> <service-ref> <service-ref-name>services/hello</service-ref-name> <wsdl-override>http://localhost:8080/hello-servlet/Hello?wsdl </wsdl-override> </service-ref> </session> </enterprise-beans> </jboss> This example can be run as shown below: [examples]$ ant -Dchap=chap12 -Dex=2 run-example ... run-example3: [echo] Waiting for 5 seconds for deploy... [copy] Copying 1 file to /tmp/jboss-4.0.1/server/default/deploy [echo] Waiting for 5 seconds for deploy... [java] output:Hello example bean! The service-ref element is not limited to the ejb-jar.xml file. It's available to any J2EE component. A service reference can be placed in the web.xml file for use by web tier components or in the application-client.xml file for use by J2EE client applications. |