从Poco::Net::HTTPServerRequest 中获取Content

1.使用 Poco::Net::HTMLForm

使用 Poco::Net::HTMLForm 获取 数据的方式如下:

virtual void handleRequest(Poco::Net::HTTPServerRequest &req, Poco::Net::HTTPServerResponse &resp) override
{
    Poco::Net::HTMLForm form(req, req.stream());
    for(const auto &it : form)
    {
        //遍历 form 数据
        std::cout << it.first << ":" << it.second << std::endl;
    }
}

Poco::Net::HTMLForm 对象初始化的时候,会首先读取 req.stream() 中的数据,然后对数据进行解析。
查看 poco/Net/src/HTMLForm.cpp源码,发现HTMLForm只能支持两种格式的数据:

  • multipart/form-data
  • 非multipart/form-data
 const std::string HTMLForm::ENCODING_URL           = "application/x-www-form-urlencoded";
 const std::string HTMLForm::ENCODING_MULTIPART     = "multipart/form-data";
 const int         HTMLForm::UNKNOWN_CONTENT_LENGTH = -1;

当 Poco 检测到 Content-Type 是 multipart/form-data 的时候,就会执行 void HTMLForm::readMultipart(std::istream& istr, PartHandler& handler) 方法,如果不是 multipart/form-data ,那么就执行 void HTMLForm::readUrl(std::istream& istr) 方法。

  • HTMLForm::readMultipart() 方法会把每一个 part 作为一个 name:value 进行解析;如果遇到文件 ,就直接忽略这个文件的内容。文件可以使用自定义的 Poco::Net::PartHandler去解析;
  • HTMLForm::readUrl()方法会把 content 内的所有内容作为很多 name:value 进行解析,'=‘作为name 和 value 的分隔符,’&'作为多个 name:value 之间的分隔符。获取name 和 value 后再进行 urldecode 解码。
    Poco::Net::HTMLForm 的缺点就是把内容强制作为 form 进行解析,因为它根本不检查 Content-Type 是什么。

2.直接读取 req.stream()

如果接收到的数据是 json,那么最好不要使用 Poco::Net::HTMLForm,尤其是数据中有 ‘=’ 存在的时候,Poco::Net::HTMLForm 会直接把 ‘=’ 作为分隔符使用,'=‘左边的是 name,’='右边的是 value。

那么如何读取 json 数据呢? 我们可以直接读取 req.stream(),然后再解析json数据,就像下面这样:

void PeripheralGpsHandler::MethodPut(Poco::Net::HTTPServerRequest &request, Poco::Net::HTTPServerResponse &response)
{
    int len = request.getContentLength();
    if (len < 0)
    {
        return;
    }
    istream& in = request.stream();
    Poco::JSON::Parser parser;
    Poco::Dynamic::Var result = parser.parse(in);
    Poco::JSON::Object::Ptr pObj = result.extract<Poco::JSON::Object::Ptr>();
    std::string value = pObj->getValue<std::string>("value");	//如果没有 value 字段, POCO框架会抛出一个异常, 但是程序不会崩溃
 	// Poco::Dynamic::Var varValue = pObj->get("value");	// 即使没有 value 字段,程序也不会崩溃,但是 varValue 的内容为空, 
 	//可以在后面通过 if (!varValue.isEmpty()) { std::string value = varValue.convert<std::string>(); } 来判断;
 	//也可以在执行这一句之前,使用 if (pObject->has("value")) { }来判断该Json对象中是否含有此字段,如果含有则取出;
 	
//        // Poco::JSON::Object类 getValue 源码
//        template<typename T>
//        T getValue(const std::string& key) const
//        {
//            Dynamic::Var value = get(key);
//            return value.convert<T>();
//        }
		/// Retrieves the property with the given name and will
		/// try to convert the value to the given template type.
		/// The convert<T>() method of Var is called
		/// which can also throw exceptions for invalid values.
		/// Note: This will not work for an array or an object.


  • 服务端响应HTTP请求时,req.stream()函数返回的输入流就是HTTP请求的请求体内容

  • 客户端发送HTTP请求时,session.sendRequest(request);只是将HTTP头组建到std::ostream,并返回ostream,我们需要通过在返回的这个ostream中追加body来诗选 HTTP Body的内容和传输

	Poco::Net::HTTPClientSession session("ip", port);
	session.setTimeout(Poco::Timespan(500 * 1000)); //超时时间500ms

	std::ostream& requestStream = session.sendRequest(request);
	QByteArray data = ui->comboBox->currentData().value<QByteArray>();
	requestStream.write(data.data(), data.size()); // 将需要发送的字节数组写入请求流中
	requestStream.flush();                         // 刷新请求流,确保数据被发送
  • 客户端接收HTTP响应时,session.receiveResponse(response); 是获取HTTP响应的响应体。
	//接收HTTP响应
	Poco::Net::HTTPResponse response;
	std::istream& responseStream = session.receiveResponse(response);
	
	// 从responseStream中读取响应数据
	std::stringstream ss;
	Poco::StreamCopier::copyStream(responseStream, ss);
	std::string responseData = ss.str();
  • 8
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值