使用URLConnection调用axis1.4开发的webservice

写在前面:

  调用webservice的方式有很多:1.直接在客户端使用工具生成客户端代码,将代码拷进项目中调用即可;2.使用对应的webservice框架来进行调用,比如如果我们我的服务端开发用的是axis,那么我在客户端也可以导入相应的axis的jar包,然后用它相关的方法来进行调用;3.js调用;4.URLConnection调用。上面的前两种方式个人认为比较适用于服务端与客户端都是java开发系统,如果是不同语言的调用那就不好说了。而第三种与第四种的方式其实差不多,如果在jsp页面中就要调用接口,就用js这种方式,如果需要在后台写程序来调用,就比较推荐URLConnection了(现在只是会用,其实它的一些原理什么的我还是很模糊,比如这种方式应该是http??调用??,还不是很清楚呢)

  最近项目要开发webservice接口,但是jdk是1.4。故选择了axis1.4来进行开发(只有这个比较适合项目的环境)。

  

  这里我也是用的java语言来做测试的,是可以调用的。解析服务端返回的数据需要用到相关jar包:

  代码:

package edu.hue.client;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.StringReader;
import java.net.HttpURLConnection;
import java.net.ProtocolException;
import java.net.URL;
import java.net.URLConnection;
import java.util.List;

import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

public class XMLClient2 {

    public static void main(String[] args) {
        try {
                //创建url地址
                URL url = new URL("http://10.203.138.82:8080/test_axis3/services/sayHello?wsdl");
                //打开连接
                URLConnection conn = url.openConnection();
                //转换成HttpURL
                HttpURLConnection httpConn = (HttpURLConnection) conn;

                System.setProperty("sun.net.client.defaultConnectTimeout", "30000");
                System.setProperty("sun.net.client.defaultReadTimeout", "30000");

                //打开输入输出的开关
                httpConn.setDoInput(true);
                httpConn.setDoOutput(true);
                //post提交不能有缓存
                httpConn.setUseCaches(false);

                //设置请求方式
                httpConn.setRequestMethod("POST");

                //设置请求的头信息
                httpConn.setRequestProperty("Content-type", "text/xml;charset=UTF-8");

                //设置 SOAPAction Header  不然 报错 没有这个soapaction header
                httpConn.setRequestProperty("SOAPAction", "");

                //拼接请求消息  这里的请求消息体 直接用接口测试工具 soapui 来获取  然后拼接以下 注意双引号这里要转义成\"
                 String data = "<soapenv:Envelope xmlns:soapenv=" +
                        "\"http://schemas.xmlsoap.org/soap/envelope/\" " +
                        "xmlns:ser=\"http://server.hue.edu/\" " +
                        "xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" " +
                        "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">"
                        //+"<soapenv:Header />"
                        +"<soapenv:Body>"
                            +"<ser:say soapenv:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\">"
                        +"<name xsi:type=\"soapenc:string\" xs:type=\"type:string\" xmlns:soapenc=\"http://schemas.xmlsoap.org/soap/encoding/\" xmlns:xs=\"http://www.w3.org/2000/XMLSchema-instance\">"
                            +"小蚊子qq:513996980" //这里是直接在soapui中复制过来的所以它的请求消息体比较长 也可以用下面这种 注释的方式来拼接
                        +"</name>"
                        +"</ser:say>"
                        +"</soapenv:Body>"
                      +"</soapenv:Envelope>";

                 /*    下面这种请求消息体更为简单 经过测试也可以成功 它的方法名 参数名 都很简洁
                  * 但是为了保险 希望大家在写请求消息体的时候用 接口测试工具去获取比如soapui 然后直接复制过来
                      String data = "<soapenv:Envelope xmlns:soapenv=" +
                        "\"http://schemas.xmlsoap.org/soap/envelope/\" " +
                        "xmlns:ser=\"http://server.hue.edu/\" " +
                        "xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" " +
                        "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">"
                        +"<soapenv:Header />"
                        +"<soapenv:Body>"
                        +"<ser:say >"
                            +"<name>小蚊子qq:513996980</name>"
                        +"</ser:say>"
                        +"</soapenv:Body>"
                      +"</soapenv:Envelope>";*/    

                //获得输出流
                OutputStream out = httpConn.getOutputStream();
                //发送数据  这里注意要带上编码utf-8  不然 不能传递中文参数过去
                out.write(data.getBytes("UTF-8"));
                //判断请求成功
                if(httpConn.getResponseCode() == 200){
                    System.out.println("调用成功.....");
                    //获得输入流
                    InputStream in = httpConn.getInputStream();
                    //使用输入流的缓冲区
                    BufferedReader reader = new BufferedReader(new InputStreamReader(in,"UTF-8"));
                    StringBuffer sb = new StringBuffer();
                    String line = null;
                    //读取输入流
                    while((line = reader.readLine()) != null){
                        sb.append(line);
                    }

                    //创建sax的读取器  这里需要导入相应的jar包
                    SAXReader saxReader = new SAXReader();
                    //创建文档对象
                    Document doc = saxReader.read(new StringReader(sb.toString()));
                    //获得请求响应return元素   这里可根据接口测试工具查看你的相应消息体的返回值的节点是什么名称 我这里是sayReturn
                    List eles = doc.selectNodes("//sayReturn");

                    for(int i=0;i<eles.size();i++){
                        Element ele = (Element)eles.get(i);
                        System.out.println(ele.getText());
                    }
                    System.out.println(sb.toString());
            }else{
          //调用不成功 打印错误的信息
                //获得输入流
                InputStream err = httpConn.getErrorStream();
                //使用输入流的缓冲区
                BufferedReader reader = new BufferedReader(new InputStreamReader(err,"UTF-8"));
                StringBuffer sb = new StringBuffer();
                String line = null;
                //读取输入流
                while((line = reader.readLine()) != null){
                    sb.append(line);
                }
                System.out.println("返回错误码:"+httpConn.getResponseCode());
                System.out.println("返回的结果:"+sb.toString());

            }
                } catch (Exception e) {
                    e.printStackTrace();
                }
}
}

  上面是客户端调用的代码,服务端这里就不多贴了,就只是一个方法,里面有一个String类型的参数。

  问题总结:

  1.报错误 说http response result code 500:

  java.io.IOException: Server returned HTTP response code: 500 for URL: http://10.203.138.82:8080/test_axis/services/sayHello
  at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1626)

  这里的500错误 一般都是你的代码有问题 哪里可能写的有点不对 这个时候就要仔细仔细再仔细 然后尝试用不同的方式去排除错误所在的地方 也要多百度 多查 ,这里我出现这个问题 是因为把输入流写在输出流的前面(对于客户端,应该是先写输出流之后,再写输入流get.InputStream())

  2.针对axis1.4的bug:AxisFault faultCode: {http://xml.apache.org/axis/}Client.NoSOAPAction faultSubcode:            faultString: no SOAPAction header! faultActor: faultNode: faultDetail: {http://xml.apache.org/axis/}stackTrace:no                         SOAPAction header!

no SOAPAction header!   这里可以注意 如果报这个错 加上一行代码就好了啦 当初为了这个错误 几乎看了一两天的博客文章  但是却没有人告诉具体的代码解决办法(有两种解决办法1:在客户端加上soapaction,其具体内容不重要,写一个空的字符串也是可以的 2:服务端重写写一个servlet,与axisServlet一样,并重新改写里面的getSoapAction()方法,这里推荐只第一种,毕竟这个也算不上是axis的bug)

  //设置 SOAPAction Header  不然 报错 没有这个soapaction header
      httpConn.setRequestProperty("SOAPAction", "");

  3.如果客户端传递参数为中文就报错:变为字节数组的时候加上UTF-8

  //获得输出流
     OutputStream out = httpConn.getOutputStream();
      //发送数据  这里注意要带上编码utf-8  不然 不能传递中文参数过去
       out.write(data.getBytes("UTF-8"));

  疑问:

  如果方法没有参数 需要怎么调用???在这里  之前 跨平台 调用wcf开发的.net系统的时候 调用的接口方法是不需要传递参数的 但是也传了一个空的字符串过去就好了  也没有写什么soap请求消息体什么的  但是这里因为是webservice 它是基于soap的 所以这里传递数据 不管有没有参数  应该都是要写上消息请求体的 所以这里需要注意一下

  比如:

// 但是为了保险 希望大家在写请求消息体的时候用 接口测试工具去获取比如soapui 然后直接复制过来
                      String data = "<soapenv:Envelope xmlns:soapenv=" +
                        "\"http://schemas.xmlsoap.org/soap/envelope/\" " +
                        "xmlns:ser=\"http://server.hue.edu/\" " +
                        "xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" " +
                        "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">"
                        +"<soapenv:Header />"
                        +"<soapenv:Body>"
                        +"<ser:say >"
                        //比如这里要调用的方法没有参数 就直接不用写就好 但是这个消息体 应该还是要的
                        +"</ser:say>"
                        +"</soapenv:Body>"
                      +"</soapenv:Envelope>";
时间: 2024-10-13 12:33:41

使用URLConnection调用axis1.4开发的webservice的相关文章

spring WebServiceTemplate 调用 axis1.4 发布的webservice

 前言: 最近在开发中需要调用对方的 webservice服务,按照现有的技术,本应该是一件很简单的事情,只需要拿到wsdl文件,生成客户端代码即可,但是,对方的webservice服务是06年用axis1.4生成发布的,wsdl文件只能用zxis1.4生产客户端代码,而axis的jar包和程序部署环境WebSphere8.5冲突,导致程序无法启动.spring的WebServiceTemplate可以在was环境下使用,所以,写一下spring如何手动编写客户端代码,调用axis1.4的服务端

服务器端获取客户端的IP地址(当客户端调用由Axis开发的WebService)

一.前言 由于项目中一个小的模块需要获取客户端的IP地址以保证安全调用webservice接口,项目中客户端使用C#编写,服务器端使用Java编写,服务器端与客户端采用Axis开发的WebService进行通信.服务器端维护IP白名单列表,只有IP地址在白名单中的客户端才可以成功调用到接口,获得服务. 二.代码清单 若要成功获取客户端IP地址,需要如下Jar包的支持. servlet-api.jar axis.jar axis2-kernel-1.6.2.jar 获取IP地址的具体代码如下: i

用C#.NET调用Java开发的WebService传递int,double问题,出现java无法获得值!

用C#.NET调用Java开发的WebService时,先在客户端封装的带有int属性的对象,当将该对象传到服务器端时,服务器端可以得到string类型的属性值,却不能得到int类型.double和DateTime类型的值(在服务端得到的均为null) 解决办法: VS2005封装WebService引用 用C#.NET调用Java开发的WebService时,先在客户端封装的带有int属性的对象,当将该对象传到服务器端时,服务器端可以得到string类型的属性值,却不能得到int类型.doub

用C#.NET调用Java开发的WebService传递int,double问题,出现java无法获

用C#.NET调用Java开发的WebService传递int,double问题,出现java无法获得值! 用C#.NET调用Java开发的WebService时,先在客户端封装的带有int属性的对象,当将该对象传到服务器端时,服务器端可以得到string类型的属性值,却不能得到int类型.double和DateTime类型的值(在服务端得到的均为null) 解决办法: VS2005封装WebService引用 用C#.NET调用Java开发的WebService时,先在客户端封装的带有int属

从零开始学android开发-通过WebService进行网络编程,使用工具类轻松实现

相信大家在平常的开发中,对网络的操作用到HTTP协议比较多,通过我们使用Get或者Post的方法调用一个数据接口,然后服务器给我们返回JSON格式的数据,我们解析JSON数据然后展现给用户,相信很多人很喜欢服务器给我们返回JSON数据格式,因为他解析方便,也有一些JSON的解析库,例如Google提供的GSON,阿里巴巴的FastJson,不过还是推荐大家使用FastJson来解析,我自己开发中也是用FastJson来解析,FastJson的介绍http://code.alibabatech.c

开发RESTful WebService

RESTful风格的webservice越来越流行了,sun也推出了RESTful WebService的官方规范:JAX-RS,全称:Java API for RESTful WebService.该规范定义了一系列的注解 RESTful简化了web service的设计,它不再需要wsdl,也不再需要soap协议,而是通过最简单的http协议传输数据(包括xml或json).既简化了设计,也减少了网络传输量(因为只传输代表数据的xml或json,没有额外的xml包装) 下面为大家介绍使用cx

如何在Delphi中调用VC6.0开发的COM

上次写了如何在VC6.0下对Delphi写的COM进行调用,原本想马上写如何在Delphi中调用VC6.0开发的COM时,由于在写事例程序中碰到了个很怪的问题,在我机子上用VC写的接口程序编译能通过.但是调用就会出现问题,(在VC下调用也是一样的出现).但是用Delphi写的接口程序编译后,不管是在VC下还是在Delphi下调用都没有问题.后来我把VC开发的接口程序编译后,拷贝到其它机子上试,怪事,完全没有问题了.总结后才知道是我机子有点问题.我到现在还没有解决为什么在我的机子上不行,在其它机子

Oracle数据库中调用Java类开发存储过程、函数的方法

Oracle数据库中调用Java类开发存储过程.函数的方法 时间:2014年12月24日  浏览:5538次 oracle数据库的开发非常灵活,不仅支持最基本的SQL,而且还提供了独有的PL/SQL,除此之外,还可以用时下最流行的编程语言Java来做开发.随着对oracle的了解越来越多,越来越禁不住oracle的诱惑,oracle技术真的是一门很有趣的学问.之前,我在博客中总结了挺多有关SQL.PL/SQL的,但是对于oracle数据库中Java类的调用却没有总结,也是因为之前不太会,这会儿总

myeclipse调用loadrunner函数开发测试脚本

myeclipse调用loadrunner函数开发测试脚本 一.使用myeclipse开发性能测试脚本 1.使用Eclipse新建一个Java工程,将目录%LoadRunner_Home%\classes\lrapi文件复制到java工程中,并打成jar包. 操作步骤:Java工程名称右键->Export->Java->Java file,next下一步选择保存位置. 2.新建Java工程,将lrapi.jar引入扩展库中 操作步骤:目标工程名右键->Build Path->