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); }}