Resumen de c ++ llamando a la interfaz de servicio web basada en https a través de gsop

ww pasos:

Paso 1: generar archivos de encabezado

La interfaz del servicio web generalmente tiene un documento de interfaz externo. Por ejemplo: http://www.webxml.com.cn/WebServices/WeatherWebService.asmx?WSDL

El parámetro después del signo de interrogación representa el documento WSDL, que es un documento XML. No importa si no comprende la configuración. A continuación, debemos generar un archivo de encabezado C++ a través de este documento.

(1) Descargar la herramienta gsoap

Enlace de descarga: Descarga del kit de herramientas gSOAP | SourceForge.net

 Una vez completada la descarga, descomprímalo e ingrese al directorio gsoap \ bin \ win32. Hay dos archivos en este directorio, wsdl2h.exe y Soapcpp2.exe. wsdl2h.exe se utiliza para generar archivos de encabezado. Generar el archivo de encabezado por sí solo no es suficiente, en este momento se debe usar Soapcpp2.exe para generar la estructura de archivo C ++ correspondiente, que se puede usar para llamar al proyecto (presentado en el segundo paso). Primero veamos cómo generar el archivo de encabezado.

 Abra el comando cmd en el directorio gsoap\bin\win32. ingresar:

wsdl2h.exe -o head.h http://www.webxml.com.cn/WebServices/WeatherWebService.asmx?WSDL

 Una vez completada la ejecución, puede ver que hay un archivo de encabezado adicional head.h en el directorio actual. Puedes abrirlo y echar un vistazo, hay algunas funciones de interfaz en su interior.

 Nota: El servicio web utiliza codificación UTF-8 de forma predeterminada durante el proceso de transmisión. Por supuesto, gsoap también utiliza caracteres estrechos de forma predeterminada al generar el archivo de encabezado. Como cadena o char*. En este momento, si los parámetros tienen caracteres chinos durante la llamada nuevamente, los caracteres serán confusos. Hay dos soluciones.

Método 1: agregue una oración al código cuando llame más tarde (el lugar específico para agregar se presentará más adelante):

soap_set_mode(&m_soap, SOAP_C_UTFSTRING);

 Método 2: de forma predeterminada, typemap.dat en el directorio raíz se usa para compilar en caracteres estrechos. No lo aplicamos en este momento, pero creamos un nuevo mytypemap.dat en el directorio actual. El contenido es el siguiente: xsd__string = | std::wstring | wchar_t*. Luego vuelva a ejecutar el comando cmd.

wdsl2h.exe -o head.h -t mytypemap.dat http://www.webxml.com.cn/WebServices/WeatherWebService.asmx?WSDL

 Después de la regeneración, puede encontrar que los tipos de cadena en head.h han cambiado a wchar_t * o tipo wstring.

Paso 2: generar una API invocable

Ejecute el comando cmd en el directorio actual:

soapcpp2.exe -C -x -I ..\..\import head.h

  

Entre ellos, -C solo genera código de cliente. -x significa no generar xml (solo necesitamos código c++) -I significa especificar el directorio de importación.
Después de una ejecución exitosa, hay algunos archivos más en el directorio actual:

 Paso 3: Importar al proyecto
Agregue los archivos en el cuadro rojo en la imagen de arriba a su proyecto. Hay dos archivos más que deben agregarse. También es necesario agregar al proyecto stdsoap2.h y stdsoap2.cpp en el directorio raíz de gsoap.
Haga clic derecho en los tres archivos cpp agregados->Propiedades->Todas las configuraciones->c/c+±>Encabezados precompilados y seleccione no utilizar encabezados precompilados. Como se muestra abajo.

Una vez completada la configuración, puede comenzar a escribir código.

Paso 4: escribe el código

Cree un nuevo proyecto de aplicación basado en MFC llamado: SoapTest 

Cree un nuevo SoapTestDlg.cpp e introduzca el archivo de encabezado.

#include "WeatherWebServiceSoap.nsmap"
#include "soap.h"

Cuando hice referencia a estos dos archivos de encabezado en el proyecto, la compilación informó errores locos. Revisé cuidadosamente y descubrí que todas eran definiciones superpuestas. La razón es que el espacio de nombres en el archivo de encabezado WeatherWebServiceSoap.nsmap entra en conflicto con la biblioteca de sockets original en el proyecto. La solución es escribir #include "WeatherWebServiceSoap.nsmap" al frente Si se utilizan encabezados precompilados, es mejor escribirlos en el archivo stdafx.h . Una vez introducido el archivo de encabezado, compílelo nuevamente y no se informará ningún error. Si no agrega encabezados precompilados, debe configurar SoapC.cpp, SOAPClientLib.cpp, SoapClient.cpp y stdsoap2.cpp para que no utilicen encabezados precompilados.


Todas las interfaces del servicio se pueden ver en SoapClient.cpp. El nombre de la función tiene el formato Soap_call __ns1_XXX.
Primero cree el objeto SOAP e inicialícelo:

struct soap m_soap;
//SOAP初始化
soap_init(&m_soap);
soap_set_mode(&m_oSoap, SOAP_C_UTFSTRING);

