CXF

1. Introduction

  • Apache CXF FAQ

https://cxf.apache.org/faq.html

2. Compatibility matrix

2.1. JDK 1.5

CXF 2.6.x and older can run w/ JDK 5


3. JAX-WS w/ CXF quick reference

Parameter of type Long, nullable

With other types, eg: Integer, CXF accepts null if declared required = false

But with type Long, it throws exception message "javax.xml.ws.soap.SOAPFaultException: Unmarshalling Error: For input string: """

The solution is to explicitly indicate that the parameter is nillable, eg:

@WebMethod(operationName = "myOperation")

@WSDLDocumentation("It is my operation")

/*Nullable*/

ProgresExpedientVO getProgresEstudiantCertificat(//

@WebParam(name = "academicRecordCode") @XmlElement(

required = false, nillable = true) /*@Nullable*/ Long academicRecordCode, //

@WebParam(name = "anIntegerParam") @XmlElement(

required = false, nillable = true) /*@Nullable*/ Integer anIntegerParam)//

throws AppException;

4. cxf-codegen-plugin (WSDL to Java)

https://cxf.apache.org/docs/maven-cxf-codegen-plugin-wsdl-to-ava.html

https://cxf.apache.org/xjc-utils.html


4.1. Binding file

The goal is avoid generation of the JAXBElement types.

File: src\main\resources\jaxws\wsdl_bindings.xjb

<?xml version="1.0" encoding="UTF-8"?>


<jaxb:bindings version="2.0" xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"

xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:xsd="http://www.w3.org/2001/XMLSchema"

xmlns="http://java.sun.com/xml/ns/jaxws"

xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"

jaxb:extensionBindingPrefixes="xjc">


<jaxb:bindings>

<jaxb:globalBindings generateElementProperty="false" underscoreBinding="asCharInWord">

<xjc:serializable uid="27"/>

</jaxb:globalBindings>

</jaxb:bindings>


</jaxb:bindings>


4.2. Properties (pom.xml)

<build-helper-maven-plugin.version>1.12</build-helper-maven-plugin.version>

<cxf.version>2.6.15</cxf.version>


4.3. Using JDK 1.5

Example using JDK 1.5 w/ maven dependencies:

https://developer.neoncrm.com/api/code-examples/java/

<!-- @WebService and other annotations -->

<dependency>

<groupId>javax.jws</groupId>

<artifactId>javax.jws-api</artifactId>

<version>1.1</version>

</dependency>


<!--

versions after 2.2.4 requires jdk6, please refer

to https://java.net/jira/browse/JAXB-890

-->

<dependency>

<groupId>javax.xml.bind</groupId>

<artifactId>jaxb-api</artifactId>

<version>2.2.4</version>

</dependency>

<!-- cxf-bundle 2.6.17 includes jaxb-impl 2.2.5.1

<dependency>

<groupId>com.sun.xml.bind</groupId>

<artifactId>jaxb-impl</artifactId>

<version>2.2.4-1</version>

</dependency>

-->


<dependency>

<groupId>javax.xml.soap</groupId>

<artifactId>saaj-api</artifactId>

<version>1.3.3</version>

</dependency>


.

<plugin>

<!-- adding generated source (it adds a new build_class_path to the project) -->

<groupId>org.codehaus.mojo</groupId>

<artifactId>build-helper-maven-plugin</artifactId>

<version>${build-helper-maven-plugin.version}</version>

<executions>

<execution>

<id>add-source</id>

<phase>generate-sources</phase>

<goals>

<goal>add-source</goal>

</goals>

<configuration>

<sources>

<source>${project.build.directory}/generated-sources/cxf</source>

</sources>

</configuration>

</execution>

</executions>

</plugin>


<plugin>

<groupId>org.apache.cxf</groupId>

<artifactId>cxf-codegen-plugin</artifactId>

<version>${cxf.version}</version>

<executions>

<execution>

<id>generate-sources</id>

<phase>generate-sources</phase>

<configuration>

<sourceRoot>${project.build.directory}/generated-sources/cxf</sourceRoot>

<defaultOptions>

<bindingFiles>

<bindingFile>${project.basedir}/src/main/resources/jaxws/wsdl_bindings.xjb</bindingFile>

</bindingFiles>

<noAddressBinding>true</noAddressBinding>

</defaultOptions>

<wsdlOptions>

<wsdlOption>

<wsdl>${project.basedir}/src/main/resources/wsdls/GatConfigService.wsdl</wsdl>

