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;

}

}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值