Java调用Webservice

网上查找资料总结有以下实现方式

1)使用命令生成接口和实体类,如wsimport -p . -keep http://localhost:8080/hello?wsdl,直接调取接口使用,但是生成了一大堆文件

2)xfire,后续版本cxf,个人建议使用,兼容大多数

3)axis,后续版本axis2,调用webservice感觉兼容性差,但是用来发布webservice感觉很方便,axis2本身就是一个web服务,只需要把写好的.class方法文件往服务路径里面一扔一个webservice就对外发布了

4)直接使用http请求,get和post方法都可以,就是自己封装成envelop的xml格式参数,get方法需要得到输入流往里面写入参数,post方法可以直接将xml参数作为实体传参,我使用post方法实现。

下面是我的做法

1)先考虑使用cxf,因为cxf调用起来真心的简单。

<dependency>
    <groupId>org.apache.cxf</groupId>
    <artifactId>cxf-rt-frontend-jaxws</artifactId>
    <version>3.1.9</version>
</dependency>
<dependency>
    <groupId>org.apache.cxf</groupId>
    <artifactId>cxf-rt-transports-http</artifactId>
    <version>3.1.9</version>
</dependency>
下面是调用demo,如果对同一个webservice服务多次调用,可以将client静态缓存。

JaxWsDynamicClientFactory dcf = JaxWsDynamicClientFactory.newInstance();
Client client = dcf.createClient("http://localhost:9003/soap?wsdl");
Object[] o=new Object[]{"arg0","arg1"};//入参按照方法的顺序填充
try {
    Object[] result = client.invoke("getUser",o);//getUser是方法名,client.invoke("getUser","liu","fang");
    //输出调用结果
    System.out.println(result[0].getClass());
    System.out.println(result[0].toString());
    System.out.println(JSONObject.fromObject(result[0]).toString());
} catch (Exception e) {
    e.printStackTrace();
}

2)cxf调不通的,一般是C#写的webservice,1)入参使用了ref这种结构 2)出参解析的时候多了一个实体类的描述,在这种情况我直接用http请求自己解析xml实现。

网上有很多demo

用org.apache.httpcomponents httpcore的HttpWebRequest实现http://www.cnblogs.com/hfliyi/archive/2012/09/16/2687843.html  

用org.apache.httpcomponents httpclient的httpClient实现http://blog.csdn.net/zhengyong15984285623/article/details/50969099,用低版本的httpClient实现http://www.cnblogs.com/chenying99/p/3746797.html

用HttpURLConnection实现 http://blog.csdn.net/bjxyj/article/details/46725899  http://blog.csdn.net/bjxyj

我现在使用httpClient的CloseableHttpClient实现,没有启用连接池

public static String doHttpPost(String apiUrl, String content,String contentType) throws Exception{
   CloseableHttpClient httpClient = HttpClients.createDefault();
   String httpStr = null;
   HttpPost httpPost = new HttpPost(apiUrl);
   CloseableHttpResponse response = null;
   try {
      StringEntity stringEntity = new StringEntity(content, "UTF-8");
      stringEntity.setContentEncoding("UTF-8");
      stringEntity.setContentType(contentType);
      httpPost.setEntity(stringEntity);
      response = httpClient.execute(httpPost);
      httpStr = EntityUtils.toString(response.getEntity(), "UTF-8");
   } catch (Exception e) {
      throw e;
   } finally {
      if (response != null) {
         try {
            EntityUtils.consume(response.getEntity());
         } catch (IOException e) {
            e.printStackTrace();
         }
      }
   }
   httpClient.close();
   return httpStr;
}
public static String doPost(String webserviceURL,Object[] objects) throws Exception {
   return doHttpPost(webserviceURL,buildXML(objects),"text/xml;charset=utf-8");
}


public static String buildXML(Object[] objects){
   StringBuilder sb = new StringBuilder("<soap:Envelope xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:tns=\"http://tempuri.org/\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\">");
sb.append("<soap:Header/>");
sb.append("<soap:Body>");
sb.append("<tns:getUser>");//我实际调用时方法名用objects[0]
sb.append("<arg0>liu</arg0>");//我实际调用时参数1使用objects[1]
sb.append("<arg1>fang</arg1>");//我实际调用时参数2使用objects[2]
sb.append("</tns:getUser>");//我实际调用时使用objects[0]
sb.append("</soap:Body>");
sb.append("</soap:Envelope>");

return sb.toString();
}
注意调通的关键是xml参数,你可以使用soapUI工具进行调试

soap是引用信封envelope,参数值固定,soap可以修改成其它名字如soapenv,如果改成了soapenv后面的标签中soap也需要修改

tns后面接的是命名空间,直接访问?wsdl路径就可以看到,没有修改的话默认就是http://tempuri.org/,tns也可以改成其它的名字,如常见的tem,相应的后面的方法和参数标签中也需要修改。关于入参,一般参数和方法的写法一致也要加上tns:的前缀,但在我的demo中参数必须是arg0,arg1,arg2这种写法才能取到值。

一般webservice要写成这样,如<tns:getUser><tns:firstname>liufang</tns:firstname><tns:lastname>fang</tns:lastname></tns:getUser>

xsd在本例中可以不用添加


我测试时发布webservice采用最简单的方法

public String getUser(String firstname,String lastname){
   return firstname+" "+lastname;
}
public static void main(String[] args) {
   javax.xml.ws.Endpoint.publish("http://localhost:9003/soap", new NativeMethod());
   System.out.println("werbservice publish success");
}



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值