电信provisioning系统中,常常需要与远程服务器实时交换一些数据,以完成用户的请求。由于简单对象访问协议(Simple Object Access Protocol, SOAP)的流行,许多涉及到第三方的应用,我们一般都比较乐意使用SOAP来开发。不过,由于可能涉及到公司的机密,本系列教程的开发实例尽量采用在网上已经公开的Web Service资源。
我开发SOAP应用程序已经有一定的经验,在C/C++环境下一般使用gSOAP,而在Java环境下一般采用axis2。比较两者的话,除了开发语言之外,还是有不少差别,处理中文字符就是其中之一。网上分别搜索一下“axis2 乱码”和“gSOAP 乱码”,匹配的结果是相差很远的。Axis2好像比较智能,能够识别服务端的字符编码,这方面的问题也少,而最新版本的gSOAP,很可能还是需要程序员做多很多功夫。
在第一节客户端的教程中,输出的中文股票名称,其实就是乱码,不过为了主次之分,当时做了特别处理,忽略过去。
网上解决gSOAP乱码的主流方案是,初始化soap对象之后对其设置SOAP_C_UTFSTRING参数,例如:
struct soap soap;
soap_init(&soap);
soap_set_mode(&soap, SOAP_C_UTFSTRING);
但是,单纯这样修改,在某些特定设置的机器上可能有效,反正我试过,仍然是乱码,如下图。怎么办呢?
Linux下有一个字符编码转换的工具iconv,同时也提供了一套可编程的接口。利用它,就可以测试出来自于服务端中文字符编码的类型,从而进一步实现在程序中自动转换编码。
Iconv常用用法是:iconv -t=to_charset -f=from_charset filename
因此,把需要转换编码的内容保存为一个文件,然后执行iconv试出需要转换的编码类型。from_charset几乎百分百肯定就是utf8,那么to_charset来来去去就那么几个,一个个试也很快试出来了。最终得出的结果是gbk编码,从而修改客户端程序以解决乱码问题。
测试成功,如下图: