Codejie's C++ Space

Using C++

GSOAP:添加Header的处理

GSOAP对Header的支持远没有其站点说的那么好,当然如果WSDL描述的严密,其工具会自动生成相应的Header处理代码,但如果WSDL写的不好,需要人为添加对Header的处理,那写起来就是灾难~
    经过四处查找资料,随意踩着前人的肩膀,终于形成了如下的代码,供大家来踩~


    对SOAPHeader定义的改正,添加所需数据:
#ifndef SOAP_TYPE_SOAP_ENV__Header
#define SOAP_TYPE_SOAP_ENV__Header (86)
/* SOAP Header: */
struct SOAP_ENV__Header
{
#ifdef WITH_NOEMPTYSTRUCT
private:
    
char dummy;    /* dummy member to enable compilation */
#endif
public:
    mms2__RequestSOAPHeader
* requestHeader;
    mms2__NotifySOAPHeader
* notifyHeader;
};
#endif

    添加SOAPHeader的in函数处理:
SOAP_FMAC3 struct SOAP_ENV__Header * SOAP_FMAC4 soap_in_SOAP_ENV__Header(struct soap *soap, const char *tag, struct SOAP_ENV__Header *a, const char *type)
{
    
if (soap_element_begin_in(soap, tag, 0, type))
        
return NULL;
    a 
= (struct SOAP_ENV__Header *)soap_id_enter(soap, soap->id, a, SOAP_TYPE_SOAP_ENV__Header, sizeof(struct SOAP_ENV__Header), 0, NULL, NULL, NULL);
    
if (!a)
        
return NULL;
    soap_default_SOAP_ENV__Header(soap, a);

    
int notifyheader = 1;
    
int requestheader = 1;

    
if (soap->body && !*soap->href)
    {
        
for (;;)
        {    soap
->error = SOAP_TAG_MISMATCH;
            
if (soap->error == SOAP_TAG_MISMATCH)
            {
                
if(notifyheader == 1)
                {
                    a
->notifyHeader = soap_in_mms2__NotifySOAPHeader(soap, "mms2:NotifySOAPHeader", a->notifyHeader, "");
                    
if(a->notifyHeader)
                    {
                        notifyheader 
= 0;
                        
continue;
                    }
                }
                
else if(requestheader == 1)
                {
                    a
->requestHeader = soap_in_mms2__RequestSOAPHeader(soap, "mms2:RequestSOAPHeader", a->requestHeader, "");
                    
if(a->requestHeader)
                    {
                        requestheader 
= 0;
                        
continue;
                    }
                }

                soap
->error = soap_ignore_element(soap);
            }
            
if (soap->error == SOAP_NO_TAG)
                
break;
            
if (soap->error)
                
return NULL;
        }
        
if (soap_element_end_in(soap, tag))
            
return NULL;
    }
    
else
    {    a 
= (struct SOAP_ENV__Header *)soap_id_forward(soap, soap->href, (void*)a, 0, SOAP_TYPE_SOAP_ENV__Header, 0sizeof(struct SOAP_ENV__Header), 0, NULL);
        
if (soap->body && soap_element_end_in(soap, tag))
            
return NULL;
    }
    
return a;
}

    添加SOAPHeader的out函数处理:
SOAP_FMAC3 int SOAP_FMAC4 soap_out_SOAP_ENV__Header(struct soap *soap, const char *tag, int id, const struct SOAP_ENV__Header *a, const char *type)
{
    
if (soap_element_begin_out(soap, tag, soap_embedded_id(soap, id, a, SOAP_TYPE_SOAP_ENV__Header), type))
        
return soap->error;

    
if(a != NULL)
    {
        
if(a->requestHeader != NULL)
            a
->requestHeader->soap_out(soap, "mms2:RequestSOAPHeader"-1"");
        else if(a->notifyHeader != NULL)
            a
->notifyHeader->soap_out(soap, "mms2:NotifySOAPHeader"-1"");
    }

    
return soap_element_end_out(soap, tag);
}




    并不确认上面的代码是否还有什么错误,还没有来得及仔细测试,就来了一次request调用,所需数据正常到达,就已经19:50了,只能下班回家了~现在GSOAP还有两个主要问题:MIME附件和SOAPFault的处理。

    熟悉GSOAP和使用的WSDL的应该很好理解上面的代码,不熟悉这个WSDL的,麻烦多猜猜了,这个WSDL虽然不是什么绝密,但BOSS跟人签了“保密”协议,这里就不乱说了,省的留下把柄~

   

