`
yunchow
  • 浏览: 318577 次
  • 性别: Icon_minigender_1
  • 来自: 南京
社区版块
存档分类
最新评论

HttpUrlConnection 发送 SOAP 请求,SAX 解析 SOAP 响应

阅读更多
HttpUrlConnection 发送 SOAP 请求,SAX 解析 SOAP 响应

并附上抓包工具:wireshark


/*
 * Socket远程调用Web服务实现,并用SAX解析XML文件,适用于性能要求较高场合
 */
package com.mypack.soap.client;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.StringReader;
import java.net.HttpURLConnection;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.Stack;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.xml.sax.Attributes;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.DefaultHandler;
import org.xml.sax.helpers.XMLReaderFactory;

/**
 * 为了提高WebService调用效率,因此手Socket自已实现,无需依赖任何Soap引擎
 * @version 1.0
 * @date 2010-08-21
 */
public final class SoapClientAsHttpUrlConnection
{
    /**
     * apache 日志记录器,底层可切换实现
     */
    private static Log logger = LogFactory.getLog(SoapClientAsHttpUrlConnection.class);
    
    /**
     * 为了简单直接写了,最好单独写一方法并采用 Executors 启动线程,将返回值加入 BlockingQueue
     */
    public static void main(String[] args) throws URISyntaxException, IOException, SAXException
    {
        // soap request string
        final String soapReuqest = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"><soapenv:Body><ns1:queryUser soapenv:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\" xmlns:ns1=\"http://services.zhang.com\"><in0 xsi:type=\"ns2:UserInfo\" xsi:nil=\"true\" xmlns:ns2=\"http://tdo.zhang.com\"/></ns1:queryUser></soapenv:Body></soapenv:Envelope>";
        
        // Web 服务所在的地址
        URI uri = new URI("http://10.40.51.156:28888/testSoap/services/UserManage");
        URL url = uri.toURL();
        
        // 打开连接
        HttpURLConnection httpUrlConnection = (HttpURLConnection) url.openConnection();
        
        // 可读取
        httpUrlConnection.setDoInput(true);
        httpUrlConnection.setDoOutput(true);
        httpUrlConnection.setRequestMethod("POST");
        
        // set request header
        httpUrlConnection.setRequestProperty("SOAPAction", "");
        //httpUrlConnection.setRequestProperty("Content-Length", soapReuqest.length() + "");
        
        OutputStream os = httpUrlConnection.getOutputStream();
        PrintWriter out = new PrintWriter(os);
        
        out.println(soapReuqest);
        out.flush();
        
        StringBuilder sb = new StringBuilder();
        
        // http status ok
        if (HttpURLConnection.HTTP_OK == httpUrlConnection.getResponseCode())
        {
            if (logger.isDebugEnabled())
            {
                logger.debug("HTTP_OK");
            }
            
            InputStream is = httpUrlConnection.getInputStream();
            BufferedReader br = new BufferedReader(new InputStreamReader(is));
            
            for (String line = br.readLine(); line != null; line = br.readLine())
            {
                sb.append(line);
            }
            is.close();
        }
        
        // Release resource
        os.close();
        out.close();
        httpUrlConnection.disconnect();
        
        String soapResponse = sb.toString();
        
        System.out.println(soapResponse);
        
        // parse the soap response
        // 底层是xces解析器,效率较高
        XMLReader xmlReader = XMLReaderFactory.createXMLReader();
        
        SimpleHandler handler = new SimpleHandler();
        xmlReader.setContentHandler(handler);
        
        InputSource inputSource = new InputSource(new StringReader(soapResponse));
        try
        {
            xmlReader.parse(inputSource);
        }
        catch (ExtSAXException e)
        {
        }
        
        // 便于演示,直接打出,生产环境请匆如此使用,可用日志进行 debug
        System.out.println("Response is " + handler.response);
    }
    
    /**
     * SAX 处理器,底层运用观察者模式
     * 对于XML这种结构,运用栈进行存储
     * 如果解析到目标串,利用抛出自定义异常来提前终止操作,提高效率
     */ 
    private static class SimpleHandler extends DefaultHandler
    {
        /**
         * 用栈缓存上下文信息
         */
        private final Stack<String> stack = new Stack<String>();

        private String response;
        
        /**
         * 每次传递 16K 数据,这一点很重要,但是在这里只需要一个串,因此忽略
         */
        @Override
        public void characters(char[] ch, int start, int length)
                throws SAXException
        {
            if (!stack.empty() && "queryUserReturn".equals(stack.pop()))
            {
                response = new String(ch, start, length);
                
                // 抛出异常,结束解析
                throw new ExtSAXException();
            }
        }

        /**
         * 元素开始自动触发,将开始标签压栈缓存
         */
        @Override
        public void startElement(String uri, String localName, String name,
                Attributes atts) throws SAXException
        {
            if ("queryUserReturn".equals(localName))
            {
                stack.push(localName);
            }
        }

    }
    
    /**
     * 自定义异常,用于终止解析任务
     */
    private static class ExtSAXException extends SAXException
    {
        private static final long serialVersionUID = 1L;
        
    }
    
}

6
0
分享到:
评论
4 楼 yanliyun 2013-12-13  
这几个案例也下载下来损害
3 楼 yanliyun 2013-12-13  
楼主这个在我控制台输出 Response is null什么情况,能不能告诉详细怎么用的
2 楼 tojaoomy 2012-04-26  
还需要在
httpUrlConnection.setRequestProperty("SOAPAction", "");
后添加httpUrlConnection.setRequestProperty("Content-type", "text/xml");
才会成功。
1 楼 playingfly 2011-12-28  
   好文! 很经典!

相关推荐

Global site tag (gtag.js) - Google Analytics