提问人:Ahmad Yazdi 提问时间:5/21/2023 更新时间:5/21/2023 访问量:128
如何修复使用Java调用SOAP Web服务时不可读的XML响应?
How to fix unreadable XML response when calling a SOAP web service with Java?
问:
调用 SOAP Web 服务
我有一个 soap web 服务要调用,这是我的代码:
private List<Guaranty> getGuarantyList(String nationalId, String centerBankCode) throws IOException{
try {
fixHttpsHandler();
} catch (Exception ex) {
System.out.println(ex.getMessage());
}
// Code to make a webservice HTTP request
String responseString = "";
String outputString = "";
String wsEndPoint = "http://192.168.5.202/services/out.asmx";
URL url = new URL(wsEndPoint);
URLConnection connection = url.openConnection();
HttpURLConnection httpConn = (HttpURLConnection) connection;
ByteArrayOutputStream bout = new ByteArrayOutputStream();
String xmlInput = "<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:pos=\"http://postbank.ir/\">\r\n" +
" <soapenv:Header>\r\n" +
" <pos:PostbankAuth>\r\n" +
" <!--Optional:-->\r\n" +
" <pos:UserName>ebank</pos:UserName>\r\n" +
" <!--Optional:-->\r\n" +
" <pos:Password>qwer@123</pos:Password>\r\n" +
" </pos:PostbankAuth>\r\n" +
" </soapenv:Header>\r\n" +
" <soapenv:Body>\r\n" +
" <pos:getGuaranty>\r\n" +
" <!--Optional:-->\r\n" +
" <pos:nationalCode>" + nationalId + "</pos:nationalCode>\r\n" +
" <!--Optional:-->\r\n" +
" <pos:centerBankCode>" + centerBankCode + "</pos:centerBankCode>\r\n" +
" <!--Optional:-->\r\n" +
" <pos:length>10</pos:length>\r\n" +
" <pos:offset>0</pos:offset>\r\n" +
" </pos:getGuaranty>\r\n" +
" </soapenv:Body>\r\n" +
"</soapenv:Envelope>";
byte[] buffer = new byte[xmlInput.length()];
buffer = xmlInput.getBytes();
bout.write(buffer);
byte[] b = bout.toByteArray();
String SOAPAction = "http://postbank.ir/getGuaranty";
httpConn.setRequestProperty("Accept-Encoding", "gzip,deflate");
httpConn.setRequestProperty("Content-Type", "text/xml; charset=utf-8");
httpConn.setRequestProperty("SOAPAction", SOAPAction);
httpConn.setRequestProperty("Content-Length", String.valueOf(b.length));
httpConn.setRequestProperty("Host", "192.168.5.202");
httpConn.setRequestProperty("Connection", "Keep-Alive");
httpConn.setRequestProperty("User-Agent", "Apache-HttpClient/4.5.5 (Java/16.0.1)");
httpConn.setRequestMethod("POST");
httpConn.setDoOutput(true);
httpConn.setDoInput(true);
OutputStream out = httpConn.getOutputStream();
// Write the content of the request to the outputstream of the HTTP
// Connection.
out.write(b);
out.close();
// Ready with sending the request.
// Read the response.
InputStreamReader isr = new InputStreamReader(httpConn.getInputStream(), Charset.forName("UTF-8"));
BufferedReader in = new BufferedReader(isr);
// Write the SOAP message response to a String.
while ((responseString = in.readLine()) != null) {
outputString = outputString + responseString;
}
String formattedSOAPResponse = formatXML(outputString);
return formattedSOAPResponse ;
}
但我得到这个作为响应,而不是一个可读的 XML:
________ _$ؐ@ _iG#) * eVe]f@ 흼 { { ;N' ?\fd_l J ɞ! ?~|?」 _ _ez MQ-? hw Q / լX^| Ѻ= > 8z T 2/ U + > yۮ_ڽ L “k >W ] r7ח ~ k _7 ٽ { 5_ . M - {kv [) O ヰ | ٲ ~ 7 j ( _Ъj I |;.n ºl __ 7Mv _Uo_ 5 ?~ N |v ] Y __ $πG E ^ ۏ > 1 I~Q, e GG{;{{�;ٻ hg νG -ۚ^ j潹 Km _ ыl 5 _ f _ = 6 _5 k C wv?˻ wp n Rެ __ nz 6 |V ۬]7 g NO _ \ 51 ku _5 ҏѠi E^c( ѿ 7 _X o _O _ ?& _ _ _ o ? o _F_ [_ W [տ 7_ _ _ dzu $ C_ q aB 2} { ӶG _ TD ;?y0 9, B$o oW , g Ͻ o 5 c ~ 3 q ٫ ;{4=43 v _ ?x s_ : _B _ 7 ;4�;; _t^Ֆ { h פ o 1D #R“ _ o 4” _A _t ;+ ?}@ _ uM__o 2_ͫe r v_ } C ^c_BL ^z S~ 9z ^ y3 __ 5 ) + ? 8 _ o K ? _ m鏿 ˜n_ Q _ o 5 _w N?G .q“i _ '} iW ˘ _ꙴZH_I�%&/m�{_J�J��t�_�
这种方式适用于其他 Web 服务,但不适用于此服务。我在 SOAP-UI 中测试了 Web 服务,它工作正常...... 谢谢
答:
您收到的乱码响应表示响应已使用 gzip 或 deflate 编码进行压缩。若要正确处理此压缩响应,需要先对其进行解码,然后再将其读取为可读的 XML。
import java.io.*;
import java.net.*;
import java.util.zip.GZIPInputStream;
private List<Guaranty> getGuarantyList(String nationalId, String centerBankCode) throws IOException {
try {
fixHttpsHandler();
} catch (Exception ex) {
System.out.println(ex.getMessage());
}
String responseString = "";
String outputString = "";
String wsEndPoint = "http://192.168.5.202/services/out.asmx";
URL url = new URL(wsEndPoint);
URLConnection connection = url.openConnection();
HttpURLConnection httpConn = (HttpURLConnection) connection;
ByteArrayOutputStream bout = new ByteArrayOutputStream();
String xmlInput = "<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:pos=\"http://postbank.ir/\">\r\n" +
...
"</soapenv:Envelope>";
byte[] buffer = new byte[xmlInput.length()];
buffer = xmlInput.getBytes();
bout.write(buffer);
byte[] b = bout.toByteArray();
String SOAPAction = "http://postbank.ir/getGuaranty";
httpConn.setRequestProperty("Accept-Encoding", "gzip,deflate");
httpConn.setRequestProperty("Content-Type", "text/xml; charset=utf-8");
httpConn.setRequestProperty("SOAPAction", SOAPAction);
httpConn.setRequestProperty("Content-Length", String.valueOf(b.length));
httpConn.setRequestProperty("Host", "192.168.5.202");
httpConn.setRequestProperty("Connection", "Keep-Alive");
httpConn.setRequestProperty("User-Agent", "Apache-HttpClient/4.5.5 (Java/16.0.1)");
httpConn.setRequestMethod("POST");
httpConn.setDoOutput(true);
httpConn.setDoInput(true);
OutputStream out = httpConn.getOutputStream();
out.write(b);
out.close();
InputStream inputStream = httpConn.getInputStream();
String contentEncoding = httpConn.getContentEncoding();
if (contentEncoding != null && contentEncoding.equalsIgnoreCase("gzip")) {
inputStream = new GZIPInputStream(inputStream);
} else if (contentEncoding != null && contentEncoding.equalsIgnoreCase("deflate")) {
inputStream = new InflaterInputStream(inputStream);
}
InputStreamReader isr = new InputStreamReader(inputStream, Charset.forName("UTF-8"));
BufferedReader in = new BufferedReader(isr);
while ((responseString = in.readLine()) != null) {
outputString = outputString + responseString;
}
String formattedSOAPResponse = formatXML(outputString);
return formattedSOAPResponse;
}
我添加了逻辑来检查 HTTP 响应的 Content-Encoding 标头。如果它指示 gzip 压缩,则 inputStream 被包装在 GZIPInputStream 中进行解压缩。同样,如果编码为 deflate,则将其包装在 InflaterInputStream 中。
评论
上一个:Java 适配器 .mts 解析
下一个:XSD 验证失败
评论