Que soap_set_mode(&m_oSoap, SOAP_C_UTFSTRING);es exactamente lo que se dijo al principio para adaptarlo a los caracteres chinos. Si inicialmente se usa wstring o wchar_t *, se puede ignorar. Luego defina la cadena reqXml y llame a la función de interfaz. Es necesario utilizar caracteres de escape entre las comillas dobles en las cadenas xml.

char* _reqXml = "<root>.....</root>";
char* _Return;
soap_call_ns1__XXX(&m_soap, NULL, NULL, G2U(_reqXml), _Return);
string ret = U2G(_Return);

Dado que el código anterior utiliza caracteres estrechos como parámetros, es decir, char *, es necesario convertirlo al formato UTF-8. Las funciones específicas son las siguientes:

char* U2G(const char* utf8)
{
	int len = MultiByteToWideChar(CP_UTF8, 0, utf8, -1, NULL, 0);
	wchar_t* wstr = new wchar_t[len + 1];
	memset(wstr, 0, len + 1);
	MultiByteToWideChar(CP_UTF8, 0, utf8, -1, wstr, len);
	len = WideCharToMultiByte(CP_ACP, 0, wstr, -1, NULL, 0, NULL, NULL);
	char* str = new char[len + 1];
	memset(str, 0, len + 1);
	WideCharToMultiByte(CP_ACP, 0, wstr, -1, str, len, NULL, NULL);
	if (wstr) delete[] wstr;
	return str;
}

char* G2U(const char* gb2312)
{
	int len = MultiByteToWideChar(CP_ACP, 0, gb2312, -1, NULL, 0);
	wchar_t* wstr = new wchar_t[len + 1];
	memset(wstr, 0, len + 1);
	MultiByteToWideChar(CP_ACP, 0, gb2312, -1, wstr, len);
	len = WideCharToMultiByte(CP_UTF8, 0, wstr, -1, NULL, 0, NULL, NULL);
	char* str = new char[len + 1];
	memset(str, 0, len + 1);
	WideCharToMultiByte(CP_UTF8, 0, wstr, -1, str, len, NULL, NULL);
	if (wstr) delete[] wstr;
	return str;
}

En este punto la compilación debería pasar. Sin embargo, la realidad es cruel. El valor _Return devuelto es NULL, lo que indica que algo salió mal. Mi dirección es https. Si uso http directamente para realizar la solicitud, se devolverá 301. La información de búsqueda dice que 301 significa redirección, lo que significa que no puede ingresar http en la barra de direcciones como un navegador, y el navegador lo redireccionará a https. . En este momento, todavía tienes que cambiarlo a https. Compile de nuevo. Um ~ Sigo informando un error. . . Para el código de error, puede verificar el valor del campo de error en la estructura m_soap durante la depuración. Si siempre es 0, significa que no hay problema. Puede consultar los códigos de error específicos en línea.
Después de cambiar a https y luego depurar, puede ver que el valor de m_soap->error es 30. Consulte la documentación y descubra que 30 significa que no se realiza la autenticación de seguridad SSL. Bien ~
agrega el siguiente código después de Soap_init(&m_soap):

soap_ssl_init();
if (soap_ssl_server_context(&m_soap, SOAP_SSL_NO_AUTHENTICATION, NULL, NULL, NULL, NULL, NULL, NULL, NULL)) {
	soap_print_fault(&m_soap, stderr);
	exit(-1);
}

Si hay un certificado SSL en el parámetro SOAP_SSSL_SERVER_CONTEXT, complete la contraseña. Está bien si no es todo NULL.
Después de compilar nuevamente, todavía no pude verificar el código a través de ~ y descubrí que CON_OPENSSLstdsoap2.h no estaba definido en el archivo de encabezado . Es gris abajo.

 Solución: haga clic derecho en las propiedades del proyecto->C/C+±>Preprocesador->Agregar CON_OPENSSL en la definición del preprocesador

 Después de agregarlo, descubrí que el color gris había desaparecido.

 Después de la compilación, se informa nuevamente un error. El mensaje de error es soap_ssl_server_contextun símbolo externo que la función no puede resolver.

razón

        La implementación de esta función no está definida. Olvidé presentar la biblioteca openssl. Dirección de descarga: https://slproweb.com/products/Win32OpenSSL.html

Descarga completa, instalación, directorio de instalación completa.

 Luego haga clic derecho en el proyecto en vs->Propiedades->Propiedades de configuración->Agregar el directorio de inclusión y el directorio de la biblioteca en el directorio VC++, como se muestra a continuación.

 Haga clic derecho en el proyecto en vs->Propiedades->Propiedades de configuración->Biblioteca de enlaces->Entrada->Agregar libcrypto.lib y libssl.lib a los elementos de biblioteca dependientes adicionales, como se muestra a continuación

Estructura de archivos

 Aviso:

Si se informa un error, indica que xx se ha definido en SoapClient.obj, como se muestra a continuación

 Solución:

        Comente todo el archivo SoapClientLib.cpp y compílelo nuevamente.

 La siguiente es la herramienta gsoap+opensll

https://download.csdn.net/download/my_angle2016/88220982

Supongo que te gusta

Origin blog.csdn.net/my_angle2016/article/details/132302759
Recomendado
Clasificación