我们完全可以利用J2SE中的HttpURLConnection类来实现SOAP调用,而不一定需要AXIS之类的第三方组件包。下面就来仔细讲解:
        通过HttpURLConnection来实现SOAP调用,无非就是向远端的WEB Service发出HTTP请求,请求的过程通过双方可以理解的XML格式流来传递数据信息。我以下面的SOAP请求的XML格式为基础来讲解:

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

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:SmInf="http://jx.ct10000.com/SmInf"> 

 <soapenv:Header /> 

 <soapenv:Body> 

  <tns:SendInstantSms xmlns:tns="SmInf" soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"> 

   <sequenceId type="xsd:long">1</sequenceId> 

   <accountCode type="xsd:string">user_id</accountCode> 

   <accountPasswd type="xsd:string">user_password</accountPasswd> 

   <sendPhoneNo type="xsd:string">1234567890</sendPhoneNo> 

   <msgContent type="xsd:string">7D27 6025 901A 77E5 FF1A 7279 522B 7D27 6025 FF0C 5341 4E07 706B 6025 002E</msgContent> 

   <recvPhoneNo type="xsd:string">1234567890</recvPhoneNo> 

   <scheduleTime type="xsd:dateTime">2000-10-10T09:35:12.123</scheduleTime> 

  </tns:SendInstantSms> 

 </soapenv:Body> 

</soapenv:Envelope>


        这个SOAP请求包格式并不能完全通用于任何场合,大家具体实现某个SOAP调用时,需要根据具体情况进行调整,可以通过Web Service服务提供商获取详情。
        通过HttpURLConnection实现SOAP调用的过程简要概述如下:
        1、拼接实现如上所示的SOAP请求包的XML格式的字符流;
        2、上面讲到过SOAP调用就是一个HTTP请求,因此通过HttpURLConnection类设置相应的请求属性;
        3、通过HttpURLConnection类的getOutputStream方法获得一个输出流,然后将SOAP请求包字符流写入此输出流;
        4、通过HttpURLConnection类的getResponseCode方法获得服务器响应代码,如果响应代码为200(即HttpURLConnection.HTTP_OK)则表示请求成功,否则请求失败,请求失败后,可以通过getErrorStream方法来了解具体的错误详情;
        5、通过HttpURLConnection类的getInputStream方法获得一个输入流,由此输入流获得服务器反馈结果数据;
        大体通过HttpURLConnection实现SOAP调用的过程就是这样。下面来看具体实现代码:
        编写CSOAPClient类,并定义成员变量_url和_httpConn,在构造函数中对其进行实例化。
       _url=new URL(url);          //这里url变量是SOAP服务的网址,如http://10.5.3.134/Webservices/methods1?wsdl
       _httpConn = (HttpURLConnection) _url.openConnection();   //这里就是获得一个SOAP服务的HttpURLConnection实例
       String send_soap=createSendSOAPPackage();    //createSendSOAPPackage函数就是用来构造如上所示SOAP请求的数据包的XML字符串
       _httpConn.setReadTimeout(TIME_OUT);        //为HttpURLConnection对象指定一个读超时
       _httpConn.setRequestProperty("User-Agent","Mozilla/4.0 (compatible; MSIE 5.0; Windows XP; DigExt)");
       _httpConn.setRequestProperty( "Content-Length",String.valueOf( send_soap.length() ) );
       _httpConn.setRequestProperty("Content-Type","text/xml; charset=UTF-8");
       _httpConn.setRequestProperty("SOAPAction",_soap_action_str);
       //以上都是为HTTP请求设定请求属性,其中SOAPAction中用来指定SOAP Action的字符串。
       _httpConn.setRequestMethod( "POST" );   //为请求指定提交数据模式,对于调用Web Service来说请求模式要被设置成POST模式。
       _httpConn.setDoInput(true);
        _httpConn.setDoOutput(true);
        _httpConn.setUseCaches(false);
       _httpConn.connect();  //连接远程Url

       OutputStream out = _httpConn.getOutputStream();   //获取输出流对象
        out.write( send_soap.getBytes() );       //将要提交服务器的SOAP请求字符流写入输出流
        out.flush();
        out.close();

       int code=0;
        code = _httpConn.getResponseCode();    //用来获取服务器响应状态
       if (code == HttpURLConnection.HTTP_OK) {
            //服务器响应状态表示成功,这此处可以来获取服务器反馈的数据信息
            InputStream is=_httpConn.getInputStream();    //获取输入流对象,通过此对象可以获取服务器传回的数据信息
            InputStreamReader isr = new InputStreamReader(is,"utf-8");
            Document _doc=_sax.build(isr);     //此处Document是jdom中的类,因为要解析服务器传回的xml数据
            Element _root = _doc.getRootElement();  //此处Element是jdom中的类
            ......(略)
           
       }
       else{
            //如果服务器返回的HTTP状态不是HTTP_OK,则表示发生了错误,此时可以通过如下方法了解错误原因。
            InputStream is=_httpConn.getErrorStream();    //通过getErrorStream了解错误的详情,因为错误详情也以XML格式返回,因此也可以用JDOM来获取。
            InputStreamReader isr = new InputStreamReader(is,"utf-8");
            Document _doc=_sax.build(isr);     //此处Document是jdom中的类,因为要解析服务器传回的xml数据
            Element _root = _doc.getRootElement();  //此处Element是jdom中的类
            ......(略)
       }
       以上就是通过HttpURLConnection调用SOAP的简介。
      下面附上实现类的代码,供参考(未优化,大家使用时要优化一下)
