C++ Poco服务端框架中JSON的使用
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
文章目录
- 前言
- 一、JSON是什么?
- 二、使用步骤
- 总结
前言
上面一篇文章教你学会了Poco开发服务端应用,这个教程教会你使用JSON。一般传JSON的时候都是POST请求,很少有人把JSON序列化放在GET请求里,不安全。
如果你不会开发服务端就先看下下面的文章,通俗易懂。我直接开门见山了,默认环境已经有了。
手把手教你使用Poco框架开发服务器应用
一、JSON是什么?
JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,设计上易于人类阅读和编写,同时也便于机器解析和生成。它源自 JavaScript 编程语言,但现在被广泛用于不同的编程环境中。
JSON 的特点
文本格式:JSON 是一种纯文本格式,由键值对和数组组成。
语言无关:虽然最初基于 JavaScript,但现在几乎所有编程语言都支持 JSON。
轻量级:结构简单,适用于数据交换,尤其是在 Web 应用程序中。
二、使用步骤
基于上面的代码在RequestHander里面先解析JSON,再写回JSON。
UpdateRequestHanler.cpp
//
// Created by anold on 2024-08-06.
//#ifndef POCO_HTTP_SERVER_UPDATEREQUESTHANDLER_H
#define POCO_HTTP_SERVER_UPDATEREQUESTHANDLER_H#include <iostream>
#include <Poco/Net/HTTPRequestHandler.h>
#include <Poco/Net/HTTPServerRequest.h>
#include <Poco/Net/HTTPServerResponse.h>
#include <Poco/JSON/Parser.h>
#include <Poco/JSON/Stringifier.h>
#include <Poco/Dynamic/Var.h>
#include <Poco/Data/RecordSet.h>
#include <Poco/Data/DataException.h>
#include <Poco/Data/MySQL/MySQLException.h>using namespace Poco::Net;class UpdateRequestHandler : public Poco::Net::HTTPRequestHandler {
public:void handleRequest(HTTPServerRequest &request, HTTPServerResponse &response) override {response.setStatus(Poco::Net::HTTPResponse::HTTP_OK);response.setContentType("application/json");auto &os = response.send();//root就是一会要response的JSON结构,因为就算出错了也要告诉请求人结果Poco::JSON::Object root;//JSON对象转换成字符串流std::stringstream ss;try {//JSON解析代码,可以直接把request.stream()传进去一次性解析出来Poco::JSON::Parser parser;Poco::Dynamic::Var result = parser.parse(request.stream());//object 就是最终解析的JSON对象,是个智能指针不需要手动回收内存,如果解析失败会触发异常Poco::JSON::Object::Ptr object = result.extract<Poco::JSON::Object::Ptr>();//JSON取值代码,这里没有对key是否存在和类型进行判断,二十借助了异常简化了代码实现//比如需要int类型,哪怕传个数字字符串也可以正常解析,会自动转换,如果是字母就抛异常auto id = object->getValue<int>("id");auto class_id = object->getValue<int>("class_id");//数据库会话池Session session(MySQLSessionPool::pool->get());if (!session.isGood()) {root.set("status", -400);root.set("message", "Error Connect To MySQL");//JSON对象写入字符串流然后序列化成字符串responsePoco::JSON::Stringifier::stringify(root, ss);os << ss.str();return;}//语句执行Statement statement(session);statement << "UPDATE student SET class_id=? WHERE id=?", use(class_id), use(id);auto rows = statement.execute();std::cout << "Effect Rows: " << rows << std::endl;if (statement.done() && rows == 1) {root.set("status", 200);root.set("message", "Success");Poco::JSON::Stringifier::stringify(root, ss);os << ss.str();} else {root.set("status", -500);root.set("message", "Error Execute Statement");Poco::JSON::Stringifier::stringify(root, ss);os << ss.str();return;}} catch (const Poco::Data::MySQL::MySQLException &e) {std::cout << "MySQL Exception: " << e.message() << std::endl;root.set("status", -600);root.set("message", "MySQL Exception: " + e.message());Poco::JSON::Stringifier::stringify(root, ss);os << ss.str();} catch (const Poco::Exception &e) {std::cout << "Poco Exception: " << e.message() << std::endl;root.set("status", -200);root.set("message", "Poco Exception: " + e.message());Poco::JSON::Stringifier::stringify(root, ss);os << ss.str();} catch (const std::exception &e) {std::cout << "Std Exception: " << e.what() << std::endl;root.set("status", -300);root.set("message", "Std Exception: " + std::string(e.what()));Poco::JSON::Stringifier::stringify(root, ss);os << ss.str();}}
};#endif //POCO_HTTP_SERVER_UPDATEREQUESTHANDLER_H
注:为什么用3个异常处理?
1、如果JSON格式出错理论上你需要对每个传进来的JSON值进行两步校验,即是否存在这个key和value是否是你需要的类型,否则一旦出错就会出现崩溃的风险,不要抱侥幸心理认为只要传值的人不犯错就没事,你是服务者,你要做的就是一定不能出错,至少不能崩溃,最差的情况哪怕HTTP请求超时也不是不能接受。
2、本身Poco框架就刻意简化了处理方式,比如Poco::Exception可以捕捉所有的JSON错误(不止JSON,可以看下源码类层次),哪怕传过来的是空字符串, e.message()可以获取具体的错误信息,将这个信息反回即可。哪怕你默认的请求是POST,别人给你传了GET,这段代码也是可以正常运行的,它会报错,但是美中不足的是报错的原因无法看出是Method的问题,这一点我觉得无关紧要,这肯定是请求者的问题,我不可能考虑的面面俱到。同样,Poco框架虽然提供了获取Method的方法,但是它没有过度区分到底是POST还是GET,而是把它归到了一起由开发者来决定处理方法,况且区分Method也是对请求人的硬性要求。
3、Poco::Data::MySQL::MySQLException捕捉数据库相关异常,但是注意:捕捉不了所有的CIUD结果,有些结果不触发异常,比如UPDATE语句,statement << "UPDATE student SET class_id=? WHERE id=?", use(class_id), use(id);这句的执行结果可能不成功,但是它可能不抛异常,可以通过返回影响行数来判断语句是否成功。std::exception能捕捉任何运行时异常,是最后的保命手段。不要担心异常会影响性能,异常对性能最大的影响是触发时的堆栈展开(stack unwinding),但是堆栈展开只有异常发生的时候才会触发,很多编译器对异常有优化,没有触发异常的语句可以获得近乎原生的性能,所以大胆地使用异常吧,但不要滥用。
总结
1、最后的总结才是最核心的部分,特别适合初学者,能少走很多弯路。
相关文章:
C++ Poco服务端框架中JSON的使用
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言一、JSON是什么?二、使用步骤总结 前言 上面一篇文章教你学会了Poco开发服务端应用,这个教程教会你使用JSON。一般传JSON的时候都是POS…...
leetcode787. K 站中转内最便宜的航班——优先队列优化的Dijkstra算法+剪枝
题目 leetcode787. K 站中转内最便宜的航班 题目分析 给定一个城市图,每个城市通过航班与其他城市相连。每个航班都有一个起点、终点和价格。你需要找到从起点城市 src 到终点城市 dst 的最便宜路径,但这条路径最多只能经过 k 个中转站。你需要返回这…...
赛盈分销亮相AI科技大会暨亚马逊新增长大会,与企业共话跨境品牌发展新机遇!
八月开端,由知无不言与xmars和钱老师课堂联合主办的2024年AI科技大会暨亚马逊新增长大会在深圳宝安顺利开展,为期2天的跨境峰会吸引了上千位优秀的卖家朋友前来感受一场盛夏大狂欢。在本次跨境峰会里,邀请了多位不同领域的先锋人物࿰…...
Nacos-配置中心
1.为什么要使用配置中心? 2.常用的配置中心组件? 3.如何使用? 在配置中心创建配置文件 启动一个单列的nacos服务 点击发布 在微服务中使用 添加依赖 <!--nacso配置中心的依赖--><dependency><groupId>com.alibaba.cloud&l…...
ava中的文件操作、IO流、递归和字符集
目录 File类的使用 创建File对象 创建和删除文件 遍历文件夹 IO流 字节流 读取文件 字符流 读取文本文件 写入文本文件 递归 计算阶乘 文件搜索 字符集 编码与解码 File类的使用 在Java中,File类用于表示文件和目录的路径。它提供了一些方法来创建、删…...
生成式人工智能安全评估体系构建
文章目录 前言一、人工智能安全治理的现状1.1 国际安全治理现状1.2 国内安全治理现状二、构建人工智能安全评估体系1.1 需要对生成式人工智能技术的安全性、可靠性、可控性、公平性等维度进行全面的考量。1.2 应对生成式人工智能全维度风险。1.3 在体系化应对框架中,应明确法律…...
NRBO-XGBoost分类 基于牛顿-拉夫逊优化算法[24年最新算法]-XGBoost多特征分类预测+交叉验证
NRBO-XGBoost分类 基于牛顿-拉夫逊优化算法[24年最新算法]-XGBoost多特征分类预测交叉验证 多输入单输出) matlab代码 程序已调试好,无需更改代码替换数据直接使用!!!数据格式为excel格式!需要定制可私&a…...
synchronized实现原理及优化
一、概述 线程安全在并发编程中是重要关注点,造成线程安全问题的主要诱因有两个:一是存在共享数据(也称临界资源),二是存在多个线程共同操作共享数据。synchronized关键字能够保证在同一时刻只有一个线程可以执行某个…...
NLP 之词的表示与语言模型
表示的基本原理: 机器无法理解文字,却能进行复杂的数学运算——神经网络只要够深、够复杂,就能拟合足够复杂的数学模式。把文字嵌入(embed)到一个向量空间中去。 词表示(Word Representation)…...
每天一个数据分析题(四百七十一)- 假设检验
下列对假设检验的描述合理的是? A. 备择假设是研究者想收集证据予以支持的假设 B. 原假设是研究者想收集证据予以推翻的假设 C. 原假设是研究者想收集证据予以支持的假设 D. 备择假设是研究者想收集证据予以推翻的假设 数据分析认证考试介绍:点击进入 题目来…...
《系统架构设计师教程(第2版)》第13章-层次式架构设计理论与实践-04-数据访问层设计
文章目录 1. 五种数据访问模式1.1 在线访问1.2 DAO1.3 DTO1.4 离线数据模式1.5 对象/关系映射 (O/R Mapping) 2. 工厂方法模式在数据访问层应用3 ORM、Hibernate与CMP2.0设计思想3.1 ORM3.2 Hibernate1)概述2) Hibernate的架构(2023年的考题&…...
【视觉SLAM】 十四讲ch7习题
简介 本文主要内容是《视觉SLAM十四讲》(第二版)第7章的习题解答,并介绍了在解答习题中的一下思考和总结的经验。本文代码部分参考了:HW-of-SLAMBOOK2 1、除了本书介绍的ORB特征点,你还能找到哪些特征点?…...
K-近邻算法(二)
三、 kd 树 问题导⼊: 实现k 近邻算法时, 主要考虑的问题是如何对训练数据进⾏快速 k 近邻搜索。这在特征空间的维数⼤及训练数据容量⼤时尤其必要。 k 近邻法最简单的实现是线性扫描(穷举搜索),即要计算输⼊实例与…...
WPF学习(2)-UniformGrid控件(均分布局)+StackPanel控件(栈式布局)
UniformGrid控件(均分布局) UniformGrid和Grid有些相似,只不过UniformGrid的每个单元格面积都是相等的,不管是横向的单元格,或是纵向的单元格,它们会平分整个UniformGrid。 UniformGrid控件提供了3个属性…...
ANTSDR E310
ANTSDR E310是一款由微相科技有限公司(MicroPhase)推出的软件无线电(SDR)平台,专为现场部署设计。以下是对ANTSDR E310的详细介绍: 一、主要特点 独立运行的软件无线电:ANTSDR E310具备独立运…...
MySQL 5.7 DDL 与 GH-OST 对比分析
作者:来自 vivo 互联网存储研发团队- Xia Qianyong 本文首先介绍MySQL 5.7 DDL以及GH-OST的原理,然后从效率、空间占用、锁阻塞、binlog日志产生量、主备延时等方面,对比GH-OST和MySQL5.7 DDL的差异。 一、背景介绍 在 MySQL 数据库中&…...
【Python】爬取网易新闻今日热点列表数据并导出
1. 需求 从网易新闻的科技模块爬取今日热点的列表数据,其中包括标题、图片、标签、发表时间、路径、详细文本内容,最后导出这些列表数据到Excel中。 网易科技新闻网址:https://tech.163.com 2. 解决步骤 2.1 前期准备 爬虫脚本中需要引用…...
软件设计之HTML5
软件设计之HTML5 【狂神说Java】HTML5完整教学通俗易懂 学习内容: 软件开发技能点参照:软件开发,小白变大佬,这套学习路线让你少走弯路是认真的,欢迎讨论 软件开发技能点参照:Java学习完整路线ÿ…...
CnosDB 元数据集群 – 分布式时序数据库的大脑
CnosDB 是一个分布式时序数据库系统,其中元数据集群是核心组件之一,负责管理整个集群的元数据信息。 1. 概述 CnosDB 是一个分布式时序数据库系统,其中元数据集群是核心组件之一,负责管理整个集群的元数据信息。元数据包括数据库…...
白骑士的Matlab教学进阶篇 2.5 Simulink
Simulink是MATLAB的扩展工具,提供了一个图形化的建模和仿真环境。它广泛应用于系统设计、仿真、自动控制、信号处理等领域。本文将详细介绍Simulink的简介与基本使用、建立与仿真模型、控制系统设计与仿真、与MATLAB的集成。 Simulink简介与基本使用 什么是Simuli…...
(LeetCode 每日一题) 3442. 奇偶频次间的最大差值 I (哈希、字符串)
题目:3442. 奇偶频次间的最大差值 I 思路 :哈希,时间复杂度0(n)。 用哈希表来记录每个字符串中字符的分布情况,哈希表这里用数组即可实现。 C版本: class Solution { public:int maxDifference(string s) {int a[26]…...
23-Oracle 23 ai 区块链表(Blockchain Table)
小伙伴有没有在金融强合规的领域中遇见,必须要保持数据不可变,管理员都无法修改和留痕的要求。比如医疗的电子病历中,影像检查检验结果不可篡改行的,药品追溯过程中数据只可插入无法删除的特性需求;登录日志、修改日志…...
8k长序列建模,蛋白质语言模型Prot42仅利用目标蛋白序列即可生成高亲和力结合剂
蛋白质结合剂(如抗体、抑制肽)在疾病诊断、成像分析及靶向药物递送等关键场景中发挥着不可替代的作用。传统上,高特异性蛋白质结合剂的开发高度依赖噬菌体展示、定向进化等实验技术,但这类方法普遍面临资源消耗巨大、研发周期冗长…...
智能在线客服平台:数字化时代企业连接用户的 AI 中枢
随着互联网技术的飞速发展,消费者期望能够随时随地与企业进行交流。在线客服平台作为连接企业与客户的重要桥梁,不仅优化了客户体验,还提升了企业的服务效率和市场竞争力。本文将探讨在线客服平台的重要性、技术进展、实际应用,并…...
全面解析各类VPN技术:GRE、IPsec、L2TP、SSL与MPLS VPN对比
目录 引言 VPN技术概述 GRE VPN 3.1 GRE封装结构 3.2 GRE的应用场景 GRE over IPsec 4.1 GRE over IPsec封装结构 4.2 为什么使用GRE over IPsec? IPsec VPN 5.1 IPsec传输模式(Transport Mode) 5.2 IPsec隧道模式(Tunne…...
dify打造数据可视化图表
一、概述 在日常工作和学习中,我们经常需要和数据打交道。无论是分析报告、项目展示,还是简单的数据洞察,一个清晰直观的图表,往往能胜过千言万语。 一款能让数据可视化变得超级简单的 MCP Server,由蚂蚁集团 AntV 团队…...
如何在网页里填写 PDF 表格?
有时候,你可能希望用户能在你的网站上填写 PDF 表单。然而,这件事并不简单,因为 PDF 并不是一种原生的网页格式。虽然浏览器可以显示 PDF 文件,但原生并不支持编辑或填写它们。更糟的是,如果你想收集表单数据ÿ…...
安卓基础(aar)
重新设置java21的环境,临时设置 $env:JAVA_HOME "D:\Android Studio\jbr" 查看当前环境变量 JAVA_HOME 的值 echo $env:JAVA_HOME 构建ARR文件 ./gradlew :private-lib:assembleRelease 目录是这样的: MyApp/ ├── app/ …...
Chromium 136 编译指南 Windows篇:depot_tools 配置与源码获取(二)
引言 工欲善其事,必先利其器。在完成了 Visual Studio 2022 和 Windows SDK 的安装后,我们即将接触到 Chromium 开发生态中最核心的工具——depot_tools。这个由 Google 精心打造的工具集,就像是连接开发者与 Chromium 庞大代码库的智能桥梁…...
WPF八大法则:告别模态窗口卡顿
⚙️ 核心问题:阻塞式模态窗口的缺陷 原始代码中ShowDialog()会阻塞UI线程,导致后续逻辑无法执行: var result modalWindow.ShowDialog(); // 线程阻塞 ProcessResult(result); // 必须等待窗口关闭根本问题:…...
