简体   繁体   English

使用REST API和Qt与QNetworkRequest向JIRA问题添加附件

[英]Adding attachment to JIRA issue using the REST API and Qt with QNetworkRequest

I'm trying to add an attacment to an existing JIRA issue using the REST API and Qt. 我正在尝试使用REST API和Qt将附件添加到现有JIRA问题中。

When I run the code below, the reply is an empty array ("[]"). 当我运行下面的代码时,答复是一个空数组(“ []”)。

edit: updated the code 编辑:更新了代码

QString APIhandler::attachFile(QString fileloc, QString issueKey, QString cookie)
{

//create multiPart
QHttpMultiPart *multiPart = new QHttpMultiPart(QHttpMultiPart::FormDataType);

QFile *file = new QFile(fileloc);
//create httpPart for file
QHttpPart filePart;

filePart.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("application/octet-stream"));
filePart.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"file\"; filename=\""+ file->fileName()+ "\""));



file->open(QIODevice::ReadOnly); 
filePart.setBodyDevice(file);

file->setParent(multiPart);

multiPart->append(filePart);

QNetworkAccessManager *mngr = new QNetworkAccessManager();

QUrl issurl(baseURL + "/api/2/issue/"+ issueKey + "/attachments");

QNetworkRequest req(issurl);
QNetworkReply *reply ;

QEventLoop loop;

//add headers
req.setRawHeader("cookie", "JSESSIONID = " + cookie.toUtf8()); // the session cookie
req.setRawHeader("X-Atlassian-Token", "nocheck");
req.setRawHeader("Content-Type", "multipart/form-data; boundary=------------------------53a5a2cd1d9c8b7f");
//req.setRawHeader("Content-Length", postDataSize);

reply = mngr->post(req, multiPart);
multiPart->setParent(reply);
QObject::connect(reply, SIGNAL(finished()), &loop, SLOT(quit()));

loop.exec();


return reply->readAll();

}

I am using the JIRA REST API documentation and qt documentation for reference, and looking off of this java implementation (which I've tried to replicate). 我正在使用JIRA REST API文档qt文档作为参考,并且正在寻找这个 Java实现(我已经尝试过复制)。

It seems like I'm either missing a header, or adding the file incorrectly. 好像我缺少标题,或错误地添加了文件。

Any help is greatly appreciated! 任何帮助是极大的赞赏!

EDIT - Here's part of a wireshark comparing the example from the api using curl (LEFT) , and my code (RIGHT). 编辑-这是Wireshark的一部分,比较了使用curl(LEFT)和我的代码(RIGHT)的api示例。 The one on the left works, and clearly has different MIME data, but I'm not sure how to implement that in Qt 左边的一个有效,并且显然具有不同的MIME数据,但是我不确定如何在Qt中实现它

在此处输入图片说明

Okay, so I figured it out. 好的,我知道了。 I might be the only one on earth who is using (or will use) Qt to interact with the JIRA API, but for posterity, here's what I came up with: 我可能是地球上唯一使用(或将使用)Qt与JIRA API进行交互的人,但是为了后代,这是我想出的:

QString APIhandler::attachFile(QString fileloc, QString issueKey, QString cookie)
{

    QHttpMultiPart *multiPart = new QHttpMultiPart(QHttpMultiPart::FormDataType);
    QHttpPart filePart;
    QFileInfo fileInfo(fileloc);

    //what I wasn't doing before!
    multiPart->setBoundary("------------------------53a5a2cf4d9c8b7f");

    filePart.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"file\"; filename=\""+fileInfo.fileName() +"\""));
    filePart.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("application/octet-stream"));

    QFile *file = new QFile(fileloc);
    file->open(QIODevice::ReadOnly); 
    filePart.setBodyDevice(file);

    file->setParent(multiPart);
    multiPart->append(filePart);

    QNetworkAccessManager *mngr = new QNetworkAccessManager();

    QUrl issurl(baseURL + "/api/2/issue/"+ issueKey + "/attachments");

    QNetworkRequest req(issurl);
    QNetworkReply *reply ;

    QEventLoop loop;

    //add headers
    req.setRawHeader("X-Atlassian-Token", "nocheck");
    req.setRawHeader("cookie", "JSESSIONID = " + cookie.toUtf8()); // the session cookie
    req.setRawHeader("Content-Type", "multipart/form-data;boundary=------------------------53a5a2cf4d9c8b7f");

    reply = mngr->post(req, multiPart);
    multiPart->setParent(reply);
    QObject::connect(reply, SIGNAL(finished()), &loop, SLOT(quit()));

    loop.exec();

    //read the reply
    QByteArray bytes=reply->readAll();

    //return the reply JSON 
    return QString::fromUtf8(bytes.data(), bytes.size());

    delete file;
    delete multiPart;
    delete reply;
    delete mngr;

}

The key part here, and what I was doing wrong, was the way in which I set the boundary for the multipart. 这里的关键部分以及我做错的是我设置多部分边界的方式。 Instead of setting it in the header, I should have used: 而不是在标题中设置它,我应该使用:

multipart->setBoundary()

Which you can see reflected above. 您可以在上面看到。

If you're coming across this and are going to use it, I'd recommend cleaning it up a bit, first. 如果您遇到此问题并打算使用它,建议您先对其进行一些清理。 But it works! 但这有效!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM