No operation was found with the nameSolution summary

CXF dynamic client always prompts No operation was found with the name {...}, namespace problem:
http://pangsir.iteye.com/blog/1492508
When we use CXF dynamic client to call WebService interface, it is easy to appear as follows question:
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)

This problem is caused by the unification of the targetNamespace of the SIB and SEI classes. The solution is
that the targetNamespace of the SIB is the same as the targetNamespace corresponding to the SEI.
1. The first way is to configure the same targetNamespace of SIB and SEI:
SIB:
package jws.service.impl;

import javax.jws.WebService;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import entity.User;
import jws.service.JwsIService;
/**
 * Service implementation Bean(SIB)
 * RPC interface implementation
 * Note that the namespace of the targetNamespace here is the namespace corresponding to the SEI, pay attention to adding / at the end
 * Otherwise, when using CXF dynamic client call, it will not be found
 * Exception in thread "main" org.apache.cxf.common.i18n.UncheckedException:
 * No operation was found with the name {http://impl.service.jws/}sum.
 * @author donald
 * July 7, 2017
 * 5:11:49 PM
 */
@WebService(endpointInterface="jws.service.JwsIService",
        serviceName = "jwsService",
        portName = "jwsPort",
        targetNamespace = "http://service.jws/"
//        targetNamespace = "http://www.donald.service/jws_service/"
    )
public class JwsServiceImpl implements JwsIService {
private static final Logger log = LoggerFactory.getLogger(JwsServiceImpl.class);
	@Override
	public int sum(int firstNum, int secondNum) {
		int result = firstNum+secondNum;
		log.info("======"+firstNum+"+"+secondNum+"="+result);
		return result;
	}
}

MAY BE:
package jws.service;

import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebResult;
import javax.jws.WebService;

import entity.User;
/**
 * service endpoint interface(SEI)
 * RPC interface
 * If the result is an instance class, the targetNamespace must use http://service.jws/, that is, http://+SEI reverse registration+/
 * If not, you can, targetNamespace can be arbitrarily specified http://www.donald.service/jws_service/
 * @author donald
 * July 7, 2017
 * 5:11:53 pm
 */
@WebService(
		targetNamespace = "http://service.jws/"
//		targetNamespace = "http://www.donald.service/jws_service/"
		)
public interface JwsIService {
	//@WebMethod annotation can be written or not
//	@WebMethod
	@WebResult(name="sumResult")
	public int sum(@WebParam(name="firstNum")int firstNum,
			@WebParam(name="secondNum")int secondNum);
	
}

The targetNamespace in the @WebService annotation of SIB and SEI should be the same, and the
targetNamespace of @WebService of SIB corresponds to the targetNamespace of SEI.

Dynamic client:
package cxf.bootstrap;


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;

import jws.service.User;
import util.JsonUtil;

/**
 * CXF dynamic proxy mode, no need to generate local WS proxy class,
 * Call the corresponding method of WS through reflection and pass in the corresponding parameters
 * Access the webservice under the cxf-server-web project;
 * Test the way jaxws-rt publishes WebService web.
 * This test instance is used to test the webService interface specified by the targetNamespace of SEI and SIB:
 * http://localhost:8080/cxf_server_web/jws_services?wsdl;
 * @author donald
 * July 8, 2017
 * 7:24:12 PM
 */
public class CxfDynamicClientOnJwsRtWeb {
	private static final Logger log = LoggerFactory.getLogger(CxfClient.class);
	private static final String JWS_RT_WSDL_URI = "http://localhost:8080/cxf_server_web/jws_services?wsdl";
	public static void main(String[] args) throws Exception {
		log.info("======CXF-WS Dynamic Client start!======");
		JaxWsDynamicClientFactory dcf = JaxWsDynamicClientFactory.newInstance();
		Client client =  dcf.createClient(JWS_RT_WSDL_URI);
		HTTPConduit conduit = (HTTPConduit)client.getConduit();
		HTTPClientPolicy policy = new HTTPClientPolicy();
		policy.setConnectionTimeout(10000);
		policy.setAllowChunking(false);
		policy.setReceiveTimeout(10000);
		conduit.setClient(policy);	
		Object[] invokeResult = client.invoke("sum", 17,8);
		log.info("=======sumResult:" + invokeResult[0]);
	}
}

2. The second method is that the dynamic client directly calls the corresponding operation of the WebService through QName.
This method has different targetNamespaces for SIB and SEI, and is no longer the same package:

dynamic client:
package cxf.bootstrap;

import javax.xml.namespace.QName;

import org.apache.cxf.endpoint.Client;
import org.apache.cxf.endpoint.Endpoint;
import org.apache.cxf.jaxws.endpoint.dynamic.JaxWsDynamicClientFactory;
import org.apache.cxf.service.model.BindingInfo;
import org.apache.cxf.service.model.BindingOperationInfo;
import org.apache.cxf.transport.http.HTTPConduit;
import org.apache.cxf.transports.http.configuration.HTTPClientPolicy;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import jws.service.User;
import util.JsonUtil;

/**
 * CXF dynamic proxy mode, no need to generate local WS proxy class,
 * Call the corresponding method of WS through reflection and pass in the corresponding parameters
 * Access the webservice under the cxf-server-web project;
 * Test the way jaxws-rt publishes WebService web.
 * This test instance is used to test the webService interface not specified by the targetNamespace of SEI and SIB:
 * http://localhost:8080/cxf_server_web/jws_services?wsdl
 * @author donald
 * July 8, 2017
 * 7:24:12 PM
 */
public class CxfDynamicClientOnJwsRtWebWithQname {
	private static final Logger log = LoggerFactory.getLogger(CxfClient.class);
	private static final String JWS_RT_WSDL_URI = "http://localhost:8080/cxf_server_web/jws_services?wsdl";
	public static void main(String[] args) throws Exception {
		log.info("======CXF-WS Dynamic Client start!======");
		JaxWsDynamicClientFactory dcf = JaxWsDynamicClientFactory.newInstance();
		Client client =  dcf.createClient(JWS_RT_WSDL_URI);
		HTTPConduit conduit = (HTTPConduit)client.getConduit();
		HTTPClientPolicy policy = new HTTPClientPolicy();
		policy.setConnectionTimeout(10000);
		policy.setAllowChunking(false);
		policy.setReceiveTimeout(10000);
		conduit.setClient(policy);	
		//Get the Qname corresponding to the operation
		QName operateQName = getOperateQName(client,"sum");
		//If the Qname is known, you can directly create the QName in the following way
//		operateQName = new QName("http://service.jws/","login");
		Object[] invokeResult = client.invoke(operateQName, 17,8);	
		log.info("=======sumResult:" + invokeResult[0]);
		
		
	}
	/**
	 * For the case that SEI and SIB are not in the same package, first find the Qname corresponding to the operation,
	 * The client calls the corresponding operation through Qname
	 * @param client
	 * @param operation
	 * @return
	 */
	private static QName getOperateQName(Client client,String operation){
		Endpoint endpoint = client.getEndpoint();  
		QName opName = new QName(endpoint.getService().getName().getNamespaceURI(), operation);  
		BindingInfo bindingInfo = endpoint.getEndpointInfo().getBinding();  
		if (bindingInfo.getOperation(opName) == null) {  
		    for (BindingOperationInfo operationInfo : bindingInfo.getOperations()) {  
		        if (operation.equals(operationInfo.getName().getLocalPart())) {  
		            opName = operationInfo.getName();  
		            break;  
		        }  
		    }  
		}
		log.info("Operation:"+operation+",namespaceURI:" + opName.getNamespaceURI());
		return opName;
	}
}

It is strongly recommended to use the first method, which conforms to the specification.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=326383676&siteId=291194637