posted on 2009-07-13 22:36 codejie 阅读(9091) 评论(32)  编辑 收藏 引用 所属分类: C++

评论

# re: GSOAP:添加Header的处理 2009-11-04 14:27 xiaobai

你好 MIME附件 发送你会吗 能不能把发送的相关代码给我学习学习我需要这部分
如能的话万分感谢
邮箱 jpytu@126.com  回复  更多评论   

# re: GSOAP:添加Header的处理 2009-11-04 14:59 codejie

◎xiaobai
代码么有,都交了。如果你能更详细地说明你所需要的,或许我也能答复的准确些。  回复  更多评论   

# re: GSOAP:添加Header的处理 2009-11-04 17:16 xiaobai

我就是想发个彩信往网关
不过不知道 gsoap 里的发送方法
比如包 头的 都需要哪些参数
发送所用的函数  回复  更多评论   

# re: GSOAP:添加Header的处理 2009-11-05 10:02 codejie

@xiaobai
这是两个问题,不过你自己应该都能搞定的。
1.GSOAP发送方法,请去GSOAP官方站点查看文档;
2.MMS所需参数,请查看所使用网关接口的规范文档;由于各个运营商使用的规范不同,实际情况是不同的。  回复  更多评论   

# re: GSOAP:添加Header的处理 2010-01-15 16:38 lmode

我按你给的链接,添加了相关的代码
a->ns4_NotifySoapHeader = soap_in_ns4__NotifySOAPHeader(soap, "-ns1:NotifySOAPHeader", a->ns4_NotifySoapHeader, "");
返回成功,char* spRevId依旧为NULL,但是我跟踪soap_in_ns4__NotifySOAPHeader这个函数进去
在执行if (soap_in_string(soap, "spRevId", &a->spRevId, "xsd:string"))语句的时候,确是失败的,报文中tag=ns1:NotifySOAPHeader,和我函数设置的是一致的.不知道什么原因了..   回复  更多评论   

# re: GSOAP:添加Header的处理 2010-01-15 17:41 codejie

@lmode
a->ns4_NotifySoapHeader = soap_in_ns4__NotifySOAPHeader(soap, "-ns1:NotifySOAPHeader", a->ns4_NotifySoapHeader, "");
为什么有个'-'在‘ns1'前面? - "-ns1:NotifySOAPHeader"  回复  更多评论   

# re: GSOAP:添加Header的处理 2010-01-18 10:11 lmode

DBGLOG(TEST, SOAP_MESSAGE)
这个打印的日志消息,去哪里看.?  回复  更多评论   

# re: GSOAP:添加Header的处理 2010-01-18 10:39 lmode

当我把-ns1 前面的-去掉后,程序会停止在SOAP_MALLOC这个函数不执行下去.  回复  更多评论   

# re: GSOAP:添加Header的处理 2010-01-18 11:22 codejie

@codejie
DBGLOG()是调试输出,输出到哪里跟你的环境相关的。
如果'-'去除,程序就出错,那可能这个'-'来自WSDL文档中,‘ns'是一个域名指示。这样看的话,应该是报文中的头部分结构跟你定义的(struct)头结构有差异,你先检查一下,struct是否符合WSDL定义。  回复  更多评论   

# re: GSOAP:添加Header的处理 2010-01-18 17:15 lmode

stdsoap2.h
#define DEBUG */ /* Uncomment to debug sending (in file SENT.log) receiving (in file RECV.log)
and messages (in file TEST.log)

可以打开DBGLOG日志信息
  回复  更多评论   

# re: GSOAP:添加Header的处理 2010-01-18 17:55 codejie

@lmode
right, when used GSOAP, I got SENT.log and RECV.log by this way.  回复  更多评论   

# re: GSOAP:添加Header的处理 2010-01-19 09:27 lmode

