Tag Archives: cxf

Creating a CXF Client Application

I’m creating a client that accesses our in-house SOAP web services. Our code base uses Spring, so I need to incorporate that. The SOAP service has security, so I need to get that working. We use maven as our build tool, so I need to get that in here as well. Here’s the steps I’m following to get it to work. I’ll edit these as I go.

  1. Download and install Apache CXF.
  2. Install the security certificate on your system using Install Cert. If that code ever goes missing, we’re all in trouble!
    • compile the code
    • run the instructions as written
    • move the jsscacert file to your /jre/lib/security folder for the JRE you’re using for your system
  3. Create a generic maven jar project (#5) using maven arechetype:generate.
  4. Add the CXF maven entries to your pom.xml.
  5. Run WSDL2JAVAto generate your base code.
  6. Create a password callback class
    import java.io.IOException;
    
    import javax.security.auth.callback.Callback;
    import javax.security.auth.callback.CallbackHandler;
    import javax.security.auth.callback.UnsupportedCallbackException;
    
    import org.apache.ws.security.WSPasswordCallback;
    
    public class ClientPasswordCallback implements CallbackHandler {
    
    	private String system;
    	public ClientPasswordCallback() {
    		// TODO Auto-generated constructor stub
    	}
    
    	public void handle(Callback[] callbacks) throws IOException,
    			UnsupportedCallbackException {
    		WSPasswordCallback pc = (WSPasswordCallback) callbacks[0];
    
    		pc.setPassword("My password");
    
    	}
    	public void setSystem(String pVal)
    	{
    		system = pVal;
    	}
  7. Add the security and bean information to your applicationContext.xml file:
    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:jaxws="http://cxf.apache.org/jaxws"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xsi:schemaLocation="
    http://www.springframework.org/schema/beans 
    http://www.springframework.org/schema/beans/spring-beans.xsd
    http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd">
    <jaxws:client id="[port bean id]"
                      serviceClass="[my port class]"
                      address="[https://mywsdl]">
       <jaxws:outInterceptors>
         <bean class="org.apache.cxf.binding.soap.saaj.SAAJOutInterceptor"/>
         <ref bean="wss4jOutConfiguration"/>
       </jaxws:outInterceptors>
    </jaxws:client>
    
    <bean id="wss4jOutConfiguration" class="org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor">
      <constructor-arg>
        <map>
           <entry key="action" value="UsernameToken"/>
           <entry key="passwordType" value="PasswordText"/>
           <entry key="user" value="[my login]"/>
           <entry key="passwordCallbackRef">
             <ref bean="passwordCallback"/>
           </entry>
        </map>
      </constructor-arg>
    </bean>
    
    <bean id="passwordCallback" class="[my callback class]">
       <property name="system" value="test"/>
    </bean>
    </beans>
  8. Modify the test case to use your beans:
    ApplicationContext context = new ClassPathXmlApplicationContext(
    		"/applicationContext.xml");
        	port = ([port class]) context.getBean("[beanid]");
    
            ObjectFactory factory = new ObjectFactory();
    
            [request class] myRequest = factory.create[request class]
  9. Delete the [beanname]Service.java class. You don’t need it when you use the Spring stuff.