Al utilizar Apache CXF para llamar a una interfaz WebService mediante JaxWsDynamicClientFactory, puede surgir un error relacionado con caracteres no mapeables en codificaicón GBK, incluso cuando el entorno está configurado para usar UTF-8.
Ejemplo de código con problema
JaxWsDynamicClientFactory factoryInstance = JaxWsDynamicClientFactory.newInstance();
Client clientProxy = factoryInstance.createClient(ConfigurationReader.get("endpoint.url"));
Object[] responseArray = clientProxy.invoke("EjecutarOperacion", arg1, arg2,
ConfigurationReader.get("auth.user"), ConfigurationReader.get("auth.password"),
ConfigurationReader.get("service.identifier"), "", ConfigurationReader.get("client.code"));
String statusCode = responseArray[0].toString();
Logger.info("Respuesta del servicio: " + StatusMapping.RESPONSE_CODES.get(statusCode));
Durante la ejecución, se observa un error de compilación dinámica con mensajes como:
Ruta\tmp\generated_sources\OperationType.java:12: error: Carácter no mapeable en codificación GBK
* <p>anonymous complex type鐨? Java 绫汇??
^
(más errores de codificación omitidos)
</p>
Observación: El servidor de aplicaciones y el entorno de desarrollo tienen la codificación establecida en UTF-8.
Razón del fallo
La compilación dinámica en DynamicClientFactory no gestiona adecuadamente caracteres no ASCII, lo que causa incompatibilidades de codificación al generar fuentes Java a partir del WSDL.
Implementación de la solución
Para corregir esto, se debe crear una subclase de DynamicClientFactory y sobrescribir el método que compila el código fuente, estableciendo explícitamente la codificación UTF-8.
A continuación, se presenta una clase personalizada que extiende DynamicClientFactory:
import org.apache.cxf.endpoint.dynamic.DynamicClientFactory;
import org.apache.cxf.Bus;
import org.apache.cxf.bus.CXFBusFactory;
public class Utf8AwareClientFactory extends DynamicClientFactory {
protected Utf8AwareClientFactory(Bus busReference) {
super(busReference);
}
public static Utf8AwareClientFactory createNewInstance() {
Bus defaultBus = CXFBusFactory.getThreadDefaultBus();
return new Utf8AwareClientFactory(defaultBus);
}
@Override
protected boolean compileJavaSrc(String classpath, List<file> sourceFiles, String destinationPath) {
org.apache.cxf.common.util.Compiler javaCompiler = new org.apache.cxf.common.util.Compiler();
// Configurar codificación UTF-8 para resolver problemas de caracteres no ASCII
javaCompiler.setEncoding("UTF-8");
javaCompiler.setClassPath(classpath);
javaCompiler.setOutputDir(destinationPath);
javaCompiler.setTarget("1.8"); // Ajustar según el entorno de ejecución
return javaCompiler.compileFiles(sourceFiles);
}
}
</file>
Posteriormente, se debe usar esta clase en lugar de JaxWsDynamicClientFactory al crear el cliente dinámico para invocar el servicio Web.