发送Soap消息并获取响应
2017-04-13 10:45
162 查看
SOAP
如下:
总结:
a:) HttpURLConnection的connect()函数,实际上只是建立了一个与服务器的tcp连接,并没有实际发送http请求。
无论是post还是get,http请求实际上直到HttpURLConnection的getInputStream()这个函数里面才正式发送出去。
b:) 在用POST方式发送URL请求时,URL请求参数的设定顺序是重中之重,
对connection对象的一切配置(那一堆set函数)都必须要在connect()函数执行之前完成。而对outputStream的写操作,又必须要在inputStream的读操作之前。
这些顺序实际上是由http请求的格式决定的。
如果inputStream读操作在outputStream的写操作之前,会抛出例外:
java.net.ProtocolException: Cannot write output after reading input.......
c:) http请求实际上由两部分组成,
一个是http头,所有关于此次http请求的配置都在http头里面定义,一个是正文content。
connect()函数会根据HttpURLConnection对象的配置值生成http头部信息,因此在调用connect函数之前,
就必须把所有的配置准备好。
d:) 在http头后面紧跟着的是http请求的正文,正文的内容是通过outputStream流写入的,实际上outputStream不是一个网络流,充其量是个字符串流,往里面写入的东西不会立即发送到网络,而是存在于内存缓冲区中,待outputStream流关闭时,根据输入的内容生成http正文。至此,http请求的东西已经全部准备就绪。在getInputStream()函数调用的时候,就会把准备好的http请求正式发送到服务器了,然后返回一个输入流,用于读取服务器对于此次http请求的返回信息。由于http请求在getInputStream的时候已经发送出去了(包括http头和正文),因此在getInputStream()函数之后对connection对象进行设置(对http头的信息进行修改)或者写入outputStream(对正文进行修改)都是没有意义的了,执行这些操作会导致异常的发生。
XML:
获取错误消息可以通过异常流urlConn.getErrorStream()。
详细参考:http://www.cnblogs.com/guodongli/archive/2011/04/05/2005930.html
SOAPUtil.rar (4.5 MB)
下载次数: 66
如下:
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.PrintWriter; import java.net.HttpURLConnection; import java.net.URL; import java.util.regex.Matcher; import java.util.regex.Pattern; /** * 该类可以将一个soap消息发送至服务端,并获取响应的soap消息 * */ public class SoapUtil { public static String invokeSrv(String endpoint,String action, String soapXml) throws IOException{ StringBuilder sb = new StringBuilder(); String method = "POST"; String contentType = "text/xml;charset=UTF-8"; URL url = new URL(endpoint); HttpURLConnection urlConn = (HttpURLConnection) url.openConnection(); // POST请求 urlConn.setRequestMethod(method); // 设置要发送消息 urlConn.setDoOutput(true); // 设置要读取响应消息 urlConn.setDoInput(true); // POST不能使用cache urlConn.setUseCaches(false); urlConn.setInstanceFollowRedirects(true); urlConn.setRequestProperty("SOAPAction", action); urlConn.setRequestProperty("Content-Type", contentType); urlConn.setRequestProperty("@test_flag", "Y"); urlConn.connect(); // 向输出流写出数据,这些数据将存到内存缓冲区中 PrintWriter pw = new PrintWriter(urlConn.getOutputStream()); pw.write(soapXml); // 刷新对象输出流,将任何字节都写入潜在的流中 pw.flush(); // 关闭流对象。此时,不能再向对象输出流写入任何数据,先前写入的数据存在于内存缓冲区中, // 在调用下边的getInputStream()函数时才把准备好的http请求正式发送到服务器 pw.close(); // 接收返回消息 // 解析返回值编码格式 String charset = "UTF-8"; String ct = urlConn.getContentType(); Pattern p = Pattern.compile("charset=.*;?"); Matcher m = p.matcher(ct); if(m.find()){ charset = m.group(); // 去除charset=和;,如果有的话 if(charset.endsWith(";")){ charset = charset.substring(charset.indexOf("=") + 1, charset.indexOf(";")); }else{ charset = charset.substring(charset.indexOf("=") + 1); } // charset = "\"UTF-8\""; // 去除引号 ,如果有的话 if(charset.contains("\"")){ charset = charset.substring(1, charset.length() - 1); } charset = charset.trim(); } // 将内存缓冲区中封装好的完整的HTTP请求电文发送到服务端。 // <===注意,实际发送请求的代码段就在这里 InputStream inStream = urlConn.getInputStream(); BufferedReader br = new BufferedReader(new InputStreamReader(inStream,charset)); String line; while((line = br.readLine()) != null){ sb.append(line); } br.close(); urlConn.disconnect(); return sb.toString(); } public static void main(String[] args) { String endpoint = "http://localhost:8088/ESB_YS_YS_InquiryEventsReferralsInfoSrv/ESBYSYSInquiryEventsReferralsInfoSrvImpl"; StringBuffer sb = new StringBuffer(); InputStream in = null; BufferedReader bf = null; try { in = SoapUtil.class.getClassLoader().getResourceAsStream("soapRequest.xml"); bf = new BufferedReader(new InputStreamReader(in)); String line = ""; while( (line = bf.readLine()) != null){ sb.append(line).append("\n"); } //输入请求 System.out.println(sb.toString()); System.out.println("------------------------------------------"); //返回请求 System.out.println(invokeSrv(endpoint,"process",sb.toString())); } catch (IOException e) { e.printStackTrace(); } } }
总结:
a:) HttpURLConnection的connect()函数,实际上只是建立了一个与服务器的tcp连接,并没有实际发送http请求。
无论是post还是get,http请求实际上直到HttpURLConnection的getInputStream()这个函数里面才正式发送出去。
b:) 在用POST方式发送URL请求时,URL请求参数的设定顺序是重中之重,
对connection对象的一切配置(那一堆set函数)都必须要在connect()函数执行之前完成。而对outputStream的写操作,又必须要在inputStream的读操作之前。
这些顺序实际上是由http请求的格式决定的。
如果inputStream读操作在outputStream的写操作之前,会抛出例外:
java.net.ProtocolException: Cannot write output after reading input.......
c:) http请求实际上由两部分组成,
一个是http头,所有关于此次http请求的配置都在http头里面定义,一个是正文content。
connect()函数会根据HttpURLConnection对象的配置值生成http头部信息,因此在调用connect函数之前,
就必须把所有的配置准备好。
d:) 在http头后面紧跟着的是http请求的正文,正文的内容是通过outputStream流写入的,实际上outputStream不是一个网络流,充其量是个字符串流,往里面写入的东西不会立即发送到网络,而是存在于内存缓冲区中,待outputStream流关闭时,根据输入的内容生成http正文。至此,http请求的东西已经全部准备就绪。在getInputStream()函数调用的时候,就会把准备好的http请求正式发送到服务器了,然后返回一个输入流,用于读取服务器对于此次http请求的返回信息。由于http请求在getInputStream的时候已经发送出去了(包括http头和正文),因此在getInputStream()函数之后对connection对象进行设置(对http头的信息进行修改)或者写入outputStream(对正文进行修改)都是没有意义的了,执行这些操作会导致异常的发生。
XML:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:esb="http://ucloud.unicom.com/ESB_YS_YS_InquiryEventsReferralsInfoSrv" xmlns:msg="http://ucloud.unicom.com/MsgHeader"> <soapenv:Header/> <soapenv:Body> <esb:ESB_YS_YS_InquiryEventsReferralsInfoSrvRequest> <esb:MsgHeader> <msg:SOURCE_APP_ID>1</msg:SOURCE_APP_ID> <msg:SOURCE_APP_NAME>1</msg:SOURCE_APP_NAME> <msg:SOURCE_MOD_ID>1</msg:SOURCE_MOD_ID> <msg:SOURCE_MOD_NAME>1</msg:SOURCE_MOD_NAME> <msg:TARGET_MOD_ID>1</msg:TARGET_MOD_ID> <msg:TARGET_MOD_NAME>1</msg:TARGET_MOD_NAME> <msg:TOKEN>1</msg:TOKEN> <msg:USERID>1</msg:USERID> <msg:USERNAME>1</msg:USERNAME> <msg:SUBMITDATE>2012-03-12T12:12:12</msg:SUBMITDATE> <msg:PAGE_SIZE>1</msg:PAGE_SIZE> <msg:CURRENT_PAGE>1</msg:CURRENT_PAGE> <msg:TOTAL_RECORD>1</msg:TOTAL_RECORD> <msg:PROVINCE_CODE>1</msg:PROVINCE_CODE> <msg:ENVIRONMENT_NAME>1</msg:ENVIRONMENT_NAME> </esb:MsgHeader> <esb:TIME_FROM>20121212121212</esb:TIME_FROM> <esb:TIME_TO>20121212121212</esb:TIME_TO> <esb:USER_CODE>1</esb:USER_CODE> <esb:ATTRIBUTE1>1</esb:ATTRIBUTE1> <esb:ATTRIBUTE2>1</esb:ATTRIBUTE2> <esb:ATTRIBUTE3>1</esb:ATTRIBUTE3> <esb:ATTRIBUTE4>1</esb:ATTRIBUTE4> </esb:ESB_YS_YS_InquiryEventsReferralsInfoSrvRequest> </soapenv:Body> </soapenv:Envelope>
获取错误消息可以通过异常流urlConn.getErrorStream()。
详细参考:http://www.cnblogs.com/guodongli/archive/2011/04/05/2005930.html
SOAPUtil.rar (4.5 MB)
下载次数: 66
相关文章推荐
- 使用 Web Services Enhancements 发送带有附件的 SOAP 消息
- 客户端(client)获取服务端(server)返回的SOAP消息包
- 使用gSOAP开发实例(5) libxml2解析SOAP响应消息
- 使用soapmonitor模块监视soap请求与响应消息
- 进程之间通过CWnd::SendMessage(WM_COPYDATA,*,*)发送和获取消息
- 提升Web Services性能原来不是通过传说中的压缩Soap请求和响应消息来实现的
- WebService大讲堂之Axis2(10):使用soapmonitor模块监视soap请求与响应消息 (zhuan)
- 基于Servlet发送、接收SOAP消息
- SQL Server:如何在Service Broker发送消息验证失败后获取源消息
- 在Python中发送广播消息并接收所有客户端响应的小脚本
- 使用SAAJ发送和接收SOAP消息
- 技巧:用JAXM发送和接收SOAP消息
- WebService大讲堂之Axis2(10):使用soapmonitor模块监视soap请求与响应消息
- 使用SAAJ发送和接收SOAP消息
- WebService大讲堂之Axis2(10):使用soapmonitor模块监视soap请求与响应消息
- 提升Web Services性能原来不是通过传说中的压缩Soap请求和响应消息来实现的
- WebService大讲堂之Axis2(10):使用soapmonitor模块监视soap请求与响应消息
- Delphi获取句柄并发送消息!
- 如何在WCF中用TcpTrace工具查看发送和接收的SOAP消息
- Axis Web Service开发之旅 (九) --使用soapmonitor模块监视soap请求与响应消息