`
uule
  • 浏览: 6358943 次
  • 性别: Icon_minigender_1
  • 来自: 一片神奇的土地
社区版块
存档分类
最新评论

发送Soap消息并获取响应

 
阅读更多

SOAP

 

如下:

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

 

 

分享到:
评论

相关推荐

    基于Servlet发送、接收SOAP消息的java源程序

    - 发送SOAP响应:利用`HttpServletResponse`对象,将响应写回到客户端。 【三】Java SOAP库 Java提供了一些内置的库,如JAX-WS(Java API for XML Web Services),简化了SOAP服务的开发。JAX-WS允许开发者通过...

    java发送SOAP报文

    本文将深入探讨如何在Java环境中构建和发送SOAP消息,同时也会提及到与给定的文件相关的编程概念。 首先,我们来看`Transporter.java`这个文件。通常情况下,`Transporter`类会扮演一个角色,负责处理HTTP传输和...

    SOAP实例程序,实现Java发送SOAP信息.zip

    在提供的压缩包中,"SOAP实例程序,实现Java发送SOAP信息"可能是源代码文件,其中包含了一个完整的Java应用示例,演示了如何发送SOAP请求并处理响应。"1"可能是额外的文件或资源,如配置文件、依赖库或测试数据。...

    MFC实现soap协议并获取监控信息

    2. **发送请求**:通过MFC的HTTP通信类,如CInternetSession和CHttpConnection,建立与服务器的连接,并发送SOAP请求。 3. **接收响应**:当服务器返回SOAP响应时,使用MFC的类解析XML响应,提取所需数据。 4. **...

    SOAP实例程序,实现Java发送SOAP信息.rar

    这个压缩包文件“SOAP实例程序,实现Java发送SOAP信息.rar”显然是一个Java项目,展示了如何使用Java来创建并发送SOAP消息。在本文中,我们将深入探讨SOAP协议、Java中的SOAP客户端实现以及与C#相关的上下文。 1. *...

    soap-build生成Soap接口请求报文

    与soap-ui相比,虽然soap-ui是一款强大的SOAP测试工具,它允许用户图形化地创建、编辑和发送SOAP请求,同时提供详尽的响应分析和测试套件管理功能。然而,“soap-build”更专注于代码生成,特别是在持续集成(CI)和...

    SOAP入门

    4. **获取SOAPConnection对象**:为了发送SOAP消息,需要获取一个`SOAPConnection`对象。这将用于执行实际的消息传输操作。 5. **发送消息**:使用`SOAPConnection.call()`或`send()`方法来发送SOAP消息。这些方法...

    java调用soap接口案例

    本案例主要关注如何使用Java来实现SOAP请求并获取响应,具体我们将围绕以下几个知识点展开: 1. **SOAP协议**:SOAP是一种轻量级的消息协议,它定义了消息的格式,使得应用程序可以通过HTTP或其他传输协议进行通信...

    soap消息头解析,不解析消息体

    这种情况下,仅解析SOAP消息头而不解析消息体可以提高性能,并减少不必要的资源消耗。 ### 实现方法 根据题目给出的部分内容,我们将以Axis2为例,介绍如何实现仅解析SOAP消息头的功能。 #### 配置Axis2 Web.xml ...

    Java使用SOAP获取webservice实例解析

    ### Java使用SOAP获取WebService实例解析 #### WebService简介 WebService是一种跨编程语言和操作系统平台的、在网络上进行数据交换的一种方式。它使用标准的Internet协议,如HTTP、XML、SOAP等来实现不同系统间的...

    WS-Security构筑安全的SOAP消息调用

    2. **消息加密**:利用XML Encryption对SOAP消息进行加密,即使消息被监听,监听者也无法获取有效信息。 3. **单消息认证**:引入了安全令牌(Security Token)的概念,通过与数字签名技术结合,服务提供者可以确认...

    Extract Soap Body From Soap Message

    - Envelope:这是SOAP消息的根元素,定义了整个消息的结构,并告诉接收者这是一个SOAP消息。 - Header:这部分包含了与消息处理相关的元数据,如安全信息、路由信息等,可选但常用。 - Body:这是SOAP消息的核心...

    Qt下实现WebServer的调用之qtsoap

    3. **发送请求**:使用`qtsoap::SoapTransport`类发送SOAP请求。这通常涉及到HTTP POST操作。例如: ```cpp qtsoap::SoapTransport transport; transport.setRequest(request); transport.sendRequest(); ``` ...

    利用DOM4J解析SOAP的简单示例

    在实际应用中,解析SOAP消息通常结合网络请求,例如使用Apache HttpClient发送SOAP请求并接收响应,然后使用DOM4J解析响应内容。了解DOM4J库的其他功能,如XPath查询、命名空间处理等,可以帮助更高效地处理复杂SOAP...

    ios客户端通过Soap获取服务器数据

    3. **发送SOAP请求**: 使用NSURLConnection创建一个POST请求,将SOAP消息体作为请求的HTTP Body。记得设置请求头中的`Content-Length`字段,以及上述提到的`SOAPAction`和`Content-Type`。 4. **处理响应**: 当...

    soap环境搭建常用jar包

    4. **soap.jar**:这是一个专门针对SOAP协议的库,提供了处理SOAP消息的基本功能,如创建、解析和发送SOAP请求和响应。它包含了一些关键类,如`javax.xml.soap.*`包下的类,使得开发者可以方便地创建SOAP头、SOAP体...

    SOAP调用webservice例子

    5. **接收SOAP响应**:Web服务接收到请求后,处理它并返回一个SOAP响应。 6. **解析响应**:客户端解析SOAP响应,提取所需的数据,并进行相应的业务处理。 **SOAP与RESTful API的对比** - SOAP是基于XML的,而...

    拼接soap,判断soap是否连接成功,返回接口的信息,解析soap报文,解析后的soap转成实体

    总的来说,这个压缩包包含了一套完整的SOAP通信解决方案,从构建请求,到发送,再到解析响应并转换为Java实体,为处理SOAP Web服务提供了一个实用的工具集。对于需要处理SOAP接口的开发者来说,这是一个宝贵的资源。

    soap入门(E版)soap入门(E版)

    本教程涵盖了SOAP基础操作,包括创建、发送SOAP消息,以及如何在消息中添加内容和附件。学习这些知识后,开发者将能够构建基本的SOAP Web服务客户端和服务器,进行数据交互。然而,深入理解SOAP还需要掌握更多高级...

    soap相关代码及资料

    此外,为了调试和测试SOAP服务,可以使用工具如SoapUI,它允许发送和接收SOAP请求,查看响应,检查消息格式,并执行性能测试。这在开发和维护过程中非常有用。 在处理SOAP时,我们还需要关注性能和安全性。由于SOAP...

Global site tag (gtag.js) - Google Analytics