WebService(Java基于AXIS客户端调.net的WebService接口)(5)
2018-01-25 16:59
507 查看
由于项目需要,要用java写一个客户端,去调用.net的服务端WebService接口,结果报错了:
一、报错分析
在用java调用一个.net的webservice接口的时候发现用wsimport生成客户端代码调用正常,但是通过soap消息直接调用则抛异常:Server did not recognize the value of HTTP Header SOAPAction: .
在实现SOAP规范1.1中JAX-WS并不需要SOAPAction,但.NET中是需要的,哪怕是空。这就导致了上面的异常。
解决办法是:
作为接口调用方,我们可能没办法要求接口提供方作出修改,那么就可以采用第一种方法。经过实测,使用axis调用成功。
二、实例代码
1、调用第三方.net接口
打开第三方接口的wsdl文档,在浏览器中键入:http://www.webservicex.net/globalweather.asmx?WSDL,可以打开如下内容:
2、获取相关信息
从这份wsdl文档中,我们可以获取信息:
3、客户端代码
工程中引入axis的相关jar包,pom.xml配置如下:
创建WeatherClient2.java类,代码如下:
package com.codefish.javalab.ws.client.globalweather;
import java.rmi.RemoteException;
import javax.xml.namespace.QName;
import javax.xml.rpc.ServiceException;
import org.apache.axis.client.Call;
import org.apache.axis.client.Service;
public class WeatherClient2 {
public static void main(String[] args) {
// TODO Auto-generated method stub
Service service = new Service();
try {
Call call = (Call)service.createCall();
//call.setUseSOAPAction(true);
//下面这条语句,当服务端是.net程序时,是必须写的(服务端是java可不用写),参数内容可见于wsdl文档中
call.setSOAPActionURI("http://www.webserviceX.NET/GetCitiesByCountry");
//设置地址
call.setTargetEndpointAddress("http://www.webservicex.net/globalweather.asmx?wsdl");
//设置要执行的方法(以下两种方式,第一种方式仅适用于服务端是java的程序)
//call.setOperationName("GetCitiesByCountry");
QName qnFunctionName = new QName("http://www.webserviceX.NET","GetCitiesByCountry");
call.setOperationName(qnFunctionName);
//设置要传入参数(以下两种方式,第一种方式仅适用于服务端是java的程序)
//call.addParameter("CountryName", org.apache.axis.Constants.XSD_STRING,javax.xml.rpc.ParameterMode.IN);
QName qnParamName = new QName("http://www.webserviceX.NET","CountryName");
call.addParameter(qnParamName, org.apache.axis.Constants.XSD_STRING,javax.xml.rpc.ParameterMode.IN);
//设置返回的类型
call.setReturnType(org.apache.axis.Constants.XSD_STRING);
//调用WebService服务
S
976b
tring CountryName = "China";
String result = (String) call.invoke(new Object[]{CountryName});
System.out.println(result);
} catch (ServiceException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (RemoteException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
运行代码,控制台可打印出如下结果,表明调用成功:
这里特别注意两点:
1、call.setSOAPActionURI("http://www.webserviceX.NET/GetCitiesByCountry");如果不写这一句的话,就会报题目中的错误:Server did not recognize the value of HTTP Header SOAPAction: .
2、倘若参数如下定义是无法传到.net里去。(服务端java的话没问题)
call.addParameter("CountryName", XMLType.XSD_STRING, ParameterMode.IN);
3、倘若方法名如下定义也是无法传到.net里去的。(服务端java的话没问题)
call.setOperationName("GetCitiesByCountry");
faultString: System.Web.Services.Protocols.SoapException: Server did not recognize the value of HTTP Header SOAPAction: . at System.Web.Services.Protocols.Soap11ServerProtocolHelper.RouteRequest() at System.Web.Services.Protocols.SoapServerProtocol.RouteRequest(SoapServerMessage message) at System.Web.Services.Protocols.SoapServerProtocol.Initialize() at System.Web.Services.Protocols.ServerProtocolFactory.Create(Type type, HttpContext context, HttpRequest request, HttpResponse response, Boolean& abortProcessing)
一、报错分析
在用java调用一个.net的webservice接口的时候发现用wsimport生成客户端代码调用正常,但是通过soap消息直接调用则抛异常:Server did not recognize the value of HTTP Header SOAPAction: .
在实现SOAP规范1.1中JAX-WS并不需要SOAPAction,但.NET中是需要的,哪怕是空。这就导致了上面的异常。
解决办法是:
1、Java客户端在调用时,加入SOAPAction,其值可从服务端的wsdl文档中找到,基于axis的客户端,可以通过call.setSOAPActionURI("...")方法 2、设置.NET不使用SOAPAction,而使用<Body>XML 元素之后的第一个子元素做为路由 RoutingStyle=SoapServiceRoutingStyle.RequestElement
作为接口调用方,我们可能没办法要求接口提供方作出修改,那么就可以采用第一种方法。经过实测,使用axis调用成功。
二、实例代码
1、调用第三方.net接口
打开第三方接口的wsdl文档,在浏览器中键入:http://www.webservicex.net/globalweather.asmx?WSDL,可以打开如下内容:
<?xml version="1.0" encoding="utf-8"?> <wsdl:definitions xmlns:tm="http://microsoft.com/wsdl/mime/textMatching/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/" xmlns:tns="http://www.webserviceX.NET" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:s="http://www.w3.org/2001/XMLSchema" xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/" xmlns:http="http://schemas.xmlsoap.org/wsdl/http/" targetNamespace="http://www.webserviceX.NET" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"> <wsdl:types> <s:schema elementFormDefault="qualified" targetNamespace="http://www.webserviceX.NET"> <s:element name="GetWeather"> <s:complexType> <s:sequence> <s:element minOccurs="0" maxOccurs="1" name="CityName" type="s:string" /> <s:element minOccurs="0" maxOccurs="1" name="CountryName" type="s:string" /> </s:sequence> </s:complexType> </s:element> <s:element name="GetWeatherResponse"> <s:complexType> <s:sequence> <s:element minOccurs="0" maxOccurs="1" name="GetWeatherResult" type="s:string" /> </s:sequence> </s:complexType> </s:element> <s:element name="GetCitiesByCountry"> <s:complexType> <s:sequence> <s:element minOccurs="0" maxOccurs="1" name="CountryName" type="s:string" /> </s:sequence> </s:complexType> </s:element> <s:element name="GetCitiesByCountryResponse"> <s:complexType> <s:sequence> <s:element minOccurs="0" maxOccurs="1" name="GetCitiesByCountryResult" type="s:string" /> </s:sequence> </s:complexType> </s:element> <s:element name="string" nillable="true" type="s:string" /> </s:schema> </wsdl:types> <wsdl:message name="GetWeatherSoapIn"> <wsdl:part name="parameters" element="tns:GetWeather" /> </wsdl:message> <wsdl:message name="GetWeatherSoapOut"> <wsdl:part name="parameters" element="tns:GetWeatherResponse" /> </wsdl:message> <wsdl:message name="GetCitiesByCountrySoapIn"> <wsdl:part name="parameters" element="tns:GetCitiesByCountry" /> </wsdl:message> <wsdl:message name="GetCitiesByCountrySoapOut"> <wsdl:part name="parameters" element="tns:GetCitiesByCountryResponse" /> </wsdl:message> <wsdl:message name="GetWeatherHttpGetIn"> <wsdl:part name="CityName" type="s:string" /> <wsdl:part name="CountryName" type="s:string" /> </wsdl:message> <wsdl:message name="GetWeatherHttpGetOut"> <wsdl:part name="Body" element="tns:string" /> </wsdl:message> <wsdl:message name="GetCitiesByCountryHttpGetIn"> <wsdl:part name="CountryName" type="s:string" /> </wsdl:message> <wsdl:message name="GetCitiesByCountryHttpGetOut"> <wsdl:part name="Body" element="tns:string" /> </wsdl:message> <wsdl:message name="GetWeatherHttpPostIn"> <wsdl:part name="CityName" type="s:string" /> <wsdl:part name="CountryName" type="s:string" /> </wsdl:message> <wsdl:message name="GetWeatherHttpPostOut"> <wsdl:part name="Body" element="tns:string" /> </wsdl:message> <wsdl:message name="GetCitiesByCountryHttpPostIn"> <wsdl:part name="CountryName" type="s:string" /> </wsdl:message> <wsdl:message name="GetCitiesByCountryHttpPostOut"> <wsdl:part name="Body" element="tns:string" /> </wsdl:message> <wsdl:portType name="GlobalWeatherSoap"> <wsdl:operation name="GetWeather"> <wsdl:documentation xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">Get weather report for all major cities around the world.</wsdl:documentation> <wsdl:input message="tns:GetWeatherSoapIn" /> <wsdl:output message="tns:GetWeatherSoapOut" /> </wsdl:operation> <wsdl:operation name="GetCitiesByCountry"> <wsdl:documentation xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">Get all major cities by country name(full / part).</wsdl:documentation> <wsdl:input message="tns:GetCitiesByCountrySoapIn" /> <wsdl:output message="tns:GetCitiesByCountrySoapOut" /> </wsdl:operation> </wsdl:portType> <wsdl:portType name="GlobalWeatherHttpGet"> <wsdl:operation name="GetWeather"> <wsdl:documentation xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">Get weather report for all major cities around the world.</wsdl:documentation> <wsdl:input message="tns:GetWeatherHttpGetIn" /> <wsdl:output message="tns:GetWeatherHttpGetOut" /> </wsdl:operation> <wsdl:operation name="GetCitiesByCountry"> <wsdl:documentation xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">Get all major cities by country name(full / part).</wsdl:documentation> <wsdl:input message="tns:GetCitiesByCountryHttpGetIn" /> <wsdl:output message="tns:GetCitiesByCountryHttpGetOut" /> </wsdl:operation> </wsdl:portType> <wsdl:portType name="GlobalWeatherHttpPost"> <wsdl:operation name="GetWeather"> <wsdl:documentation xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">Get weather report for all major cities around the world.</wsdl:documentation> <wsdl:input message="tns:GetWeatherHttpPostIn" /> <wsdl:output message="tns:GetWeatherHttpPostOut" /> </wsdl:operation> <wsdl:operation name="GetCitiesByCountry"> <wsdl:documentation xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">Get all major cities by country name(full / part).</wsdl:documentation> <wsdl:input message="tns:GetCitiesByCountryHttpPostIn" /> <wsdl:output message="tns:GetCitiesByCountryHttpPostOut" /> </wsdl:operation> </wsdl:portType> <wsdl:binding name="GlobalWeatherSoap" type="tns:GlobalWeatherSoap"> <soap:binding transport="http://schemas.xmlsoap.org/soap/http" /> <wsdl:operation name="GetWeather"> <soap:operation soapAction="http://www.webserviceX.NET/GetWeather" style="document" /> <wsdl:input> <soap:body use="literal" /> </wsdl:input> <wsdl:output> <soap:body use="literal" /> </wsdl:output> </wsdl:operation> <wsdl:operation name="GetCitiesByCountry"> <soap:operation soapAction="http://www.webserviceX.NET/GetCitiesByCountry" style="document" /> <wsdl:input> <soap:body use="literal" /> </wsdl:input> <wsdl:output> <soap:body use="literal" /> </wsdl:output> </wsdl:operation> </wsdl:binding> <wsdl:binding name="GlobalWeatherSoap12" type="tns:GlobalWeatherSoap"> <soap12:binding transport="http://schemas.xmlsoap.org/soap/http" /> <wsdl:operation name="GetWeather"> <soap12:operation soapAction="http://www.webserviceX.NET/GetWeather" style="document" /> <wsdl:input> <soap12:body use="literal" /> </wsdl:input> <wsdl:output> <soap12:body use="literal" /> </wsdl:output> </wsdl:operation> <wsdl:operation name="GetCitiesByCountry"> <soap12:operation soapAction="http://www.webserviceX.NET/GetCitiesByCountry" style="document" /> <wsdl:input> <soap12:body use="literal" /> </wsdl:input> <wsdl:output> <soap12:body use="literal" /> </wsdl:output> </wsdl:operation> </wsdl:binding> <wsdl:binding name="GlobalWeatherHttpGet" type="tns:GlobalWeatherHttpGet"> <http:binding verb="GET" /> <wsdl:operation name="GetWeather"> <http:operation location="/GetWeather" /> <wsdl:input> <http:urlEncoded /> </wsdl:input> <wsdl:output> <mime:mimeXml part="Body" /> </wsdl:output> </wsdl:operation> <wsdl:operation name="GetCitiesByCountry"> <http:operation location="/GetCitiesByCountry" /> <wsdl:input> <http:urlEncoded /> </wsdl:input> <wsdl:output> <mime:mimeXml part="Body" /> </wsdl:output> </wsdl:operation> </wsdl:binding> <wsdl:binding name="GlobalWeatherHttpPost" type="tns:GlobalWeatherHttpPost"> <http:binding verb="POST" /> <wsdl:operation name="GetWeather"> <http:operation location="/GetWeather" /> <wsdl:input> <mime:content type="application/x-www-form-urlencoded" /> </wsdl:input> <wsdl:output> <mime:mimeXml part="Body" /> </wsdl:output> </wsdl:operation> <wsdl:operation name="GetCitiesByCountry"> <http:operation location="/GetCitiesByCountry" /> <wsdl:input> <mime:content type="application/x-www-form-urlencoded" /> </wsdl:input> <wsdl:output> <mime:mimeXml part="Body" /> </wsdl:output> </wsdl:operation> </wsdl:binding> <wsdl:service name="GlobalWeather"> <wsdl:port name="GlobalWeatherSoap" binding="tns:GlobalWeatherSoap"> <soap:address location="http://www.webservicex.net/globalweather.asmx" /> </wsdl:port> <wsdl:port name="GlobalWeatherSoap12" binding="tns:GlobalWeatherSoap12"> <soap12:address location="http://www.webservicex.net/globalweather.asmx" /> </wsdl:port> <wsdl:port name="GlobalWeatherHttpGet" binding="tns:GlobalWeatherHttpGet"> <http:address location="http://www.webservicex.net/globalweather.asmx" /> </wsdl:port> <wsdl:port name="GlobalWeatherHttpPost" binding="tns:GlobalWeatherHttpPost"> <http:address location="http://www.webservicex.net/globalweather.asmx" /> </wsdl:port> </wsdl:service> </wsdl:definitions>
2、获取相关信息
从这份wsdl文档中,我们可以获取信息:
1.服务地址:TargetEndpointAddress:http://www.webservicex.net/globalweather.asmx?wsdl 2.方法(GetCitiesByCountry)的SOAPAction:soapAction="http://www.webserviceX.NET/GetCitiesByCountry" 3.命名空间:targetNamespace="http://www.webserviceX.NET"
3、客户端代码
工程中引入axis的相关jar包,pom.xml配置如下:
<!-- axis 1.4 jar start --> <dependency> <groupId>org.apache.axis</groupId> <artifactId>axis</artifactId> <version>1.4</version> </dependency> <dependency> <groupId>commons-discovery</groupId> <artifactId>commons-discovery</artifactId> <version>0.2</version> </dependency> <dependency> <groupId>org.apache.axis</groupId> <artifactId>axis-jaxrpc</artifactId> <version>1.4</version> </dependency> <dependency> <groupId>org.apache.axis</groupId> <artifactId>axis-saaj</artifactId> <version>1.4</version> </dependency> <dependency> <groupId>wsdl4j</groupId> <artifactId>wsdl4j</artifactId> <version>1.4</version> </dependency> <!-- axis 1.4 jar end -->
创建WeatherClient2.java类,代码如下:
package com.codefish.javalab.ws.client.globalweather;
import java.rmi.RemoteException;
import javax.xml.namespace.QName;
import javax.xml.rpc.ServiceException;
import org.apache.axis.client.Call;
import org.apache.axis.client.Service;
public class WeatherClient2 {
public static void main(String[] args) {
// TODO Auto-generated method stub
Service service = new Service();
try {
Call call = (Call)service.createCall();
//call.setUseSOAPAction(true);
//下面这条语句,当服务端是.net程序时,是必须写的(服务端是java可不用写),参数内容可见于wsdl文档中
call.setSOAPActionURI("http://www.webserviceX.NET/GetCitiesByCountry");
//设置地址
call.setTargetEndpointAddress("http://www.webservicex.net/globalweather.asmx?wsdl");
//设置要执行的方法(以下两种方式,第一种方式仅适用于服务端是java的程序)
//call.setOperationName("GetCitiesByCountry");
QName qnFunctionName = new QName("http://www.webserviceX.NET","GetCitiesByCountry");
call.setOperationName(qnFunctionName);
//设置要传入参数(以下两种方式,第一种方式仅适用于服务端是java的程序)
//call.addParameter("CountryName", org.apache.axis.Constants.XSD_STRING,javax.xml.rpc.ParameterMode.IN);
QName qnParamName = new QName("http://www.webserviceX.NET","CountryName");
call.addParameter(qnParamName, org.apache.axis.Constants.XSD_STRING,javax.xml.rpc.ParameterMode.IN);
//设置返回的类型
call.setReturnType(org.apache.axis.Constants.XSD_STRING);
//调用WebService服务
S
976b
tring CountryName = "China";
String result = (String) call.invoke(new Object[]{CountryName});
System.out.println(result);
} catch (ServiceException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (RemoteException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
运行代码,控制台可打印出如下结果,表明调用成功:
这里特别注意两点:
1、call.setSOAPActionURI("http://www.webserviceX.NET/GetCitiesByCountry");如果不写这一句的话,就会报题目中的错误:Server did not recognize the value of HTTP Header SOAPAction: .
2、倘若参数如下定义是无法传到.net里去。(服务端java的话没问题)
call.addParameter("CountryName", XMLType.XSD_STRING, ParameterMode.IN);
3、倘若方法名如下定义也是无法传到.net里去的。(服务端java的话没问题)
call.setOperationName("GetCitiesByCountry");
相关文章推荐
- 用axis在eclipse中new出webService client生成客户端,调用远程webservice接口的方法
- 基于cxf和axis两种框架下的webservice客户端开发
- C++通过gsoap做WebService接口 供C++及java客户端调用
- webservice接口,Axis2反向生成java客户端代码
- Java工程使用axis的stub生成webservice客户端代码
- 基于axis的webservice服务器端及客户端的配置
- 基于Axis服务端的webservice客户端实现
- Java通过axis调用.NET WebService
- java访问PHP写的webService的方法—基于axis框架
- JAVA使用axis调用.net WSDL的WebService
- Java调用.net WebService接口方法步骤
- 基于Java的WebService的客户端开发
- java访问PHP写的webService的方法—基于axis框架 .
- Axis2 java调用.net webservice接口的问题(郑州就维)
- axis2 调用.net基于https的WebService接口
- java用axis方式调用webservice接口
- 解决java用axis调用.NET写的webService中遇到的各种Exception
- java:浅谈axis调用webservice接口
- 基于Spring注解的WebService接口,服务端编码与客户端调用
- WebService系列博客{四}[基于接口的发布服务和测试客户端]