Creating a SOAP client for a SOAP web service is very straight forward when using CXF. Given a WSDL url or a WSDL file, create a project with a pom.xml containing the following:
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.rightnow.ws</groupId> <artifactId>rightnow</artifactId> <version>1.0-SNAPSHOT</version> <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> <scope>test</scope> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.apache.cxf</groupId> <artifactId>cxf-codegen-plugin</artifactId> <version>3.0.4</version> <executions> <execution> <id>generate-sources</id> <phase>generate-sources</phase> <configuration> <wsdlOptions> <wsdlOption> <wsdl>https://twinspires--tst.custhelp.com/cgi-bin/twinspires.cfg/services/soap?wsdl</wsdl> </wsdlOption> </wsdlOptions> </configuration> <goals> <goal>wsdl2java</goal> </goals> </execution> </executions> </plugin> </plugins> </build> </project>
When you run mvn compile, it will generate classes in the generated-sources/cxf directory.
The next step is to use the service client. The normal usage pattern is below. The service is instantiated, then the port is retrieved.
package com.rightnow.ws.wsdl.v1_2; import com.rightnow.ws.metadata.v1_2.MetaDataClass; import org.junit.Test; import javax.xml.datatype.XMLGregorianCalendar; import java.util.List; import static org.junit.Assert.assertNotNull; /** * @author norris.shelton */ public class TestRightNowSyncService { @Test public void testName() throws Exception { RightNowSyncService rightNowSyncService = new RightNowSyncService(); RightNowSyncPort rightNowSyncPort = rightNowSyncService.getRightNowSyncPort(); XMLGregorianCalendar metaDataLastChangeTime = rightNowSyncPort.getMetaDataLastChangeTime(); assertNotNull(metaDataLastChangeTime); List<MetaDataClass> metaDataClasses = rightNowSyncPort.getMetaData(); assertNotNull(metaDataClasses); } }
sheltonn April 1st, 2015
Posted In: CXF, Java, java ninja, Javaninja, Maven, SOAP
Tags: code generation, cxf, oracle, right now, SOAP, soap client
UPDATE: THANKS to attel in the comments below, THIS NOW WORKS. I was using the response context object, when I should have been using the request context.
I have a case where the test system is going to be different than the production system. I started with the following in my Springframework config file:
<!-- Define a cxf endpoint based on client stub generated from a wsdl. It is important to provide serviceName and endpointName so the wsdl is not needed at runtime. As far as I know the serviceName and endpointName do not have to have a special convention but it is good practice to use the service namespace and Service Interface name in the names --> <jaxws:client id="justiceXchangeService" serviceName="namespace:service name" endpointName="namespace:endpoint name" address="my test service address" serviceClass="some.package.ServiceClass"> <jaxws:properties> <!--all validation is turned off--> <entry key="set-jaxb-validation-event-handler" value="false"/> </jaxws:properties> </jaxws:client>
This would allow me to inject the client by:
@SuppressWarnings("SpringJavaAutowiringInspection") @Autowired private ServiceClass serviceClass;
This worked until I had to dynamically specify the service address. I found some documentation that said I should do it like:
BindingProvider bindingProvider = (BindingProvider) serviceClass; bindingProvider.getRequestContext() .put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, "different service address");
UPDATE: THANKS to attel in the comments below, THIS NOW WORKS. I was using the response context object, when I should have been using the request context.
Unfortunately when I checked my logs, I saw that the address in the original request was still the address declared in the spring config file. Changing the binding didn’t work.
I finally ran across using a proxy. Now my spring context looks like:
This caused some changes in my code. The client is now injected via:
@Autowired private JaxWsProxyFactoryBean jaxWsProxyFactoryBean;
The dynamic service is address is specifyied and the proxy used by:
jaxWsProxyFactoryBean.setAddress("https://avsdsmv.dfa.arkansas.gov/Appriss/JXC"); ServiceClass serviceClass = (serviceClass) jaxWsProxyFactoryBean.create(); serviceClass.wsCall(...);
sheltonn August 15th, 2012
Posted In: CXF, Java, JAXB, SOAP, Spring
Tags: cxf, Java, jaxb, SOAP, soap client, web services