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

如何将IBM大型机IBM-37编码的XML消息转为UTF-8适配SpringBoot?

解决IBM-37编码XML转UTF-8的Feign实现方案

核心问题:大型机返回的响应采用IBM-37(CP037) EBCDIC编码,Feign默认以UTF-8解码,导致乱码。以下是两种可行的实现方法:

方法一:自定义Feign解码器手动转换编码

通过实现Feign的Decoder接口,拦截响应字节流,先以IBM-37解码,再转换为UTF-8格式。

1. 实现自定义Decoder

import feign.Response;
import feign.Util;
import feign.decoder.Decoder;
import feign.decoder.StringDecoder;
import java.io.IOException;
import java.lang.reflect.Type;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;

public class IBM37Decoder extends Decoder {
    private final Decoder defaultDecoder;

    public IBM37Decoder() {
        this.defaultDecoder = new StringDecoder();
    }

    @Override
    public Object decode(Response response, Type type) throws IOException {
        if (String.class.equals(type)) {
            // 读取响应原始字节
            byte[] responseBytes = Util.toByteArray(response.body().asInputStream());
            // 用IBM-37解码为字符串
            String ebcdicStr = new String(responseBytes, Charset.forName("IBM-37"));
            // 转换为UTF-8(Java字符串内部为UTF-16,此步骤确保编码标准化)
            return new String(ebcdicStr.getBytes(StandardCharsets.UTF_8), StandardCharsets.UTF_8);
        }
        // 非String类型交给默认解码器处理
        return defaultDecoder.decode(response, type);
    }
}

2. 配置Feign客户端使用自定义Decoder

RESoapClient soapClient = Feign.builder()
        .client(new ApacheHttp5Client())
        .decoder(new IBM37Decoder()) // 替换默认解码器
        .target(SoapClient.class, "http://10.10.10.10:8000/B2B/Broker/api/v1");

方法二:配置Apache HttpClient5默认编码

通过自定义Apache HttpClient5实例,设置响应的默认字符编码为IBM-37,让HttpClient自动完成解码转换。

1. 创建自定义HttpClient

import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
import org.apache.hc.client5.http.impl.classic.HttpClients;
import org.apache.hc.core5.http.config.CharCodingConfig;
import java.nio.charset.Charset;

CloseableHttpClient httpClient = HttpClients.custom()
        .setDefaultCharCodingConfig(CharCodingConfig.custom()
                .setCharset(Charset.forName("IBM-37")) // 设置默认响应编码
                .build())
        .build();

2. 绑定到Feign客户端

RESoapClient soapClient = Feign.builder()
        .client(new ApacheHttp5Client(httpClient)) // 传入自定义HttpClient
        .target(SoapClient.class, "http://10.10.10.10:8000/B2B/Broker/api/v1");

注意:如果响应头Content-Type明确指定了编码,HttpClient会优先使用响应头的编码配置,此方法仅在响应未指定编码时生效。

补充:请求头优化

可在Feign接口的请求头中添加Accept-Charset,明确告知服务器返回IBM-37编码的响应:

public interface SoapClient {
    @RequestLine("POST")
    @Headers({
        "SOAPAction: operationSaveReq", 
        "Content-Type: text/xml;charset=UTF-8",
        "Accept: text/xml",
        "Accept-Charset: IBM-37, UTF-8"
    })
    String operationSaveReq(String soapBody);
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 12:13:10