Qt+Cutelyst学习笔记(二十七)win10+Qt5.15.2+qmake实现一个简单的RESTful服务器

本文档介绍了在win10环境下,使用Qt5.15.2和qmake创建一个简单的RESTful服务器的过程。通过创建控制器类ApiV1并利用Cutelyst的ActionClass(REST)宏,实现了针对HTTP方法的不同处理。文章还展示了编译测试过程,包括GET、POST、PUT和DELETE请求的响应。

前言:

之前的文档记录的都是一些基本功能的实现,本次尝试做一个比较实用的demo,可以以此为模板,创建自己的RESTful服务

一、创建控制器

关于如何创建完整的工程,可以参考笔者之前的文档,在此不再重复

Qt+Cutelyst学习笔记(二十四)win10+Qt5.15.2+qmake实现一个简单的http服务器_aggs1990的博客-优快云博客

Qt+Cutelyst学习笔记(二十五)win10+Qt5.15.2+qmake实现一个简单的https服务器_aggs1990的博客-优快云博客 创建一个类ApiV1,继承自Controller类,并添加方法,apiv1.h如下所示

    C_ATTR(users, :Local :AutoArgs :ActionClass(REST))
    void users(Context *c);

    C_ATTR(users_GET, :Private)
    void users_GET(Context *c);

    C_ATTR(users_POST, :Private)
    void users_POST(Context *c);

    C_ATTR(users_PUT, :Private)
    void users_PUT(Context *c);

    C_ATTR(users_DELETE, :Private)
    void users_DELETE(Context *c);

    C_ATTR(users_uuid, :Path('users') :AutoArgs :ActionClass(REST))
    void users_uuid(Context *c, const QString &uuid);

    C_ATTR(users_uuid_GET, :Private)
    void users_uuid_GET(Context *c, const QString &uuid);

    C_ATTR(users_uuid_POST, :Private)
    void users_uuid_POST(Context *c, const QString &uuid);

    C_ATTR(users_uuid_PUT, :Private)
    void users_uuid_PUT(Context *c, const QString &uuid);

    C_ATTR(users_uuid_DELETE, :Private)
    void users_uuid_DELETE(Context *c, const QString &uuid);

我们来分析下这个声明

 C_ATTR宏用于添加有关MOC将生成的类的元数据,因此Cutelyst知道如何将URL映射到这些函数。

  • :Local -通过生成/api/v1/users将方法名称映射到URL
  • :AutoArgs -自动检查上下文*后的参数数量,在users_uuid中,我们只有一个参数,因此如果URL为/api/v1/users/anything,将调用该方法
  • :ActionClass(REST) ​​- 将加载REST插件,该插件将创建一个操作类来处理此方法,ActionREST将根据调用的方法调用其他方法
  • :Private -在Cutelyst中将操作注册为Private,因此无法通过URL直接访问

第一部分,告诉服务端,要处理请求url为http(s)://localhost:3001/api/v1/users的REST请求

第二部分,告诉服务端,要处理请求url为http(s)://localhost:3001/api/v1/users/*/的REST请求,其中*的位置,对应uuid的参数

根据每个函数的HTTP方法,自动进行函数映射,需要注意的是,第一个函数(没有_METHOD)总是执行的

以第一部分为例,当请求http(s)://localhost:3001/api/v1/users时,users()函数会先执行,然后根据请求的方法不同,再执行对应的函数:

  • 若请求方法为get,则执行users_GET()方法
  • 若请求方法为post,则执行users_POST()方法
  • 若请求方法为put,则执行users_PUT()方法
  • 若请求方法为delete,则执行users_DELETE()方法

第二部分和第一部分类型,只是增加了一个参数,在此不再重复

声明分析完成了,下面看下是如何实现的,apiv1.cpp如下所示

void ApiV1::users(Context *c)
{
    qDebug() << Q_FUNC_INFO
             <<"\n hostname:"<<c->request()->hostname()
            <<"\n port:"<<c->request()->port()
           <<"\n uri:"<<c->request()->uri()
          <<"\n base:"<<c->request()->base()
         <<"\n path:"<<c->request()->path()
        <<"\n match:"<<c->request()->match()
       <<"\n arguments:"<<c->request()->arguments()
     <<"\n secure:"<<c->request()->secure()
    <<"\n bodyData:"<<c->request()->bodyData()
    <<"\n bodyParameters:"<<c->request()->bodyParameters()
    <<"\n queryParameters:"<<c->request()->queryParameters()
    <<"\n contentEncoding:"<<c->request()->contentEncoding()
    <<"\n contentType:"<<c->request()->contentType()
    <<"\n method:"<<c->request()->method()
    <<"\n protocol:"<<c->request()->protocol()
    <<"\n userAgent:"<<c->request()->userAgent()
    <<"\n referer:"<<c->request()->referer()
    <<"\n remoteUser:"<<c->request()->remoteUser();
}

笔者建议,为方便进一步理解,把常用的属性打印下,在编程时,可能会用到某些参数

void ApiV1::users_GET(Context *c)
{
    qDebug() << Q_FUNC_INFO
                <<c->request()->queryParameters();
//    c->request()->queryParameters("arg1");

    c->response()->setJsonObjectBody({
                                        {QStringLiteral("message"), QStringLiteral("users_GET")}
                                    });
}

 对于get方法,可以使用c->request()->queryParameters()获取url里的查询参数

然后返回一个简单的json串

void ApiV1::users_POST(Context *c)
{
    qDebug() << Q_FUNC_INFO
             << c->request()->bodyData()
                <<c->request()->queryParameters();
    c->response()->setJsonObjectBody({
                                        {QStringLiteral("message"), QStringLiteral("users_POST")}
                                     });
}

 对于post方法,可以使用c->request()->queryParameters()获取url里的查询参数

若提交的数据是json,且请求的头设置为application/json,可以通过c->request()->bodyData()获取提交的json对象

然后返回一个简单的json串

put方法和post方法类似;delete方法和get方法类似;就不重复说明了

二、编译测试

直接编译运行,控制台输出如下

 1.来一个get请求:https://localhost:3001/api/v1/users?arg1=val1&arg2=val2

控制台输出如下:

参数也捕获正常

2.来一个post请求:https://localhost:3001/api/v1/users?arg1=val1&arg2=val2

请求数据为 { "key1" = "val1", "key2" = "val2" }

输出如下:

 3.来一个put请求:https://localhost:3001/api/v1/users?arg1=val1&arg2=val2

请求数据为 { "key1" = "val1", "key2" = "val2" }

输出如下:

 4.来一个delete请求:https://localhost:3001/api/v1/users?arg1=val1&arg2=val2

控制台输出如下:

 本次测试源码下载

使用的客户端代码:Qt http(s)同步请求测试(restfull中常用的get/post/put/delete、文件上传/下载)_aggs1990的博客-优快云博客

后记:

基本的请求响应完成了,还有一个常用的操作,就是通过表单上传文件,这个在下一篇中介绍

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

꧁白杨树下꧂

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值