2010-04-08 19 views
46

Tengo un servicio web que necesito PARA PUBLICAR algunos datos para usar Qt. Pensé que puedo usar un QByteArray al realizar una POST en el servicio web.¿Cómo puedo PUBLICAR datos en una url usando QNetworkAccessManager

Mi pregunta es, ¿cómo puedo formatear esta matriz para ser analizada correctamente en el otro extremo?

Este es el código que tengo hasta ahora:

// Setup the webservice url 
    QUrl serviceUrl = QUrl("http://myserver/myservice.asmx"); 
    QByteArray postData; 

    /* 
    Setup the post data somehow 
    I want to transmit: 
    param1=string, 
    param2=string 
    */ 

    // Call the webservice 
    QNetworkAccessManager *networkManager = new QNetworkAccessManager(this); 
    connect(networkManager, SIGNAL(finished(QNetworkReply*)), this, SLOT(serviceRequestFinished(QNetworkReply*))); 
    networkManager->post(QNetworkRequest(serviceUrl), postData); 

Gracias!

Respuesta

14

utilicé:

QByteArray postData; 
postData.append("param1=string&"); 
postData.append("param2=string"); 

Así & en lugar de salto de línea después de cada parámetro.

+7

Este enfoque no protege contra que los caracteres estén en la entrada. Si 'cadena' es la entrada del usuario, podrían inyectar parámetros. – Halfgaar

-4
QByteArray postData; 
postData.append("param1=string,\n"); 
postData.append("param2=string\n"); 
+2

Esto ni siquiera funciona – relipse

5

la realidad respuesta es

QByteArray postData; 
postData.append("param1=string&"); 
postData.append("param2=string"); 

NOTA: utilizar "&" aquí !!!.

No noté la respuesta de Juha aquí, y perdí mucho tiempo en probar mi código con el método ", \ n".

Por favor, cambie la respuesta correcta a la de Juha.

101

Debido a que algunos parámetros y valores que tenga que ser UTF-8 y codificado por ciento (espacios, &, =, caracteres especiales ...), se debe utilizar en lugar QUrl (para Qt 4) o QUrlQuery (para Qt 5) para construir la cadena publicada.

código de ejemplo para Qt 4:

QUrl postData; 
postData.addQueryItem("param1", "string"); 
postData.addQueryItem("param2", "string"); 
... 
QNetworkRequest request(serviceUrl);  
request.setHeader(QNetworkRequest::ContentTypeHeader, 
    "application/x-www-form-urlencoded"); 
networkManager->post(request, postData.encodedQuery()); 

y para Qt 5:

QUrlQuery postData; 
postData.addQueryItem("param1", "string"); 
postData.addQueryItem("param2", "string"); 
... 
QNetworkRequest request(serviceUrl); 
request.setHeader(QNetworkRequest::ContentTypeHeader, 
    "application/x-www-form-urlencoded"); 
networkManager->post(request, postData.toString(QUrl::FullyEncoded).toUtf8()); 

Comenzando con Qt 4.8 también se puede utilizar QHttpMultiPart si necesita subir archivos.

+7

Esta es sin duda la forma más adecuada de llevar a cabo la tarea en cuestión. +1. –

+2

A partir de Qt 5, QUrl ya no tiene addQueryItem(). – mjk99

+1

@ mjk99 'QUrlQuery', pero no tiene' .encodedQuery() ' – JVE999

2

Aquí es otra manera de manejar esto, estoy usando el código también para dar un código completo:

 // Setup the webservice url   
    QUrl serviceUrl = QUrl("http://myserver/myservice.asmx"); 
    QByteArray postData; 

    QUrl params; 
    params.addQueryItem("param1","string1"); 
    params.addQueryItem("param2","string2"); 

    postData = params.encodedQuery(); 

    // Call the webservice 
    QNetworkAccessManager *networkManager = new QNetworkAccessManager(this); 
    connect(networkManager, SIGNAL(finished(QNetworkReply*)), this, SLOT(serviceRequestFinished(QNetworkReply*))); 

     networkManager->post(QNetworkRequest(serviceUrl), postData); 
7

Actualización alexisdm respuesta a QT5:

// Setup the webservice url 
QUrl serviceUrl = QUrl("http://your.url"); 
QByteArray postData; 

QUrl params; 
QUrlQuery query; 
query.addQueryItem("param1","string1"); 
query.addQueryItem("param2","string2"); 

params.setQuery(query); 

postData = params.toEncoded(QUrl::RemoveFragment); 

// Call the webservice 
QNetworkAccessManager *networkManager = new QNetworkAccessManager(this); 
connect(networkManager, SIGNAL(finished(QNetworkReply*)), 
     SLOT(onPostAnswer(QNetworkReply*))); 

QNetworkRequest networkRequest(serviceUrl); 
networkRequest.setHeader(QNetworkRequest::ContentTypeHeader,"application/x-www-form-urlencoded"); 

networkManager->post(networkRequest,postData); 

No se olvide de incluir

QT += network 

en .pro.

+1

Lo que hace este código de forma diferente es que la construcción de un QByteArray como Juha es que el postData es '"? Param1 = string1 & param2 = string2 "', lo que no funciona. – Halfgaar

+1

Si realiza varias solicitudes utilizando el mismo administrador de acceso a la red, tiene sentido conectar la ranura a la señal 'finished()' de 'QNetworkReply' en lugar de' QNetworkAccessManager'. De esta forma, puede tener diferentes señales por solicitud y manejarlas por separado, o manejar datos parte por parte usando la señal 'readyRead()'. – nurettin

Cuestiones relacionadas