Codejie's C++ Space

Using C++

GSOAP:添加FAULT的处理

不知道是WSDL描述还是GSOAP自身的问题,有其生成的代码中在不支持Header的情况下,一样不支持对FAULT处理,于是,照着处理Header的过程,添加了对FAULT的处理。
     为处理FAULT,需要事先知道SOAP报文中将FAULT信息放在哪里,当然了,一般自定义扩充都放在DETAIL里面。只是开始不太确定,于是还特意发了个错误报文给对端,收到如下回复,从而确认猜测是对的,这样就可以修改了。

<?xml version='1.0' encoding='utf-8'?><soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"><soapenv:Header /><soapenv:Body><soapenv:Fault><faultcode>soapenv:Client</faultcode><faultstring>Authentication Failed AccessCfgHelper.getProductInfor(productId) is empty or is null..</faultstring><detail><ns2:ServiceException xmlns:ns2="http://www.chinatelecom.com.cn/schema/ctcc/common/v2_1"><messageId>SVC0901</messageId><text>CP/SP authenticate access failed:Authentication Failed AccessCfgHelper.getProductInfor(productId) is empty or is null..</text></ns2:ServiceException></detail></soapenv:Fault></soapenv:Body></soapenv:Envelope>


    首先在Detail结构里面添加所需要的Fault类型:
#ifndef SOAP_TYPE_SOAP_ENV__Detail
#define SOAP_TYPE_SOAP_ENV__Detail (90)
/* SOAP-ENV:Detail */
struct SOAP_ENV__Detail
{
public:
    
//int __type;    /* any type of element <fault> (defined below) */
    
//void *fault;    /* transient */
    
//char *__any;

    sms2__ServiceException 
*serviceException;
    sms2__PolicyException 
*policyException;
};
#endif

    然后就是一样修改Detail的in和out函数了:
SOAP_FMAC3 int SOAP_FMAC4 soap_out_SOAP_ENV__Detail(struct soap *soap, const char *tag, int id, const struct SOAP_ENV__Detail *a, const char *type)
{
    
if (soap_element_begin_out(soap, tag, soap_embedded_id(soap, id, a, SOAP_TYPE_SOAP_ENV__Detail), type))
        
return soap->error;
    
//if (soap_putelement(soap, a->fault, "fault", -1, a->__type))
    
//    return soap->error;
    
//soap_outliteral(soap, "-any", &a->__any, NULL);

    
if(a != NULL)
    {
        
if(a->serviceException != NULL)
            a
->serviceException->soap_out(soap, "sms2:ServiceException"-1"");
        
else if(a->policyException != NULL)
            a
->policyException->soap_out(soap, "sms2:PolicyException"-1"");
    }

    
return soap_element_end_out(soap, tag);
}

SOAP_FMAC3 struct SOAP_ENV__Detail * SOAP_FMAC4 soap_in_SOAP_ENV__Detail(struct soap *soap, const char *tag, struct SOAP_ENV__Detail *a, const char *type)
{
    
//size_t soap_flag_fault = 1;
    
//size_t soap_flag___any = 1;
    if (soap_element_begin_in(soap, tag, 0, type))
        
return NULL;
    a 
= (struct SOAP_ENV__Detail *)soap_id_enter(soap, soap->id, a, SOAP_TYPE_SOAP_ENV__Detail, sizeof(struct SOAP_ENV__Detail), 0, NULL, NULL, NULL);
    
if (!a)
        
return NULL;
    soap_default_SOAP_ENV__Detail(soap, a);

    
int service = 1;
    
int policy = 1;

    
if (soap->body && !*soap->href)
    {
        
for (;;)
        {    soap
->error = SOAP_TAG_MISMATCH;
            
//if (soap_flag_fault && soap->error == SOAP_TAG_MISMATCH)
            
//    if ((a->fault = soap_getelement(soap, &a->__type)))
            
//    {    soap_flag_fault = 0;
            
//        continue;
            
//    }
            
//if (soap_flag___any && (soap->error == SOAP_TAG_MISMATCH || soap->error == SOAP_NO_TAG))
            
//    if (soap_inliteral(soap, "-any", &a->__any))
            
//    {    soap_flag___any--;
            
//        continue;
            
//    }
            
            
if (soap->error == SOAP_TAG_MISMATCH)
            {
                
if(service == 1)
                {
                    a
->serviceException = soap_in_sms2__ServiceException(soap, "sms2:ServiceException", a->serviceException, "");
                    
if(a->serviceException)
                    {
                        service 
= 0;
                        
continue;
                    }
                }
                
else if(policy == 1)
                {
                    a
->policyException = soap_in_sms2__PolicyException(soap, "sms2:PolicyException", a->policyException, "");
                    
if(a->policyException)
                    {
                        policy 
= 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__Detail *)soap_id_forward(soap, soap->href, (void*)a, 0, SOAP_TYPE_SOAP_ENV__Detail, 0sizeof(struct SOAP_ENV__Detail), 0, NULL);
        
if (soap->body && soap_element_end_in(soap, tag))
            
return NULL;
    }
    
return a;
}

    由此,SOAP接口的主要问题除了“附件”还没有处理外,就都解决了,其他都是业务应用的问题了,处理起来就有底了~

posted on 2009-07-27 18:34 codejie 阅读(1799) 评论(0)  编辑 收藏 引用 所属分类: C++


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


公告

Using C++

导航

统计

留言簿(73)

随笔分类(513)

积分与排名

最新评论

阅读排行榜

评论排行榜