如下:
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
相关推荐
- 发送SOAP响应:利用`HttpServletResponse`对象,将响应写回到客户端。 【三】Java SOAP库 Java提供了一些内置的库,如JAX-WS(Java API for XML Web Services),简化了SOAP服务的开发。JAX-WS允许开发者通过...
本文将深入探讨如何在Java环境中构建和发送SOAP消息,同时也会提及到与给定的文件相关的编程概念。 首先,我们来看`Transporter.java`这个文件。通常情况下,`Transporter`类会扮演一个角色,负责处理HTTP传输和...
在提供的压缩包中,"SOAP实例程序,实现Java发送SOAP信息"可能是源代码文件,其中包含了一个完整的Java应用示例,演示了如何发送SOAP请求并处理响应。"1"可能是额外的文件或资源,如配置文件、依赖库或测试数据。...
2. **发送请求**:通过MFC的HTTP通信类,如CInternetSession和CHttpConnection,建立与服务器的连接,并发送SOAP请求。 3. **接收响应**:当服务器返回SOAP响应时,使用MFC的类解析XML响应,提取所需数据。 4. **...
这个压缩包文件“SOAP实例程序,实现Java发送SOAP信息.rar”显然是一个Java项目,展示了如何使用Java来创建并发送SOAP消息。在本文中,我们将深入探讨SOAP协议、Java中的SOAP客户端实现以及与C#相关的上下文。 1. *...
与soap-ui相比,虽然soap-ui是一款强大的SOAP测试工具,它允许用户图形化地创建、编辑和发送SOAP请求,同时提供详尽的响应分析和测试套件管理功能。然而,“soap-build”更专注于代码生成,特别是在持续集成(CI)和...
4. **获取SOAPConnection对象**:为了发送SOAP消息,需要获取一个`SOAPConnection`对象。这将用于执行实际的消息传输操作。 5. **发送消息**:使用`SOAPConnection.call()`或`send()`方法来发送SOAP消息。这些方法...
本案例主要关注如何使用Java来实现SOAP请求并获取响应,具体我们将围绕以下几个知识点展开: 1. **SOAP协议**:SOAP是一种轻量级的消息协议,它定义了消息的格式,使得应用程序可以通过HTTP或其他传输协议进行通信...
这种情况下,仅解析SOAP消息头而不解析消息体可以提高性能,并减少不必要的资源消耗。 ### 实现方法 根据题目给出的部分内容,我们将以Axis2为例,介绍如何实现仅解析SOAP消息头的功能。 #### 配置Axis2 Web.xml ...
### Java使用SOAP获取WebService实例解析 #### WebService简介 WebService是一种跨编程语言和操作系统平台的、在网络上进行数据交换的一种方式。它使用标准的Internet协议,如HTTP、XML、SOAP等来实现不同系统间的...
2. **消息加密**:利用XML Encryption对SOAP消息进行加密,即使消息被监听,监听者也无法获取有效信息。 3. **单消息认证**:引入了安全令牌(Security Token)的概念,通过与数字签名技术结合,服务提供者可以确认...
- Envelope:这是SOAP消息的根元素,定义了整个消息的结构,并告诉接收者这是一个SOAP消息。 - Header:这部分包含了与消息处理相关的元数据,如安全信息、路由信息等,可选但常用。 - Body:这是SOAP消息的核心...
3. **发送请求**:使用`qtsoap::SoapTransport`类发送SOAP请求。这通常涉及到HTTP POST操作。例如: ```cpp qtsoap::SoapTransport transport; transport.setRequest(request); transport.sendRequest(); ``` ...
在实际应用中,解析SOAP消息通常结合网络请求,例如使用Apache HttpClient发送SOAP请求并接收响应,然后使用DOM4J解析响应内容。了解DOM4J库的其他功能,如XPath查询、命名空间处理等,可以帮助更高效地处理复杂SOAP...
3. **发送SOAP请求**: 使用NSURLConnection创建一个POST请求,将SOAP消息体作为请求的HTTP Body。记得设置请求头中的`Content-Length`字段,以及上述提到的`SOAPAction`和`Content-Type`。 4. **处理响应**: 当...
4. **soap.jar**:这是一个专门针对SOAP协议的库,提供了处理SOAP消息的基本功能,如创建、解析和发送SOAP请求和响应。它包含了一些关键类,如`javax.xml.soap.*`包下的类,使得开发者可以方便地创建SOAP头、SOAP体...
5. **接收SOAP响应**:Web服务接收到请求后,处理它并返回一个SOAP响应。 6. **解析响应**:客户端解析SOAP响应,提取所需的数据,并进行相应的业务处理。 **SOAP与RESTful API的对比** - SOAP是基于XML的,而...
总的来说,这个压缩包包含了一套完整的SOAP通信解决方案,从构建请求,到发送,再到解析响应并转换为Java实体,为处理SOAP Web服务提供了一个实用的工具集。对于需要处理SOAP接口的开发者来说,这是一个宝贵的资源。
本教程涵盖了SOAP基础操作,包括创建、发送SOAP消息,以及如何在消息中添加内容和附件。学习这些知识后,开发者将能够构建基本的SOAP Web服务客户端和服务器,进行数据交互。然而,深入理解SOAP还需要掌握更多高级...
此外,为了调试和测试SOAP服务,可以使用工具如SoapUI,它允许发送和接收SOAP请求,查看响应,检查消息格式,并执行性能测试。这在开发和维护过程中非常有用。 在处理SOAP时,我们还需要关注性能和安全性。由于SOAP...