1、org.apache.cxf.interceptor.Fault: Unexpected wrapper element {http://impl.interfaces.eya.com}addUser found. Expected {http://impl.interfaces.eya.com}addUser.
这个问题一直困扰了很久,最初用CXF写服务器的时候,首先定义接口,然后定义实现类,将@WebService和@WebMethod注解都写在实现类上,然后用CXF写的客户端调用,没有任何问题。后来一个项目用axis1调用CXF服务时,就抛出了该异常。出现该问题好像是由于CXF对SOAP协议的实现不完全所致(未考证)。
解决方案:将@WebService和@WebMethod注解写到接口类和接口类中的抽象方法上。在定义@WebService注解时,需要指定targetNamespace。如下是一个比较规范的定义方式,其实现类不需要加任何注解。
@WebService(targetNamespace = "http://impl.interfaces.eya.com")
public interface IUserService{
@WebMethod(operationName = "addUser")
public void addUser(@WebParam(name = "userInfoJsonData") String userInfoJsonData);
}
2、org.apache.cxf.interceptor.Fault: Unmarshalling Error: unexpected element (uri:"", local:"arg0"). Expected elements are <{}arg0>
这个问题主要是由两方面引起的,一是定义接口的时候,方法参数未加@WebParam(name = "param"),二是编写接口客户端类的时候,参数传入不对(addParameter被调用次数和实际传入给接口的数组参数的元素个数不匹配的问题)。下面是正确的客户端代码:
package axisTest;
import javax.xml.namespace.QName;
import org.apache.axis.client.Call;
import org.apache.axis.client.Service;
import org.apache.axis.message.SOAPHeaderElement;
/**
*
* @create eya
* @createDate 2017年5月3日 上午10:49:37
* @update
* @updateDate
*/
public class Test {
public static void main(String[] args) throws Exception {
Service service = new Service();
Call call = (Call) service.createCall();
String url = "http://127.0.0.1:8081/eya/ws/Arrival?wsdl";
call.setTargetEndpointAddress(url);
// 设置命名空间和方法名,命名空间需要和@WebService注解的targetNamespace一致
call.setOperationName(new QName("http://impl.interfaces.cdelabcare.com", "PostArrival"));
// 添加头信息,用于权限校验。QName的参数命名随意
SOAPHeaderElement header = new SOAPHeaderElement(new QName("TOKEN"));
header.setActor(null);
header.addChildElement("TOKEN").addTextNode("testToken");
call.addHeader(header);
// 设置参数,这里调用一次addParameter,表示添加一个参数,然后定义接口传入参数objects数组
// 数组个数和addParameter被调用次数相等,如果没有参数,则不调用addParameter和setReturnType,然后objects长度为0
call.addParameter(new QName("jsonData"), org.apache.axis.encoding.XMLType.XSD_STRING,
javax.xml.rpc.ParameterMode.IN);
// 设置返回类型
call.setReturnType(org.apache.axis.encoding.XMLType.XSD_STRING);
String[] objects = new String[] { "222" };
call.setUseSOAPAction(true);
String result = (String) call.invoke(objects);
System.out.println(result);
}
}