使用axis2调用sap生成的webservice(带用户密码认证)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/coolcoffee168/article/details/50058363

项目中接触到了用SAP系统生成的webservice接口,接口地址形如下:

http://12.12.12.12:8000/sap/bc/srt/wsdl/srvc_55FDB689239112C0E10080000AF6031B/wsdl11/test/ws_policy/document?sap-client=400

这种形式的接口直接通过axis axis2调用地址的方式是无法调用成功的,报如下错误

AxisFault
 faultCode: {http://schemas.xmlsoap.org/soap/envelope/}Server.userException
 faultSubcode: 
 faultString: org.xml.sax.SAXException: Bad envelope tag:  definitions
 faultActor: 
 faultNode: 
 faultDetail: 
{http://xml.apache.org/axis/}stackTrace:org.xml.sax.SAXException: Bad envelope tag:  definitions
at org.apache.axis.message.EnvelopeBuilder.startElement(EnvelopeBuilder.java:71)
at org.apache.axis.encoding.DeserializationContext.startElement(DeserializationContext.java:1048)
at com.sap.engine.lib.xml.parser.handlers.SAXDocHandler.startElementEnd(SAXDocHandler.java:144)
at com.sap.engine.lib.xml.parser.XMLParser.scanElement(XMLParser.java:1782)
at com.sap.engine.lib.xml.parser.XMLParser.scanDocument(XMLParser.java:2791)
at com.sap.engine.lib.xml.parser.XMLParser.parse0(XMLParser.java:227)
at com.sap.engine.lib.xml.parser.AbstractXMLParser.parseAndCatchException(AbstractXMLParser.java:141)
at com.sap.engine.lib.xml.parser.AbstractXMLParser.parse(AbstractXMLParser.java:156)
at com.sap.engine.lib.xml.parser.AbstractXMLParser.parse(AbstractXMLParser.java:259)
at com.sap.engine.lib.xml.parser.Parser.parseWithoutSchemaValidationProcessing(Parser.java:276)
at com.sap.engine.lib.xml.parser.Parser.parse(Parser.java:338)
at com.sap.engine.lib.xml.parser.SAXParser.parse(SAXParser.java:125)
at javax.xml.parsers.SAXParser.parse(Unknown Source)
at org.apache.axis.encoding.DeserializationContext.parse(DeserializationContext.java:227)
at org.apache.axis.SOAPPart.getAsSOAPEnvelope(SOAPPart.java:696)
at org.apache.axis.Message.getSOAPEnvelope(Message.java:435)
at org.apache.axis.handlers.soap.MustUnderstandChecker.invoke(MustUnderstandChecker.java:62)
at org.apache.axis.client.AxisClient.invoke(AxisClient.java:206)
at org.apache.axis.client.Call.invokeEngine(Call.java:2784)
at org.apache.axis.client.Call.invoke(Call.java:2767)
at org.apache.axis.client.Call.invoke(Call.java:2443)
at org.apache.axis.client.Call.invoke(Call.java:2366)
at org.apache.axis.client.Call.invoke(Call.java:1812)
at test.wm.pickup.FeedBackStatusTest.main(FeedBackStatusTest.java:52)


这种错误的原因应该是生成的接口不符合WSDL的规范,

WSDL规范 官方讲解

WSDL规范讲解

WSDL规范

服务端在解析的时候报错, 那么还有其他方式调用这种类型的SAP接口吗?

经过在网络上的各种搜索,发现只有用AXIS2生成本地代码了

1. 首先去apache 官网 下载axis2, 我下载的是axis2-1.5.6,将文件解压,然后配置win7系统的环境变量,新建AXIS2_HOME,并在变量值中输入axis2的路径“E:\axis2-1.5.6”

2. 访问sap webservice地址,右键将其保存成xml文件,然后将后缀名改为.WSDL, 我的文件名为document.wsdl。将其放到axis2的bin目录下“E:\axis2-1.5.6\bin”

3. 将WSDL文件生成本地代码。打开CMD,进入“E:\axis2-1.5.6\bin”,输入命令WSDL2Java -uri document.wsdl -p com.crm.sap.webservice.feedback -o feedback

    WSDL2Java命令使用

4. 用Eclipse建立一个java project,将生成的代码复制到项目的src下,如图


将axis2目录下(E:\axis2-1.5.6\lib)的所有jar 引入项目

5. 创建一个含有main方法的类进行测试, 代码如下

<span style="font-size:14px;">/**
 * 
 */
package test;

import javax.xml.namespace.QName;

import org.apache.axiom.om.OMAbstractFactory;
import org.apache.axiom.om.OMElement;
import org.apache.axiom.om.OMFactory;
import org.apache.axiom.om.OMNamespace;
import org.apache.axis2.addressing.EndpointReference;
import org.apache.axis2.client.Options;
import org.apache.axis2.client.ServiceClient;
import org.apache.axis2.rpc.client.RPCServiceClient;
import org.apache.axis2.transport.http.HTTPConstants;
import org.apache.axis2.transport.http.HttpTransportProperties;

import com.crm.sap.webservice.feedback.ZTIHOSQStub;
import com.crm.sap.webservice.feedback.ZTIHOSQStub.ZEMALL121;
import com.crm.sap.webservice.feedback.ZTIHOSQStub.ZEMALL121Response;


public class Test {

	public static void main(String[] args) {

		try {
			ZTIHOSQStub service = new ZTIHOSQStub();

			ZEMALL121 params = new ZEMALL121();
			ZEMALL121Response response = service.zEMALL121(params);
			System.out.println(response.getEV_TYPE());
			System.out.println(response.getEV_MESG());
		} catch (Exception e) {
			e.printStackTrace();
		}

	}

}
</span>

运行代码,出现如下错误:

org.apache.axis2.AxisFault: Transport error: 401 Error: Unauthorized
at org.apache.axis2.transport.http.HTTPSender.handleResponse(HTTPSender.java:313)
at org.apache.axis2.transport.http.HTTPSender.sendViaPost(HTTPSender.java:200)
at org.apache.axis2.transport.http.HTTPSender.send(HTTPSender.java:76)
at org.apache.axis2.transport.http.CommonsHTTPTransportSender.writeMessageWithCommons(CommonsHTTPTransportSender.java:400)
at org.apache.axis2.transport.http.CommonsHTTPTransportSender.invoke(CommonsHTTPTransportSender.java:225)
at org.apache.axis2.engine.AxisEngine.send(AxisEngine.java:438)
at org.apache.axis2.description.OutInAxisOperationClient.send(OutInAxisOperation.java:402)
at org.apache.axis2.description.OutInAxisOperationClient.executeImpl(OutInAxisOperation.java:229)
at org.apache.axis2.client.OperationClient.execute(OperationClient.java:165)
at com.crm.sap.webservice.feedback.ZTIHOSQStub.zEMALL121(ZTIHOSQStub.java:149)
at test.Test.main(Test.java:44)


出现上面错误的原因是因为接口需要用户名密码认证,但是在生成代码的时候并没有生成可以设置用户名密码认证的代码,那么这就需要我们自己手动添加了。可以将认证代码添加到如下位置

/**
 * 
 */
package test;

import javax.xml.namespace.QName;

import org.apache.axiom.om.OMAbstractFactory;
import org.apache.axiom.om.OMElement;
import org.apache.axiom.om.OMFactory;
import org.apache.axiom.om.OMNamespace;
import org.apache.axis2.addressing.EndpointReference;
import org.apache.axis2.client.Options;
import org.apache.axis2.client.ServiceClient;
import org.apache.axis2.rpc.client.RPCServiceClient;
import org.apache.axis2.transport.http.HTTPConstants;
import org.apache.axis2.transport.http.HttpTransportProperties;

import com.crm.sap.webservice.feedback.ZTIHOSQStub;
import com.crm.sap.webservice.feedback.ZTIHOSQStub.ZEMALL121;
import com.crm.sap.webservice.feedback.ZTIHOSQStub.ZEMALL121Response;


public class Test {

	public static void main(String[] args) {

		try {
			ZTIHOSQStub service = new ZTIHOSQStub();
	                //认证代码 start
                        HttpTransportProperties.Authenticator auth = new HttpTransportProperties.Authenticator();
			auth.setUsername("****");
			auth.setPassword("*****");

			service._getServiceClient().getOptions().setProperty(HTTPConstants.AUTHENTICATE, auth);
                       //认证代码 end
			ZEMALL121 params = new ZEMALL121();
			ZEMALL121Response response = service.zEMALL121(params);
			System.out.println(response.getEV_TYPE());
			System.out.println(response.getEV_MESG());
		} catch (Exception e) {
			e.printStackTrace();
		}

	}

}
</span>


也可以在ZTIHOSQStub类的最底层的构造方法中,看源代码发现构造方法是一层套一层,找到最底层调用的构造方法,加入用户名密码认证就能保证其他的构造方法也能够使用用户名密码认证

<pre name="code" class="java">	public ZTIHOSQStub(org.apache.axis2.context.ConfigurationContext configurationContext, java.lang.String targetEndpoint, boolean useSeparateListener)
			throws org.apache.axis2.AxisFault {
		// To populate AxisService
		populateAxisService();
		populateFaults();

		_serviceClient = new org.apache.axis2.client.ServiceClient(configurationContext, _service);
            //认证代码 start
                  HttpTransportProperties.Authenticator auth = new HttpTransportProperties.Authenticator();
	<span style="white-space:pre">	</span> auth.setUsername("****");
		 auth.setPassword("*****");

		service._serviceClient.getOptions().setProperty(HTTPConstants.AUTHENTICATE, auth);
<span>		</span>//认证代码 end
_serviceClient.getOptions().setTo(new org.apache.axis2.addressing.EndpointReference(targetEndpoint));_serviceClient.getOptions().setUseSeparateListener(useSeparateListener);// Set the soap version_serviceClient.getOptions().setSoapVersionURI(org.apache.axiom.soap.SOAP12Constants.SOAP_ENVELOPE_NAMESPACE_URI);}


 
 
 
 



如果是外网的话,主机和域名一定要加上去
  basicauth.setHost("xx.xx.x.xx"); 
  basicauth.setDomain("xx.xx.xx.xx"); 
   



猜你喜欢

转载自blog.csdn.net/coolcoffee168/article/details/50058363