`
uule
  • 浏览: 6322790 次
  • 性别: 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传输和...

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

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

    java调用soap接口案例

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

    Java使用SOAP获取webservice实例解析

    在这个过程中,Java 程序需要使用到 SOAP 协议来发送请求和接收响应,实现对 Webservice 的调用。 首先,需要了解 Webservice 的基本概念。Webservice 是一种基于网络的软件系统,可以提供各种服务,如天气预报、...

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

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

    Extract Soap Body From Soap Message

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

    利用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调用webservice例子

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

    soap环境搭建常用jar包

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

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

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

    soap相关代码及资料

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

    soap的实现简单的服务发布

    在上述代码中,客户端创建了一个SOAP Call对象,设置了服务的URL、操作名称以及传递的参数,然后调用`invoke`方法发送请求并获取响应。 总结,SOAP协议在Web服务中扮演着重要角色,通过XML格式提供了一种跨平台、跨...

    soap协议上传数据

    1. 客户端(例如,你的应用程序)构建一个SOAP消息,其中包含要发送到MES系统的操作和数据。 2. 消息被封装成HTTP请求,并发送到MES系统的Web服务接口。 3. MES系统接收到HTTP请求后,解析SOAP消息,执行请求的操作...

    webservice 调用实例soap协议

    例如,在Java中,可以使用`javax.xml.soap`包中的`SOAPConnectionFactory`和`SOAPMessage`类来创建并发送SOAP请求。 3. **接收并解析SOAP响应**:Web服务执行操作后,会返回一个SOAP响应,同样也是XML格式。客户端...

    Soap方式调用WebService

    - **客户端解析响应**:客户端接收到响应后,解析SOAP消息以获取结果。 4. **SOAP版本与WSDL** SOAP有1.1和1.2两个主要版本,WSDL则是用来描述WebService接口的XML格式文件,包含了服务地址、操作名称、输入/输出...

    Qt下实现WebServer的调用之qtsoap

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

    关于soap客户端附件上传相关资料

    7. **处理响应**:接收SOAP响应后,解析消息以获取附件。如果是MTOM,你将根据XOP引用下载附件;如果是SwA,解码Base64数据。 8. **错误处理**:处理可能的网络错误、SOAP错误或其他异常情况。 在提供的压缩包文件...

    android利用SOAP实现天气预报

    5. 发送请求和处理响应:使用HttpTransportSE对象发送SOAP请求,并捕获响应。解析返回的SOAP响应,从中提取所需数据。 ```java HttpTransportSE androidHttpTransport = new HttpTransportSE(URL); try { ...

Global site tag (gtag.js) - Google Analytics