The power of C, the power of MD

A problem is a chance to do your best
posts - 11, comments - 22, trackbacks - 0, articles - 0
  C++博客 :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理
电信provisioning系统中,常常需要与远程服务器实时交换一些数据,以完成用户的请求。由于简单对象访问协议(Simple Object Access Protocol, SOAP)的流行,许多涉及到第三方的应用,我们一般都比较乐意使用SOAP来开发。不过,由于可能涉及到公司的机密,本系列教程的开发实例尽量采用在网上已经公开的Web Service资源。
 
上一节,讲解了用iconv解决gSOAP输出的中文文本乱码的问题。在本节中,我们用一个天气预报客户端的例子,简述一下gSOAP输入的中文文本乱码的问题。
 
Webxml.com.cn提供的天气预报web服务,endpoint地址是:http://webservice.webxml.com.cn/WebServices/WeatherWebService.asmx,大家可以点击进去,查看一下该服务的所有对外提供的接口。其中,利用getWeatherbyCityName接口,可以按给定的城市名字查询该城市的天气预报,如果输入的城市名字不能识别,将统一返回北京的天气预报。
 
根据前三节的内容,我们可以很快地准备好其客户端存根程序:
1.     mkdir –p weather
2.     cd weather
3.     ../wsdl2h -c -o weather.h
http://webservice.webxml.com.cn/WebServices/WeatherWebService.asmx?wsdl
4.     ../../bin/linux386/soapcpp2 –C –L –x weather.h
 
由于程序并不复杂,直接给出其源代码:
#include <iconv.h>

#include 
"soapH.h"
#include 
"WeatherWebServiceSoap12.nsmap"

#define OUTPUT_LEN 2048

int conv_charset(const char *dest, const char *src, char *input, size_t ilen, char *output, size_t olen) {
    iconv_t conv 
= iconv_open(dest, src);
    
if ( conv == (iconv_t) -1 )
        
return -1;
    memset(output, 
0, olen);
    
if ( iconv(conv, &input, &ilen, &output, &olen) )
        
return -1;
    iconv_close(conv);
    
return 0;
}

int main(int argc, char **argv) {
    
if ( argc != 2 && argc != 3 ) {
        printf(
"Usage: %s city_name [end_point]\n", argv[0]);
        exit(
-1);
    }

    
struct soap soap;
    soap_init(
&soap);
    soap_set_mode(
&soap, SOAP_C_UTFSTRING);

    
struct _ns1__getWeatherbyCityName request;
    
struct _ns1__getWeatherbyCityNameResponse response;

    size_t ilen 
= strlen(argv[1]);
    
char output[OUTPUT_LEN];
    
if ( conv_charset("UTF-8""GBK", argv[1], ilen, output, OUTPUT_LEN) )
        request.theCityName 
= argv[1];
    
else
        request.theCityName 
= output;

    
char *endpoint = NULL;
    
if ( argc == 3 )
        endpoint 
= argv[2];
        
if ( soap_call___ns3__getWeatherbyCityName(&soap, endpoint, NULL, &request, &response) == SOAP_OK ) {
        
int element_counter = response.getWeatherbyCityNameResult->__sizestring;
        
int i = 0;
        
for ( i = 0; i < element_counter; i++ ) {
            
switch ( i ) {
                
case 0  : printf("Province          : "); break;
                
case 1  : printf("City              : "); break;
                
case 2  : printf("City code         : "); break;
                
case 3  : printf("City pic. name    : "); break;
                
case 4  : printf("Timestamp         : "); break;
                
case 5  : printf("Temp. of today    : "); break;
                
case 6  : printf("Summary           : "); break;
                
case 7  : printf("Wind              : "); break;
                
case 8  : printf("Icon 1            : "); break;
                
case 9  : printf("Icon 2            : "); break;
                
case 10 : printf("Description       : "); break;
                
case 11 : printf("Reserved          : "); break;
                
case 12 : printf("Temp. of tomorrow : "); break;
                
case 13 : printf("Summary           : "); break;
                
case 14 : printf("Wind              : "); break;
                
case 15 : printf("Icon 1            : "); break;
                
case 16 : printf("Icon 2            : "); break;
                
case 17 : printf("Temp. of af. tmr. : "); break;
                
case 18 : printf("Summary           : "); break;
                
case 19 : printf("Wind              : "); break;
                
case 20 : printf("Icon 1            : "); break;
                
case 21 : printf("Icon 2            : "); break;
                
case 22 : printf("Introduction      : "); break;
                
default : break;
            }
            ilen 
= strlen(response.getWeatherbyCityNameResult->string[i]);
            
if ( conv_charset("GBK""UTF-8", response.getWeatherbyCityNameResult->string[i], ilen, output, OUTPUT_LEN) )
                printf(
"%s\n", response.getWeatherbyCityNameResult->string[i]);
            
else
                printf(
"%s\n", output);
        }
    }
    
else {
        soap_print_fault(
&soap, stderr);
    }

    soap_destroy(
&soap);
    soap_end(
&soap);
    soap_done(
&soap);
    
return 0;
}


编译命令是:gcc -O2 -o weather weather.c soapC.c soapClient.c ../../stdsoap2.c -I../.. -L../.. –lgsoap

 

基本上与上一节的股票信息客户端差不多,唯一不同的是,作为输入参数的城市名字,首先需要iconv转换编码,从GBK转到UTF-8,才可以提交给服务端。各位可以试一下,不作转换的话,无论输入什么,服务端只会返回北京的天气预报,因为传入的参数在服务端产生了乱码。

 

以下为正常的执行结果,输入广州,可以得到广州的天气预报:


如上图,最后一段的介绍也出现了乱码,不过我认为这是putty的问题,行末的最后一个全角字符,如果只能显示一半的话,下一行开始将产生乱码,如果再遇到一个半角字符,又能显示正常了。

http://blog.csdn.net/yui/archive/2010/07/23/5758906.aspx

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理