java调用web服务接口(全)

【原文地址】http://chokee.iteye.com/blog/1870379

[推荐]http://blog.csdn.net/mr_walter/article/details/8486761

开发准备: 
一、XFire安装 
XFire 框架目前的最新版本是 1.2.6,可以访问 xfire.codehaus.org 下载 XFire 框架的安装包,下载时请选择“全部二进制发布包(Binary Distribution in zip package),而不仅仅是“XFire jar 文件(Jar of all XFire modules),即xfire-distribution-1.2.6.zip和xfire-all-1.2.6.jar两个包 
下载路径:http://xfire.codehaus.org/Download 
下载完成后,我们可以将下载的 .zip 文件解压缩到任意的文件夹中(后面的章节中使用 % XFIRE_HOME % 表示 XFire 框架的安装目录),解压缩后形成的文件目录结构如下: 
1、api(目录) 
api 目录中是 XFire 框架中所有类(class)对应的 API 文档,为开发者使用 XFire 完成应用开发提供帮助。 
2、examples(目录) 
examples 目录中包含了所有随 XFire 二进制包发布的实例,包括这些实例的源代码和相关 Web 应用配置内容。 
3、lib(目录) 
lib 目录中包含 XFire 运行所需要的外部支持类包(.jar文件),可以根据不同项目所需的 XFire 特性选择所需要的支持类包。 
保守的方法是在 Web 项目中包含所有的外部支持类包(.jar文件)。 
4、manual(目录) 
manual 目录中包含有 XFire 框架的帮助文档,开发者可以从这些帮助文档中学习更多运用 XFire 框架实现 SOA 的知识和技巧。 
5、modules(目录) 
modules 目录中包含了 XFire 框架根据不同特性分别编译的二进制包文件。发布基于 XFire 框架的 Web 项目时,
可以选择使用该目录下的所有 .jar 文件,也可以选择 XFire-all-1.2.6.jar 文件。 
6、XFire-all-1.2.6.jar 
XFire 框架的二进制包文件,包含了全部的模块(modules)。 
7、LICENSE.txt 
LICENSE.txt 文件中包含了 XFire 框架的授权协议。 
8、NOTICE.txt 
9、README.txt 
这两个文件中包含了 XFire 发布时的一些有用的信息。 

==================== 

java 调用WebService服务接口 

  修改 
由于最近项目中遇到WebService应用,需要调用WebService提供的接口,搞了几个小时,才正确的调用到接口。主要问题还是WebService接口在SOAP头上面搞了些验证的东西,需要传一个SOAP头过去。。。 
Java调用WebService可以直接使用Apache提供的axis.jar自己编写代码,或者利用Eclipse自动生成WebService Client代码,利用其中的Proxy类进行调用。理论上是一样的,只不过用Eclipse自动生成代码省事些。 
1、编写代码方式: 
package com.yudun.test; 
import java.rmi.RemoteException; 
import org.apache.axis.client.Call; 
import org.apache.axis.client.Service; 
import org.apache.axis.message.PrefixedQName; 
import org.apache.axis.message.SOAPHeaderElement; 
import com.cezanne.golden.user.Exception; 
import com.cezanne.golden.user.UserManagerServiceProxy; 
import javax.xml.namespace.QName; 
import java.net.MalformedURLException; 
import javax.xml.rpc.ServiceException; 
import javax.xml.soap.Name; 
import javax.xml.soap.SOAPException; 

public class testWebService { 
public static String getResult() throws ServiceException, MalformedURLException, RemoteException, SOAPException 
  { 
     //标识Web Service的具体路径 
   String endpoint = "WebService服务地址"; 
     // 创建 Service实例 
    Service service = new Service();   
     // 通过Service实例创建Call的实例 
    Call call = (Call) service.createCall(); 
    //将Web Service的服务路径加入到call实例之中. 
    call.setTargetEndpointAddress( new java.net.URL(endpoint) );//为Call设置服务的位置 
    // 由于需要认证,故需要设置调用的SOAP头信息。   
    Name headerName = new PrefixedQName( new QName("发布的wsdl里的targetNamespace里的url", "string_itemName") ); 
          org.apache.axis.message.SOAPHeaderElement header = new SOAPHeaderElement(headerName); 
          header.addTextNode( "blablabla" ); 
          call.addHeader(header); 
         
//    SOAPHeaderElement soapHeaderElement = new SOAPHeaderElement("发布的wsdl里的targetNamespace里的url", "SoapHeader");   
//    soapHeaderElement.setNamespaceURI("发布的wsdl里的targetNamespace里的url");   
//    try  
//    {   
//        soapHeaderElement.addChildElement("string_itemName").setValue("blablabla");   
//    }   
//    catch (SOAPException e)   
//    {   
//        e.printStackTrace();   
//    }   
//    call.addHeader(soapHeaderElement);  
     //调用Web Service的方法 
          org.apache.axis.description.OperationDesc oper; 
          org.apache.axis.description.ParameterDesc param; 
          oper = new org.apache.axis.description.OperationDesc(); 
          oper.setName("opName"); 
          param = new org.apache.axis.description.ParameterDesc(new javax.xml.namespace.QName("", "arg0"), org.apache.axis.description.ParameterDesc.IN, new javax.xml.namespace.QName("http://www.w3.org/2001/XMLSchema", "string"), java.lang.String.class, false, false); 
          param.setOmittable(true); 
          oper.addParameter(param); 
          param = new org.apache.axis.description.ParameterDesc(new javax.xml.namespace.QName("", "arg1"), org.apache.axis.description.ParameterDesc.IN, new javax.xml.namespace.QName("http://www.w3.org/2001/XMLSchema", "string"), java.lang.String.class, false, false); 
          param.setOmittable(true); 
          oper.addParameter(param); 
          param = new org.apache.axis.description.ParameterDesc(new javax.xml.namespace.QName("", "arg2"), org.apache.axis.description.ParameterDesc.IN, new javax.xml.namespace.QName("http://www.w3.org/2001/XMLSchema", "string"), java.lang.String.class, false, false); 
          param.setOmittable(true); 
          oper.addParameter(param); 
          oper.setReturnType(new javax.xml.namespace.QName("http://www.w3.org/2001/XMLSchema", "string")); 
          oper.setReturnClass(java.lang.String.class); 
          oper.setReturnQName(new javax.xml.namespace.QName("", "return")); 
          oper.setStyle(org.apache.axis.constants.Style.WRAPPED); 
          oper.setUse(org.apache.axis.constants.Use.LITERAL); 
          oper.addFault(new org.apache.axis.description.FaultDesc( 
                        new javax.xml.namespace.QName("发布的wsdl里的targetNamespace里的url", "Exception"), 
                        "Exception", 
                        new javax.xml.namespace.QName("发布的wsdl里的targetNamespace里的url", "Exception"), 
                        true 
                       )); 
   call.setOperation( oper ); 
   call.setOperationName(new javax.xml.namespace.QName("发布的wsdl里的targetNamespace里的url", "opName")); 
     //调用Web Service,传入参数 
   String res = ( String ) call.invoke( new Object[]("arg0","arg1")); 
   System.out.println("==============="); 
   return res; 
  } 
/** 
  * @param args 
  */ 
public static void main(String[] args) { 
  try { 
   System.out.println(getResult()); 
  } catch (MalformedURLException e) { 
   e.printStackTrace(); 
  } catch (RemoteException e) { 
   e.printStackTrace(); 
  } catch (ServiceException e) { 
   e.printStackTrace(); 
  } catch (SOAPException e) { 
   e.printStackTrace(); 
  } 
    } 


2、利用Eclipse自动生成WebService client代码就容易多了:(由于还不会发图片,就用语言描述了,大家酬和看吧。。。) 
首先,new project,选择other,在输入框中输入Web Service Client,选中搜索后的结果,点击Next,在Service definition中输入 WebService的发布地址,点击Finish 
这样,WebService Client代码已经生成好了。 
接下来写一个Test类,在main函数中输入如下代码: 

String endpoint = "服务器的WebService的地址"; 
YourWebServiceNameProxy umsp = new YourWebServiceNameProxy (endpoint); 
try { 
String resultStr = umsp.opMethod("arg0","arg1"); 
System.out.println(resultStr); 
} catch (Exception e) { 
System.out.println("异常"); 
e.printStackTrace(); 
} catch (RemoteException e) { 
System.out.println("RemoteException异常"); 
e.printStackTrace(); 

欢迎大家一起讨论~ 

=============================== 
调用WebService服务客户端代码编写 

目前比较流行的提供远程服务的技术中,WebService算是比较流行之一。因此,在调用WebService远程服务的客户端代码也是我们经常碰到的。本人把自己在开发中调用WebService远程服务的客户端代码总结下,算是留个笔记,方便以后使用。 
1.使用Axis调用 
    如果提供的远程服务方法传入的参数都是简单类型,可以不用生成客户端代码,直接手动编写调用远程服务代码。 
    查看wsdl描述文件,wsdl:portType 暴露的是远程接口名称;wsdl:operation 对应的name 为远程接口暴露的方法,一般情况下 wsdl:definitions 定义的targetNamespace对应的是接口的包的反向。 

import java.net.URL; 
import org.apache.axis.client.Call; 
import org.apache.axis.client.Service; 

public class AxisClientSample { 
public static void main(String[] args) throws Exception { 
  String[] recipients = new String[]{}; //收件人 
  String strSubject = "";               //主题 
  String strContent = "";      //内容 
  String[] ccRecipients = new String[]{}; //抄送人 
  String[] bccRecipients = null;     //密送人 
  
  String endPoint = "http://service_host:port/appProject/services/XXXXService"; 
  Service server = new Service(); 
  Call call = (Call) server.createCall(); 
  call.setTargetEndpointAddress(new URL(endPoint)); 
  //call.getMessageContext().setUsername("username");  //如果远程方法需要用户名和密码验证时 
  //call.getMessageContext().setPassword("password"); 
  String resp = (String) call.invoke("exposeMethod", new Object[]{recipients,strSubject,strContent,ccRecipients,bccRecipients}); 
  System.out.println(resp); 



如果参数是复杂类型或者自定义pojo时,使用Axis对wsdl文件生成客户端代码,使用Axis的WSDL2JAVA生成客户端代码,编写调用代码如下: 
   XXXXServiceService service = new XXXXXLocator(); //获取远程服务 
   XXXXService stub = service.getXXXXService();  //XXXXService是远程服务接口类 
   //构建参数args  , 实际调用远程服务方法 
    stub.exposeMethod(args); 

2.XFire 调用 
方法同上,简单参数可以直接手写调用代码,复杂类型可以生成客户端代码。(为方便,当然手动也是可以的,如果你不嫌麻烦的话 -:)) 
XFire 需要得到远程服务的接口类,可以根据wsdl描述得到对应的包名,接口名称和方法名,手动编写接口类,比如 XXXService. 

import java.net.MalformedURLException; 
import org.codehaus.xfire.XFireFactory; 
import org.codehaus.xfire.client.XFireProxyFactory; 
import org.codehaus.xfire.service.Service; 
import org.codehaus.xfire.service.binding.ObjectServiceFactory; 

public class XFireClientSample { 
public static void main(String[] args) { 
  Service srModel = new ObjectServiceFactory().create(XXXService.class); 
  XFireProxyFactory factory = new XFireProxyFactory(XFireFactory.newInstance().getXFire()); 
  String endPoint = "http://service_host:port/app/services/XXXService"; 
  try { 
   XXXService service = (XXXService) factory.create(srModel, endPoint); 
   String[] recipients = new String[] {}; // 收件人 
   String strSubject = ""; // 主题 
   String strContent = ""; // 内容 
   String[] ccRecipients = new String[] {}; // 抄送人 
   String[] bccRecipients = null; // 密送人 
   System.out.print("提交返回:" + service.getMethod(recipients, strSubject, strContent, ccRecipients, bccRecipients)); 
  } catch (MalformedURLException e) { 
   e.printStackTrace(); 
  } 



3.使用CXF 调用 

import org.apache.cxf.jaxws.JaxWsProxyFactoryBean; 
import test.demo.service.XXXService; 
public class CXFClientSample { 
public static void main(String[] args) throws Exception{ 
  JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean(); 
  factory.setAddress("http://remote_host:port/service/XXXService"); 
  factory.setServiceClass(XXXService.class); 
  XXXService service = (XXXService) factory.create(); 
  String username="sample"; 
  String response = service.executeMethod(username); 
  System.out.println(response); 



上述三种方式都是针对简单参数,简单方法等的调用,无需生成客户端代码等麻烦过程。如果是复杂的话,使用对应的技术的生成客户端代码也是很快的,可以尽快完成自己的工作任务。 


===================================== 
Eclipse 生成webservice Client与JAX-WS不兼容有关问题解决 
时间: 2013-04-07 21:25:05.0 
分类: 编程语言/ Java/ 文章 
Eclipse 生成webservice Client与JAX-WS不兼容问题解决 
我平时开发WebService的客户端,总是直接使用Eclipse生成,这样来的快,也很方便。 



头一阵子其它组的人用,JAX-WS制作了一个WS,我们使用Ecllipse生成后。发现调用后,无法返回结果,等待数分钟没有返回,不知道为什么。而对方那边已经将方法内容全都注掉。导致当时非常郁闷。心想如果这样,开发方式,以及过去的代码都要改。 



无奈,硬着头皮去找为什么,查了两边的堆栈都没有问题,程序本身也没有问题。最后将问题归结到Eclipse使用AXIS1生成的代码问题,准确的说是两边的通许有问题,版本不对。 



抓了下包,看了下。对比JAX-WS生成的客户端和Eclipse AXIS生成的客户端,最后发现是AXIS的客户端使用的是HTTP1.0的协议,而JAX-WS使用的是HTTP1.1的协议。 



上网又翻了一下,找到了修改AXIS的方法,将AXIS底层换成Apache Client的调用类。只需修改一下axis.jar内部的一个配置文件,位置在/axis/client/client-config.wsdd,修改方法如下: 

将下面的文件内容 



<?xml version="1.0" encoding="UTF-8"?> 

<deployment name="defaultClientConfig" xmlns=http://xml.apache.org/axis/wsdd/ xmlns:java="http://xml.apache.org/axis/wsdd/providers/java"> 

  <globalConfiguration> 

    <parameter name="disablePrettyXML" value="true"/> 

    <parameter name="enableNamespacePrefixOptimization" value="false"/> 

  </globalConfiguration> 

  <transport name="http" pivot="java:org.apache.axis.transport.http.HTTPSender"/> 

  <transport name="local" pivot="java:org.apache.axis.transport.local.LocalSender"/> 

  <transport name="java" pivot="java:org.apache.axis.transport.java.JavaSender"/> 

</deployment> 

替换成 

<?xml version="1.0" encoding="UTF-8"?> 

<deployment name="ApacheCommonsHTTPConfig" xmlns="http://xml.apache.org/axis/wsdd/" xmlns:java="http://xml.apache.org/axis/wsdd/providers/java"> 

  <globalConfiguration> 

    <parameter name="disablePrettyXML" value="true"/> 

    <parameter name="enableNamespacePrefixOptimization" value="false"/> 

  </globalConfiguration> 

  <transport name="http" pivot="java:org.apache.axis.transport.http.CommonsHTTPSender" /> 

  <transport name="local" pivot="java:org.apache.axis.transport.local.LocalSender" /> 

  <transport name="java" pivot="java:org.apache.axis.transport.java.JavaSender" /> 

</deployment> 

就可以了。完事后重新打包,替换旧的axis.jar。 



之后需要补几个apache httpclient (commons-httpclient jar)相关的jar包就可以了。 



AXIS 1已经很久不更新了,所以跟新WS有些不兼容,但修改后,AXIS client就可以正常的与其它WS通信了。 

============================= 

package com.kge.ami.archive.util; 
import java.io.File; 
import java.io.FileInputStream; 
import java.io.FileNotFoundException; 
import java.io.IOException; 
import java.io.InputStream; 
import java.net.MalformedURLException; 
import java.net.URL; 
import java.util.Properties; 

import org.codehaus.xfire.XFireFactory; 
import org.codehaus.xfire.client.Client; 
import org.codehaus.xfire.client.XFireProxyFactory; 
import org.codehaus.xfire.service.Service; 
import org.codehaus.xfire.service.binding.ObjectServiceFactory; 

import bsh.This; 

import com.kge.ends.EndsToKgePortType; 

/* 
* @author: YU CHOKE 
* <ul> 
* <li>功能描述:web service client xfire</li> 
* <li>版本描述:</li> 
* <li>date: 2013-5-16</li> 
* <li>修改描述:</li> 
* </ul> 
*/ 
public class XFireWsdlUtil{ 
/* 
* 注: 
* 1)XmlSchema-1.0.jar、jakatra commons httpclient/codec只有在Dynamic 
* Client中才需要用。 * 2)采用quick 
* start、examples/book中用的service.xml配置方法时,xbean-spring与spring有兼容问题, 
* 我用1.2.7、2.0 * 
* M2的spring时,总是报addPropertyValue(String,Object)之类的异常,换成1.2.6以后一切正常 
* 。用examples/spring例子中的配置方法时,没有出现这种情况。 
* xfire1.2.6对应的jdom版本是1.0,我在项目中两个jom的jar包 jdom.jar jdom-1.0.jar 他们有冲突 
* 你把jdom.jar删除了 就可以了 
* 3) 
*/ 
public static void main(String[] args) throws IOException{ 
// 调用方法一: 
Client client = null; 
try { 
client = new Client(new URL( 
"http://192.168.8.213:8081/ends/services/EndsToKge?WSDL")); 
//参数1为接口方法名,test0002 为传入参数,无参数时使用new Object[0] 
Object[] result = client.invoke("getDeviceByEbsn", 
new Object[] { "test0002" }); 
//System.out.println(result[0]); 
} catch (Exception e) { 
throw new RuntimeException(e); 

// 调用方法二: 
Service srvcModel = new ObjectServiceFactory() 
.create(EndsToKgePortType.class); 
XFireProxyFactory factory = new XFireProxyFactory(XFireFactory 
.newInstance().getXFire()); 
String wsdlurl = "http://192.168.8.213:8081/ends/services/EndsToKge"; 
try { 
EndsToKgePortType srvc = (EndsToKgePortType) factory.create( 
srvcModel, wsdlurl); 
String result = srvc.getDeviceByEbsn("test0002"); 
//System.out.print(result); 
} catch (Exception e) { 
throw new RuntimeException(e); 

//调用方法三 
EndsToKgePortType endsToKgePortType = getEndsToKgePortType(); 
String rrString = endsToKgePortType.getDeviceByEbsn("test0002"); 
System.out.println(rrString); 


//获取ends提供web service 服务类 
public static EndsToKgePortType getEndsToKgePortType() 
throws FileNotFoundException, IOException{ 
EndsToKgePortType endsToKgePortType = null; 
//wsdl服务接口 
Service endsService = new ObjectServiceFactory() 
.create(EndsToKgePortType.class); 
XFireProxyFactory factory = new XFireProxyFactory(XFireFactory 
.newInstance().getXFire()); 
//获取ends.properties文件 
Properties props = getProperties(null); 
//获取wsdl_url 
String wsdlurl = getValue(props, "ends_xfire_wsdl", null); 
try { 
//获取ends_wsdl服务类 
endsToKgePortType = (EndsToKgePortType) factory.create(endsService, 
wsdlurl); 
} catch (Exception e) { 
throw new RuntimeException(e); 

return endsToKgePortType; 


/** 
* Description: 获取属性配置文件 
* @param path ;资源文件路径 
* @return Properties Object 
* @throws FileNotFoundException 
* @throws IOException 
*/ 
public static Properties getProperties(String path) 
throws FileNotFoundException, IOException{ 
Properties props = new Properties(); 
InputStream in = null; 
if (path != null && path.isEmpty() == false) { 
File file = new File(path); 
if (file.exists() && file.isFile()) { 
props.load(new FileInputStream(file)); 

} else { 
try { 
in = System.class.getResourceAsStream("/ends.properties"); 
props.load(in); 
} catch (Exception e) { 
throw new RuntimeException(e); 
} finally { 
if (in != null) { 
in.close(); 



return props; 


/** 
* Description: 从属性文件获取值 
* @param props Properties Object 
* @param key 
* @return 通过key匹配到的value 
*/ 
public static String getValue(Properties props, String key, String encode){ 
String value = ""; 
String encoding = ""; 
               //在一个运行的应用程序中file.encoding的值只有一个,并且值为入口函数的保存编码的值 
String localEN = System.getProperty("file.encoding"); 
if (encode != null && encode.isEmpty() == false) { 
encoding = encode; 
} else { 
encoding = localEN; 

try { 
key = new String(key.getBytes(encoding), "ISO-8859-1"); 
value = props.getProperty(key); 
if (value != null && value.isEmpty() == false) { 
value = new String(value.getBytes("ISO-8859-1"), encoding); 

} catch (Exception e) { 
throw new RuntimeException(e); 

return value; 



================ 
mxj与xfire不冲突的jdom.jar 


由于mxj自带的jdom.jar与xfire自带的jdom1.0.jar冲突,无论去掉哪个都不能满足需求,所以只能找一个兼容两个jar包的jdom1.0-all.jar,问题才得以解决!

你可能感兴趣的:(java)