您的位置:首页 > 其它

发送Soap消息并获取响应

2017-04-13 10:45 162 查看
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

 

 

SOAPUtil.rar (4.5 MB)

下载次数: 66
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: