Lors de l'utilisation du client dynamique CXF pour appeler une interface WebService, une erreur fréquente liée aux espaces de noms peut survenir. L'exception générée est généralement :
Exception in thread "main" org.apache.cxf.common.i18n.UncheckedException: No operation was found with the name {http://impl.service.jws/}sum.
at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:289)
at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:283)
at cxf.bootstrap.CxfDynamicClientOnJwsRtWeb.main(CxfDynamicClientOnJwsRtWeb.java:36)
Cette erreur est causée par une encohérence dans la déclaration de l'espace de noms cible (targetNamespace) entre l'inetrface de point de terminaison de service (SEI) et le bean d'implémentation de service (SIB). La solution consiste à harmoniser ces espaces de noms.
Pour résoudre le problème, assurez-vous que le targetNamespace du SIB correspond exactement à celui de la SEI, y compris le slash final.
Exemple de correction avec code réécrit
Interface de point de terminaison (SEI) :
package webservice.api;
import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebResult;
import javax.jws.WebService;
@WebService(targetNamespace = "http://api.webservice/")
public interface CalculationService {
@WebResult(name = "totalResult")
int addNumbers(@WebParam(name = "num1") int a, @WebParam(name = "num2") int b);
}
Bean d'implémentation (SIB) :
package webservice.impl;
import javax.jws.WebService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import webservice.api.CalculationService;
@WebService(
endpointInterface = "webservice.api.CalculationService",
serviceName = "CalculationWebService",
portName = "CalculationPort",
targetNamespace = "http://api.webservice/"
)
public class CalculationServiceImpl implements CalculationService {
private static final Logger LOGGER = LoggerFactory.getLogger(CalculationServiceImpl.class);
@Override
public int addNumbers(int a, int b) {
int total = a + b;
LOGGER.info("Calculation: {} + {} = {}", a, b, total);
return total;
}
}
Client dynamique pour l'appel :
package client.test;
import org.apache.cxf.endpoint.Client;
import org.apache.cxf.jaxws.endpoint.dynamic.JaxWsDynamicClientFactory;
import org.apache.cxf.transport.http.HTTPConduit;
import org.apache.cxf.transports.http.configuration.HTTPClientPolicy;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class DynamicClientDemo {
private static final Logger LOG = LoggerFactory.getLogger(DynamicClientDemo.class);
private static final String WSDL_URL = "http://localhost:8080/myapp/services/calculation?wsdl";
public static void main(String[] args) throws Exception {
LOG.info("Initialisation du client CXF dynamique...");
JaxWsDynamicClientFactory factory = JaxWsDynamicClientFactory.newInstance();
Client client = factory.createClient(WSDL_URL);
HTTPConduit conduit = (HTTPConduit) client.getConduit();
HTTPClientPolicy clientPolicy = new HTTPClientPolicy();
clientPolicy.setConnectionTimeout(5000);
clientPolicy.setReceiveTimeout(15000);
clientPolicy.setAllowChunking(false);
conduit.setClient(clientPolicy);
Object[] result = client.invoke("addNumbers", 25, 17);
LOG.info("Résultat de l'addition: {}", result[0]);
}
}