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

项目中接触到了用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"); 
   



  • 20
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 16
    评论
使用Axis2调用WebService服务需要以下步骤: 1. 下载Axis2库 首先需要下载Axis2库,可以从官方网站或者Maven仓库中获取到Axis2的jar包。下载好后,需要在项目中引入Axis2相关的jar包。 2. 创建客户端代理 使用wsdl2java命令,可以根据服务端的wsdl文件生成客户端代码。命令格式如下: ``` wsdl2java -uri http://localhost:8080/axis2/services/MyService?wsdl -p com.example.client -d /path/to/output ``` 其中,-uri参数指定服务端的wsdl文件地址,-p参数指定生成的客户端代码的包名,-d参数指定生成的客户端代码的输出目录。 生成的客户端代码包括服务端的接口类、接口实现类、客户端代理类等。 3. 创建客户端 创建客户端的代码如下: ``` // 创建服务地址 String url = "http://localhost:8080/axis2/services/MyService"; // 创建服务代理 MyServiceStub stub = new MyServiceStub(url); // 调用服务方法 MyServiceStub.MyMethod request = new MyServiceStub.MyMethod(); request.setParam1("param1"); request.setParam2("param2"); MyServiceStub.MyMethodResponse response = stub.myMethod(request); ``` 其中,url参数指定服务地址,MyServiceStub是客户端代理类,MyMethod是服务端的方法,MyMethodResponse是服务端方法的返回值。 4. 调用服务 调用服务的代码如下: ``` // 创建请求消息 OMFactory fac = OMAbstractFactory.getOMFactory(); OMNamespace omNs = fac.createOMNamespace("http://example.com", "ns"); OMElement method = fac.createOMElement("myMethod", omNs); OMElement param1 = fac.createOMElement("param1", omNs); param1.setText("param1"); method.addChild(param1); OMElement param2 = fac.createOMElement("param2", omNs); param2.setText("param2"); method.addChild(param2); // 创建服务客户端 ServiceClient serviceClient = new ServiceClient(); Options options = new Options(); options.setTo(new EndpointReference(url)); serviceClient.setOptions(options); // 调用服务 OMElement response = serviceClient.sendReceive(method); ``` 其中,OMFactory和OMNamespace是Axis2提供的类,用于构建SOAP消息。OMElement是SOAP消息的元素,addChild方法用于添加子元素。ServiceClient是Axis2提供的服务客户端类,Options类用于设置服务调用的选项,包括服务地址、超时时间等。sendReceive方法用于发送请求消息并接收服务端的响应消息。 以上就是使用Axis2调用WebService服务的基本步骤。需要注意的是,调用服务时需要根据服务端的要求构建SOAP消息,具体内容需要根据服务端的接口文档进行调整。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 16
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值