1、CSOAPClient
 

package util; 


import java.io.OutputStream; 

import java.net.HttpURLConnection; 

import java.net.URL; 

import java.util.Hashtable; 

import java.util.LinkedList; 

import java.util.Set; 

import org.jdom.Attribute; 

import org.jdom.Document; 

import org.jdom.Element; 

import org.jdom.Namespace; 

import org.jdom.output.Format; 

import org.jdom.output.XMLOutputter; 


/** 

 * 

 * @author zhaob 

 */ 

public class CSOAPClient { 

    private static int TIME_OUT=15000; 

     

    private URL _url = null; 

    private String _service_id=null; 

    private String _method=null; 

    private String _soap_action_str=null; 

    private LinkedList<NParam> _params = new LinkedList<NParam>(); 

    private HttpURLConnection _httpConn=null; 


    private String _root_master_namespace_name=null; 

    private Hashtable<String,String> _root_namespace=new Hashtable<String,String>(); 

    private boolean _setted_root_master_namespace_flag=false; 


    private boolean _hasHead=true; 

    private boolean _hasParamType=true; 


    private Hashtable<String,String> _method_attrib=new Hashtable<String,String>(); 

    private Hashtable<String,String> _method_attrib_namespace=new Hashtable<String,String>(); 

    private Hashtable<String,String> _methodattrib_namespace=new Hashtable<String,String>(); 

    private Hashtable<String,String> _methods_namespace=new Hashtable<String,String>(); 


    public CSOAPClient(String url,String service_id,String method,String soap_action) throws Exception { 

        _url=new URL(url);          //SOAP服务的网址 

        if((service_id==null)||(service_id.trim().equals(""))){ 

            _service_id=null; 

        } 

        else{ 

            _service_id=service_id; 

        } 

         

        _method=method; 

        _soap_action_str=soap_action; 

        createSocket(); 

         

    } 


    public void setHasParamType(boolean v){ 

        _hasParamType=v; 

    } 


    public void setHasHead(boolean v){ 

        _hasHead=v; 

    } 


    protected void createSocket() throws Exception { 

        if(_httpConn==null){ 

//            Properties systemProperties = System.getProperties(); 

//            systemProperties.setProperty("http.proxyHost","192.168.1.1"); 

//            systemProperties.setProperty("http.proxyPort","8080"); 

            _httpConn = (HttpURLConnection) _url.openConnection();; 

             

        } 

    } 


    public void addParams(String params_name,Object v,EParamType type){ 

        NParam np=new NParam(params_name,v,type); 

        _params.add(np); 

    } 


    public void addMethodNamespace(String namespace_name,String namespace_v){ 

        _methods_namespace.put(namespace_name,namespace_v); 

    } 


    public void addMethodAttrib(String attrib_name,String v,String namespace_name,String namespace_v){ 

        _method_attrib.put(attrib_name, v); 

        _method_attrib_namespace.put(attrib_name, namespace_name); 

        _methodattrib_namespace.put(namespace_name,namespace_v); 

    } 


    public void addMethodAttrib(String attrib_name,String v){ 

        _method_attrib.put(attrib_name, v); 

    } 


    public void setRootMasterNamespace(){ 

        if(!_setted_root_master_namespace_flag){ 

            _root_master_namespace_name="soapenv"; 

            _root_namespace.put(_root_master_namespace_name, "http://schemas.xmlsoap.org/soap/envelope/"); 

            _setted_root_master_namespace_flag=true; 

        } 

    } 


    public void setRootMasterNamespace(String name){ 

        if(!_setted_root_master_namespace_flag){ 

            _root_master_namespace_name=name; 

            _root_namespace.put(_root_master_namespace_name, "http://schemas.xmlsoap.org/soap/envelope/"); 

            _setted_root_master_namespace_flag=true; 

        } 

    } 


    public void addRootNamespace(String name,String v){ 

        _root_namespace.put(name, v); 

    } 


    public String createSendSOAPPackage(){ 

        Hashtable<String,Namespace> namespace_set=new Hashtable<String,Namespace>(); 

        // 创建根节点 root; 

        Element root = new Element("Envelope"); 

        Set<String> sets=_root_namespace.keySet(); 

        Namespace master_namespace=null; 

        for(String s:sets){ 

            String v=_root_namespace.get(s); 

            Namespace sn=Namespace.getNamespace(s, v); 

            namespace_set.put(s, sn); 

            if(s.equals(_root_master_namespace_name)){ 

                root.setNamespace(sn); 

                master_namespace=sn; 

            } 

            else{ 

                root.addNamespaceDeclaration(sn); 

            } 

             

        } 

         

        // 根节点添加到文档中; 

        Document doc = new Document(root); 


        if(_hasHead){ 

            //创建Header节点 

            Element head=new Element("Header"); 

            head.setNamespace(master_namespace); 

            //加入根节点 

            root.addContent(head); 

        } 

         

        //创建Body节点 

        Element body=new Element("Body"); 

        body.setNamespace(master_namespace); 

        //加入根节点 

        root.addContent(body); 


        //创建调用的方法节点 

        Element method=new Element(_method); 

        body.addContent(method); 

        Set<String> method_attrib_set=_method_attrib.keySet(); 

        boolean flag=false; 

        Namespace ns=null; 

                 

        for(String attrib_name:method_attrib_set){ 

            String attrib_v=_method_attrib.get(attrib_name); 

            flag=_method_attrib_namespace.containsKey(attrib_name); 

            if(flag){ 

                String namespace_name=_method_attrib_namespace.get(attrib_name); 

                flag=namespace_set.containsKey(namespace_name); 

                if(flag){ 

                    ns=namespace_set.get(namespace_name); 

                     

                } 

                else{ 

                    String namespace_v=_methodattrib_namespace.get(namespace_name); 

                    ns=Namespace.getNamespace(namespace_name, namespace_v); 

                    method.setNamespace(ns); 

                    namespace_set.put(namespace_name, ns); 

                } 

                Attribute attrib=new Attribute(attrib_name, attrib_v,ns); 

                method.setAttribute(attrib); 

            } 

            else{ 

                Attribute attrib=new Attribute(attrib_name, attrib_v); 

                method.setAttribute(attrib); 

            } 

        } 

        Set<String> methods_attrib=_methods_namespace.keySet(); 

        for(String namespace_name:methods_attrib){ 

            flag=namespace_set.containsKey(namespace_name); 

            if(flag){ 

                 

            } 

            else{ 

                String namespace_v=_methods_namespace.get(namespace_name); 

                ns=Namespace.getNamespace(namespace_name, namespace_v); 

                method.setNamespace(ns); 

                namespace_set.put(namespace_name, ns); 

            } 

        } 

        if(_service_id!=null){ 

            Namespace nsl=Namespace.getNamespace("tns", _service_id); 

            method.setNamespace(nsl); 

        } 

         

        //创建调用方法的参数节点 

        int count=_params.size(); 

        for(int i=0;i<count;i++){ 

            NParam np=_params.get(i); 

            String param_name=np.getName(); 

            String param_value=np.getValue().toString(); 

            String param_type=np.getType().getValue(); 


            Element param=new Element(param_name); 

            method.addContent(param); 

            param.setText(param_value); 

            if(_hasParamType){ 

                Attribute param_attrib=new Attribute("type", param_type); 

                param.setAttribute(param_attrib); 

            } 

             

             

        } 


        //定义输出 

        XMLOutputter XMLOut = new XMLOutputter(); 

        //设置格式 

        Format format = Format.getPrettyFormat(); 

        format.setEncoding("UTF-8"); //设置 xml文件的字符为UTF-8 

        format.setIndent(" "); //设置xml文件的缩进为4个空格 

        XMLOut.setFormat(format); 


        return XMLOut.outputString(doc); 

    } 


