xmlsoapopenfeign

IBM mainframe in IBM-37 chartset encoding format to UTF-8 to be understood in springboot app


Hi how are you? I am trying to convert a xml raw message with comes from IBM mainframe in IBM-37 chartset encoding format to UTF-8 to be understood in springboot app. Any idea how to do that? I am using Feign's http requests to Apache's HttpClient 5.

public interface SoapClient {

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


}



 RESoapClient soapClient = Feign.builder()
                .client(new ApacheHttp5Client())
                .target(SoapClient.class, "http://10.10.10.10:8000/B2B/Broker/api/v1");


 String soapResponse = soapClient.operationSaveReq("xml string");  

the string object soapResponse returned raw message like:

enter image description here


Solution

  • This got me interested so I looked a bit into Feign. Turns out that the OkHttp client detects the charset parameter and correctly decodes the payload. Sample here using the JDK built-in HTTP server, serving ibm-37 encoded XML:

    import java.net.InetSocketAddress;
    import java.nio.charset.Charset;
    
    import com.sun.net.httpserver.HttpServer;
    
    import feign.Feign;
    import feign.okhttp.OkHttpClient;
    
    public class Main {
    
        public static void main(String[] args) throws Exception {
            
            var server = HttpServer.create(new InetSocketAddress("localhost", 0), 0);
            server.createContext("/", x -> {
                x.getResponseHeaders().add("Content-Type", "text/xml;charset=ibm-37");
                x.sendResponseHeaders(201, 0);
                x.getResponseBody().write("<root version='4711'><sub>data</sub></root>".getBytes(Charset.forName("ibm-37")));
                x.getResponseBody().close();
            });
            
            server.start();
            
            try {
                var url = String.format("http://localhost:%d/", server.getAddress().getPort());
                
                var soapClient = Feign.builder()
                        .client(new OkHttpClient())
                        .target(SoapClient.class, url);
        
        
                var soapResponse = soapClient.operationSaveReq("xml string");
                System.out.println(soapResponse);
            } finally {
                server.stop(0);
            }
        }
    }
    

    If you need to use the Apache client, you probably have to create a custom decoder, or maybe configure the Apache client to honor the full content-type info.