You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java调用SOAP Web Service时XML响应乱码的解决方法

解决SOAP Web Service调用乱码问题

问题描述

我需要调用SOAP Web Service获取担保列表,Java代码如下,但调用后返回乱码内容。该调用方式在其他Web Service上正常,且服务在SOAP-UI中测试正常。

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 ;
        
    }

问题原因与解决方法

乱码的核心原因是你请求了gzip/deflate压缩响应,但没有对返回的压缩数据进行解压,直接用UTF-8读取压缩字节流必然会出现乱码。

具体修复方案

方案一:禁用压缩请求(最简单)

直接删除Accept-Encoding请求头,让服务返回未压缩的明文XML:

// 移除这一行
// httpConn.setRequestProperty("Accept-Encoding", "gzip,deflate");

方案二:保留压缩并添加解压逻辑

如果需要压缩提升传输效率,在读取响应时先判断并解压数据流:

// 读取响应部分替换为以下代码
InputStream inputStream = httpConn.getInputStream();
// 检查响应是否被压缩
String contentEncoding = httpConn.getContentEncoding();
if (contentEncoding != null && contentEncoding.contains("gzip")) {
    inputStream = new GZIPInputStream(inputStream);
} else if (contentEncoding != null && contentEncoding.contains("deflate")) {
    inputStream = new InflaterInputStream(inputStream);
}

// 用UTF-8读取解压后的流
InputStreamReader isr = new InputStreamReader(inputStream, StandardCharsets.UTF_8);
BufferedReader in = new BufferedReader(isr);
String responseString;
// 用StringBuilder替代String拼接,提升性能
StringBuilder outputString = new StringBuilder();
while ((responseString = in.readLine()) != null) {
    outputString.append(responseString);
}

String formattedSOAPResponse = formatXML(outputString.toString());
// 注意:方法声明返回List<Guaranty>,此处需补充XML解析逻辑将字符串转换为目标对象
// List<Guaranty> guarantyList = parseXmlToGuarantyList(formattedSOAPResponse);
// return guarantyList;

额外注意点

代码中存在返回值类型不匹配问题:方法声明返回List<Guaranty>,但当前最后返回的是String,需要后续添加XML解析逻辑,将格式化后的SOAP响应转换为List<Guaranty>对象。

内容的提问来源于stack exchange,提问作者Ahmad Yazdi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.21 05:27:18