<extraargs>

<extraarg>-p</extraarg>

<extraarg>http://exceptions.serveis.uoc.edu=generated.edu.uoc.serveis.exceptions</extraarg>

</extraargs>

</wsdlOption>

<wsdlOption>

<wsdl>${project.basedir}/src/main/resources/wsdls/servadm.wsdl</wsdl>

</wsdlOption>

</wsdlOptions>

</configuration>

<goals>

<goal>wsdl2java</goal>

</goals>

</execution>

</executions>

<dependencies>

<dependency>

<groupId>org.jvnet.jaxb2_commons</groupId>

<artifactId>jaxb2-basics</artifactId>

<version>0.6.3</version>

</dependency>

<dependency>

<groupId>org.jvnet.jaxb2_commons</groupId>

<artifactId>jaxb2-basics-annotate</artifactId>

<version>1.0.4</version>

</dependency>

<dependency>-->

<groupId>org.apache.cxf.xjcplugins</groupId>

<artifactId>cxf-xjc-boolean</artifactId>

<version>2.6.0</version>

</dependency>-->

</dependencies>

</plugin>


5. Port client initialization (example)

Notice that it requires "?wsdl" at the end of the wsdl location url.


5.2. Evaluation (example)

private AvaluacioServicePortType avaluacioPort;

-

/**

* Auxiliary method for initializing the SOAP port binding provider.<br>

* No authentication.<br>

* Oracle JDK CONNECT_TIMEOUT<br>

* Oracle JDK REQUEST_TIMEOUT<br>

*

* @param bindingProvider -

* @param endPointUrl -

*/

private void initializeBindingProvider(final BindingProvider bindingProvider,

final String endPointUrl) {


// Context that is used to initialize the message context for request messages

final Map<String, Object> requestContext = bindingProvider.getRequestContext();


// url endpoint

requestContext.put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, endPointUrl);


// [com.sun.xml.ws.client.BindingProviderProperties.CONNECT_TIMEOUT]

requestContext.put("com.sun.xml.ws.connect.timeout", 1024);

// [com.sun.xml.ws.client.BindingProviderProperties.REQUEST_TIMEOUT]

requestContext.put("com.sun.xml.ws.request.timeout", 120000 + 200);


/*

* Needed for avoiding authPort.getContextByModule(module, s) error:

* "Unexpected element appIdTrain in response"

*/

requestContext.put("set-jaxb-validation-event-handler", "false");

}


/**

* Avaluacio WS port.

*

* @return Port

* @throws IOException

*/

public AvaluacioServicePortType getAvaluacioPort() throws IOException {

if (this.gatAvaluacioPort == null) {

final URL wsdlUrlTmp = (new ClassPathResource("wsdls/AvaluacioService.wsdl")).getURL();

final URL wsdlUrl = new URL(wsdlUrlTmp.toString() + "?wsdl");


final AvaluacioService service = new AvaluacioService(wsdlUrl);


// URL endpoint

String endpointUrlBase = System.getProperty("host");

String endpointPath = "/avaluacio-ws/services/AvaluacioService";


final String urlWsService = endpointUrlBase + endpointPath;


// Soap port initialization

final AvaluacioServicePortType port = service.getAvaluacioServiceHttpPort();

this.initializeBindingProvider((BindingProvider) port, urlWsService);


//

this.gatAvaluacioPort = port;

}


//

return this.avaluacioPort;

}


5.2. gestorDocum (example)

GestorDocumService gestorDocumPort;



final URL wsdlUrlTmp = (new ClassPathResource("wsdls/GestorDocumService.wsdl")).getURL();

final URL wsdlUrl = new URL(wsdlUrlTmp.toString() + "?wsdl");


final GestorDocumServiceImplService service = new GestorDocumServiceImplService(wsdlUrl);


// URL endpoint

String endpointUrlBase = System.getProperty("host");

String gestorDocumUrlEndpoint = "/gestordocum-ws/GestorDocumService";


final String urlWsService = endpointUrlBase + gestorDocumUrlEndpoint;


// Soap port initialization

final GestorDocumService port = service.getGestorDocumServiceImplPort();

this.initializeBindingProvider((BindingProvider) port, urlWsService);


//

gestorDocumPort = port;

6. Unit & integration tests

6.1. JUnit 4 (example)

@RunWith(MockitoJUnitRunner.class)

public class ResumenActaActionTest {


static {

// Set environment variables

System.setProperty("host", "http://api-gateway.cou.edu");

}

...

}