    public CXML call() throws Exception { 

        String send_soap=createSendSOAPPackage(); 

        System.out.println("Request XML:"); 

        System.out.println(send_soap); 


        _httpConn.setReadTimeout(TIME_OUT); 

        _httpConn.setRequestProperty("User-Agent","Mozilla/4.0 (compatible; MSIE 5.0; Windows XP; DigExt)"); 

        _httpConn.setRequestProperty( "Content-Length",String.valueOf( send_soap.length() ) ); 

        System.out.println("Content-Length:"+String.valueOf( send_soap.length() )); 

        _httpConn.setRequestProperty("Content-Type","text/xml; charset=UTF-8"); 

        System.out.println("Content-Type:text/xml; charset=UTF-8"); 

//        _httpConn.setRequestProperty("soapActionString",_soap_action_str); 

        _httpConn.setRequestProperty("SOAPAction",_soap_action_str); 

        System.out.println("SOAPAction:"+_soap_action_str); 

        _httpConn.setRequestMethod( "POST" ); 

        System.out.println("Request Method:POST"); 

        _httpConn.setDoInput(true); 

        _httpConn.setDoOutput(true); 

        _httpConn.setUseCaches(false); 

         

        _httpConn.connect(); 

         

        OutputStream out = _httpConn.getOutputStream(); 

        out.write( send_soap.getBytes() ); 

        out.flush(); 

        out.close(); 


        int code=0; 

        code = _httpConn.getResponseCode(); 

        CXML xmlobj=null; 

        if (code == HttpURLConnection.HTTP_OK) { 

            xmlobj=new CXML(_httpConn.getInputStream(),_root_master_namespace_name,_root_namespace.get(_root_master_namespace_name)); 

             

        } 

        else{ 

            System.out.println("Response Code: "+String.valueOf(code)); 


            xmlobj=new CXML(_httpConn.getErrorStream(),_root_master_namespace_name,_root_namespace.get(_root_master_namespace_name)); 

             

            System.out.println("错误详情: "); 

            String faultcode=xmlobj.getElementTextByXPath("/soapenv:Envelope/soapenv:Body/soapenv:Fault/faultcode"); 

            System.out.println("错误代码: "+faultcode); 

            String faultstring=xmlobj.getElementTextByXPath("/soapenv:Envelope/soapenv:Body/soapenv:Fault/faultstring"); 

            System.out.println("错误描述: "+faultstring); 

             

        } 

         

        return xmlobj; 

    } 


    public void destroy(){ 

        if(_httpConn!=null){ 

           _httpConn=null; 


        } 

    } 


    public String toUTF8(String str) { 

         if ("".equals(str)) { 

             return ""; 

         } 


         StringBuffer strBuff = new StringBuffer(""); 

         try { 

             byte b[] = str.getBytes("UTF-16"); 

             for (int n = 0; n < b.length; n++) { 

                 str = (Integer.toHexString(b[n] & 0XFF)); 

                 if (str.length() == 1) { 

                     strBuff.append("0").append(str); 

                 } else { 

                     strBuff.append(str); 

                 } 

             } 


             // 去除第一个标记字符 

             str = strBuff.toString().toUpperCase().substring(4); 

             // System.out.println(str); 

             char[] chs = str.toCharArray(); 

             strBuff.delete(0, strBuff.length()); 

             for (int i = 0; i < chs.length; i = i + 4) { 

                 strBuff.append(chs[i]) 

                        .append(chs[i + 1]) 

                        .append(chs[i + 2]) 

                        .append(chs[i + 3]) 

                        .append(" "); 

             } 

         } catch (Exception e) { 

             System.out.print(e.getStackTrace()); 

             e.getStackTrace(); 

         } 


         return strBuff.toString(); 

     } 


    public final class NParam { 

        private String _name=null; 

        private Object _value=null; 

        private EParamType _type=null; 


        public NParam(String name,Object value,EParamType type){ 

            _name=name; 

            _value=value; 

            _type=type; 

        } 


        public String getName() { 

            return _name; 

        } 


        public EParamType getType() { 

            return _type; 

        } 


        public Object getValue() { 

            return _value; 

        } 

         

    } 


    public enum EParamType{ 

        String("xsd:string"),Integer("xsd:integer"),Long("xsd:long"),Datetime("xsd:dateTime"); 

        private final String _v; 

        private EParamType(String v) { 

            this._v = v; 

        } 

        public String getValue() { 

            return _v; 

        } 

    } 

} 


2、CXML 

  

package util; 


import java.io.InputStream; 