soap_in_SOAP_ENV__Header:start soap_in_ns4__NotifySOAPHeader

Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 125721488 (LWP 26449)]
0x0043adf1 in _int_malloc () from /lib/libc.so.6
(gdb) bt
#0 0x0043adf1 in _int_malloc () from /lib/libc.so.6
#1 0x0043c35e in malloc () from /lib/libc.so.6
#2 0x0806795a in soap_track_malloc (soap=0x95e82a0, file=0x808eb66 "./webintf/stdsoap2.c", line=5364, size=20) at ./webintf/stdsoap2.c:5414
#3 0x0806831e in soap_malloc (soap=0x95e82a0, n=<value optimized out>) at ./webintf/stdsoap2.c:5364
#4 0x080699ff in soap_strdup (soap=0x95e82a0, s=0x95ff930 "14101163") at ./webintf/stdsoap2.c:2037
#5 0x0807bdfc in soap_string_in (soap=0x95e82a0, flag=1, minlen=-1, maxlen=-1) at ./webintf/stdsoap2.c:8724
#6 0x0807df63 in soap_instring (soap=0x95e82a0, tag=0x8092968 "spRevId", p=0x512170, type=0x8092bc9 "xsd:string", t=3, flag=1, minlen=-1, maxlen=-1)
at ./webintf/stdsoap2.c:10247
#7 0x08080046 in soap_in_string (soap=0x95e82a0, tag=0x8092968 "spRevId", a=0x512170, type=0x8092bc9 "xsd:string") at ./webintf/soapC.c:3361
#8 0x0808726c in soap_in_ns4__NotifySOAPHeader (soap=0x95e82a0, tag=0x8092c82 "ns1:NotifySOAPHeader", a=0x512170, type=0x808ef3c "")
at ./webintf/soapC.c:2315
#9 0x080887a5 in soap_in_SOAP_ENV__Header (soap=0x95e82a0, tag=0x8092c97 "SOAP-ENV:Header", a=0x95ffca8, type=0x0) at ./webintf/soapC.c:1529
#10 0x08088833 in soap_getheader (soap=0x95e82a0) at ./webintf/soapC.c:38
#11 0x08066352 in soap_recv_header (soap=0x95e82a0) at ./webintf/stdsoap2.c:13226
#12 0x0808a855 in soap_serve (soap=0x95e82a0) at ./webintf/soapServer.c:52
#13 0x0808c7c9 in process_queue (soap=0x95e82a0) at notifywapdemo.cpp:297
#14 0x009db45b in start_thread () from /lib/libpthread.so.0
#15 0x004a2c4e in clone () from /lib/libc.so.6

现在遇到这个问题了..  回复  更多评论   

# re: GSOAP:添加Header的处理 2010-01-19 09:36 codejie

@lmode
没有code,看不出哪里问题。从core点看,是和内存有关的,不是地址访问错,就是空间申请,这里怀疑还是Header结构定义跟WSDL定义不相符,导致空间申请时出乱子。  回复  更多评论   

# re: GSOAP:添加Header的处理 2010-01-19 09:58 lmode

@codejie
我生成代码的wsdl文件都没有soap header的,估计是这个原因,soapheader是协议里另外写的..  回复  更多评论   

# re: GSOAP:添加Header的处理 2010-01-19 11:32 codejie

@lmode
这种情况下建议别看协议文档,直接看WSDL定义来,人工实现Header的结构。对于某些WSDL,GSOAP是存在无法自动生成代码的情况,尤其是‘CTC’或者某个设备商提供的WSDL文档,不规范的地方比比皆是。。。  回复  更多评论   

# re: GSOAP:添加Header的处理 2010-01-19 14:23 lmode

这样修改代码就通过了.具体原因还不明白...
a->notifyHeader = soap_in_mms2__NotifySOAPHeader(soap, "mms2:NotifySOAPHeader", NULL, "");
  回复  更多评论   

# re: GSOAP:添加Header的处理 2010-01-19 16:33 codejie

@lmode
通过就好。。。

soap_in_mms2__NotifySOAPHeader(soap, "mms2:NotifySOAPHeader", NULL, "");
后面两个参数记得好像是mms2域名标签的地址什么信息,你查看gsoap的文档,有说明的。可以用NULL或者空,因为一般在SOAP报文的前面,会在指定域名的地址的,如果前面没有的,应该就在这里指定了。  回复  更多评论   

# gsoap 发送汉字标题,终端显示乱码 2010-03-05 13:39 lmode

gsoap 发送汉字标题,终端显示乱码,英文的就不会有问题,我把汉字从gb2312转成utf-8,终端还是乱码  回复  更多评论   

# re: GSOAP:添加Header的处理 2010-03-05 14:59 codejie

@lmode
首先可能需要确认数据是否正确,如果正确,那可能是数据存储和终端显示的问题。比如我使用wxString存放中文数据,如果不调用setlocale()设置wcout,则cmd终端输出就会出错。  回复  更多评论   

# re: GSOAP:添加Header的处理 2010-03-08 12:40 lmode

@codejie

问题解决了,直接转unicode,再组合成文本格式就可以了,不要转utf-8  回复  更多评论   

# re: GSOAP:添加Header的处理 2010-03-08 13:53 codejie

@lmode
辛苦啊~  回复  更多评论   

# re: GSOAP:添加Header的处理 2010-04-07 16:48 davelv

最近也看了gsoap,对很多内置函数使用的一个变量 int id;不是很理解。
博主明白这是什么东西吗?  回复  更多评论   

# re: GSOAP:添加Header的处理[未登录] 2010-04-07 22:14 codejie

@davelv
不好意思,你说哪个id?能给段代码不?我都忘光光了。。。  回复  更多评论   

# re: GSOAP:添加Header的处理 2010-04-08 16:10 davelv

@codejie
比如这个gsoap自带方法
soap_outint(struct soap *soap, const char *tag, int id, const int *p, const char *type, int n);
或者根据头文件生成出来的方法
SOAP_FMAC3 int SOAP_FMAC4 soap_out_cwmp__Reboot(struct soap *soap, const char *tag, int id, const struct cwmp__Reboot *a, const char *type)

凡是out的方法都会有个一个int id,不晓得这个id是什么作用。不知博主是否注意过这个东西
  回复  更多评论   

# re: GSOAP:添加Header的处理 2010-04-08 16:16 davelv

in方法也一样。博主的方法里面就有这个int id参数  回复  更多评论   

# re: GSOAP:添加Header的处理 2010-04-08 17:27 codejie

@davelv
这个ID我还真没认真想过,可能是跟tag对应的,tag是字符串参数,id就是数字参数,应该是定位用的。一般情况下是用tag定位的,所以这个id可以填-1。
一句话,调用时,如果有id,比如传入就有,那就继续传进去;如果是需要新填,那就用-1试试。
仅供参考啊。。。。  回复  更多评论   

# re: GSOAP:添加Header的处理 2010-04-08 17:50 davelv

@codejie
我目前也都是按照-1写进去的,因为我看到它别的代码也大都这么写。
听博主的解释,应该差不多这个样子。谢谢。  回复  更多评论   

# re: GSOAP:添加Header的处理 2012-08-15 20:02 Tulipomania

请问楼住如何调用你修改的 soap_out_SOAP_ENV__Header函数在客户端?能否提供个例子?多谢!  回复  更多评论   

# re: GSOAP:添加Header的处理[未登录] 2012-08-15 22:47 codejie

@Tulipomania
啊...完全没印象了...是不是gsoap框架会自动调用啊?不好意思,真的都忘记了...  回复  更多评论   

# re: GSOAP:添加Header的处理 2012-08-18 06:46 Tulipomania

没关系,时间久远,要我也会忘记的。多谢你的信息。  回复  更多评论   

# re: GSOAP:添加Header的处理 2013-08-06 11:55 阿斯蒂芬

mms2__RequestSOAPHeader请问这个变量是在哪定义的呢?  回复  更多评论   

# re: GSOAP:添加Header的处理 2013-08-06 12:45 codejie

@阿斯蒂芬
这个应该是wsdl脚本写好,然后自动生成的吧...(抱歉啊,时间嗖嗖的啊...)  回复  更多评论   


只有注册用户登录后才能发表评论。
【推荐】超50万行VC++源码: 大型组态工控、电力仿真CAD与GIS源码库
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理


公告

Using C++

导航

统计

留言簿(73)

随笔分类(513)

积分与排名

最新评论

阅读排行榜

评论排行榜