import java.io.InputStreamReader; 

import org.jdom.Document; 

import org.jdom.Element; 

import org.jdom.Namespace; 

import org.jdom.input.SAXBuilder; 

import org.jdom.output.Format; 

import org.jdom.output.XMLOutputter; 

import org.jdom.xpath.XPath; 


/** 

 * 

 * @author zhaob 

 */ 

public class CXML { 


    private SAXBuilder _sax=new SAXBuilder(); 

    private Document _doc=null; 

    private Element _root = null; 

    private Namespace _master_namespace=null; 


    public CXML(InputStream is,String namespace_name,String namespace_v) throws Exception { 

        InputStreamReader isr = new InputStreamReader(is,"utf-8"); 

        _doc=_sax.build(isr); 

        _root = _doc.getRootElement(); 

        _master_namespace=Namespace.getNamespace(namespace_name, namespace_v); 


    } 


    public String getElementTextByXPath(String xpath) throws Exception { 

        String rtn=null; 


        XPath xpathobj=XPath.newInstance(xpath); 

        xpathobj.addNamespace(_master_namespace); 

        Element obj=(Element)xpathobj.selectSingleNode(_doc); 

        rtn=obj.getTextTrim(); 


        return rtn; 

    } 


    public String toString(){ 

        XMLOutputter o=new XMLOutputter(); 

        //设置格式 

        Format format = Format.getPrettyFormat(); 

        format.setEncoding("UTF-8"); //设置 xml文件的字符为UTF-8 

        format.setIndent(" "); //设置xml文件的缩进为4个空格 

        o.setFormat(format); 

        String xmlstr=o.outputString(_doc); 

         

        return xmlstr; 

    } 

} 


3、CSOAPClinetTest   这是一个JUNIT的测试类,看其中RUN方法即可。 

  

package util; 


import java.util.List; 

import org.junit.After; 

import org.junit.AfterClass; 

import org.junit.Before; 

import org.junit.BeforeClass; 

import org.junit.Test; 

import util.CSOAPClient.EParamType; 


/** 

 * 

 * @author zhaob 

 */ 

public class CSOAPClinetTest { 


    public CSOAPClinetTest() { 

    } 


    @BeforeClass 

    public static void setUpClass() throws Exception { 

    } 


    @AfterClass 

    public static void tearDownClass() throws Exception { 

    } 


    @Before 

    public void setUp() { 

    } 


    @After 

    public void tearDown() { 

    } 


    // TODO add test methods here. 

    // The methods must be annotated with annotation @Test. For example: 

    // 

    // @Test 

    // public void hello() {} 


    @Test 

    public void run(){ 

        CSOAPClient soap_client=null; 


        try{ 

            soap_client=new CSOAPClient("http://10.20.4.21:8080/Webservices/SmsInf","SmInf","SendInstantSms","http://w.rr.com/SmsInf/SendInstantSms"); 

        } 

        catch(Exception e){ 

            System.out.println("Error:"+e.getMessage()); 

        } 

        if(soap_client!=null){ 

            soap_client.setHasHead(true); 

            soap_client.setRootMasterNamespace("soapenv"); 

            soap_client.addRootNamespace("SmInf", "http://x.rr.com/SmInf"); 

            soap_client.addMethodAttrib("encodingStyle", "http://schemas.xmlsoap.org/soap/encoding/","soapenv",""); 

            soap_client.setHasParamType(true); 


            soap_client.addParams("sequenceId", 2, EParamType.Long); 

            soap_client.addParams("accountCode", "user_id", EParamType.String); 

            soap_client.addParams("accountPasswd", "user_password", EParamType.String); 

            soap_client.addParams("sendPhoneNo", "1234567890", EParamType.String); 

            soap_client.addParams("msgContent", soap_client.toUTF8("紧急通知:特别紧急,十万火急."), EParamType.String); 

            soap_client.addParams("recvPhoneNo", "07919999999", EParamType.String); 

            soap_client.addParams("scheduleTime", "2000-10-10T09:35:12.123", EParamType.Datetime); 


            try{ 

                CXML xmlobj=soap_client.call(); 

                System.out.println("返回的XML:"); 

                System.out.println(xmlobj.toString()); 

            } 

            catch(Exception e){ 

                System.out.println("Error:"+e.getMessage()); 

            } 


        } 

    } 

}


4、注意:运行此代码需要加入JDOM的全部lib目录下的包,否则使用XPATH时将报告错误。
如果还有什么疑问,可直接联系我。