在本页

QHttpServer Class

QHttpServer 是一个用于QAbstractHttpServerQHttpServerRouter 的简化 API。更多

头文件: #include <QHttpServer>
CMake: find_package(Qt6 REQUIRED COMPONENTS HttpServer)
target_link_libraries(mytarget PRIVATE Qt6::HttpServer)
qmake: QT += httpserver
Qt 6.4
继承于 QAbstractHttpServer

公共函数

QHttpServer(QObject *parent = nullptr)
virtual ~QHttpServer() override
void addAfterRequestHandler(const QObject *context, Functor &&slot)
void clearMissingHandler()
Rule *route(const QString &pathPattern, QHttpServerRequest::Methods method, const QObject *context, Functor &&slot)
Rule *route(const QString &pathPattern, Functor &&handler)
Rule *route(const QString &pathPattern, QHttpServerRequest::Methods method, Functor &&handler)
Rule *route(const QString &pathPattern, const QObject *context, Functor &&slot)
QHttpServerRouter *router()
const QHttpServerRouter *router() const
void setMissingHandler(const QObject *context, Functor &&slot)

详细说明

QHttpServer 用于通过注册一系列请求处理程序来创建一个简单的 HTTP 服务器。

route 函数可用于方便地向服务器的QHttpServerRouter 添加规则。要注册一个在每次请求后都会调用的处理程序,以进一步处理响应,请使用addAfterRequestHandler ,但这种机制只适用于返回QHttpServerResponseQFuture<QHttpServerResponse> 的路由。要为所有未处理的请求注册一个处理程序,请使用setMissingHandler

最小示例

QHttpServerserver; server.route("/", []() {return "hello world"; });autotcpserver= newQTcpServer();if(!tcpserver->listen()|| !server.bind(tcpserver)) {deletetcpserver;return-1;}
qDebug() << "Listening on port" << tcpserver->serverPort();

成员函数文档

[explicit] QHttpServer::QHttpServer(QObject *parent = nullptr)

创建 QHttpServer 实例,其父节点为parent

[override virtual noexcept] QHttpServer::~QHttpServer()

销毁QHttpServer.

template <typename Functor> void QHttpServer::addAfterRequestHandler(const QObject *context, Functor &&slot)

注册contextslot ,以便在处理每个请求后调用。

slot 必须实现void (*)(const QHttpServerRequest &, QHttpServerResponse &) 的签名。

slot 也可以是函数指针、不可变 lambda 或其他任何带有 const 调用操作符的可复制可调用对象。在这种情况下,context 将是一个上下文对象,处理程序将一直有效,直到上下文对象被销毁。

示例

server.addAfterRequestHandler(&server, [] (const QHttpServerRequest &req, QHttpServerResponse &resp) {
    auto h = resp.headers();
    h.append(QHttpHeaders::WellKnownHeader::Cookie, "PollyWants=Cracker");
    resp.setHeaders(std::move(h));
}

注意: 只有路由处理程序处理的请求返回QHttpServerResponseQFuture<QHttpServerResponse> 时,才会调用这些处理程序。

void QHttpServer::clearMissingHandler()

将处理程序重置为默认处理程序,以产生状态为404 Not Found 的回复。

另请参阅 setMissingHandler

template <typename Rule = QHttpServerRouterRule, typename Functor> Rule *QHttpServer::route(const QString &pathPattern, QHttpServerRequest::Methods method, const QObject *context, Functor &&slot)

该方法将一个新的路由Rule 添加到服务器的QHttpServerRouter 成员中。Rule 模板参数可以是任何从QHttpServerRouterRule 派生的类。参数传递给Rule 。服务器根据 URL 路径和 HTTP 方法,将传入的 HTTP 请求与已注册的规则进行匹配,并执行两者中最先匹配的规则。

pathPattern 参数与传入请求的 URL 的path() 进行比较。method 参数与传入请求的 HTTP 方法进行比较。slot 参数是请求处理程序。它可以是context 的成员函数指针、函数指针、不可变 lambda 或任何带有 const 调用操作符的可复制可调用函数。如果提供了context ,只要上下文存在,规则就一直有效。context 必须与QHttpServer 共享相同的线程亲和性。

slot 将任意数量的解析参数作为参数,这些参数通过匹配"<arg>" 占位符从pathPattern 中提取,然后是可选的QHttpServerRequest 和可选的QHttpServerResponder 。这两类参数被称为特殊参数。

slot 可以返回QHttpServerResponse 或可转换类型:

QHttpServer server;
server.route("/test/", this, [] () { return ""; });

注意: 不能从slot 调用 route() 这个函数,因此任何路由处理程序都不能注册其他路由处理程序。

另外,如果提供了可选的QHttpServerResponder 参数,则必须使用该参数编写响应,函数必须返回voidQFuture<void>。Qt 6.11 中添加了对QFuture<void> 的支持。QHttpServerResponder 不可复制,可以作为引用或 r 值引用传递,除非返回QFuture<void>,在这种情况下,必须作为 r 值引用传递,以防止超出作用域。

server.route("/test2", this,
             [] (QHttpServerResponder &&responder) {
                responder.write(QHttpServerResponder::StatusCode::Forbidden);
             });

注意: 如果请求是由接受QHttpServerResponder 作为参数的slot 处理的,则不会调用任何后置请求处理程序(参见addAfterRequestHandler )。

此外,QHttpServerRequest 可以作为最后一个参数使用,如果有QHttpServerResponder 参数,也可以作为倒数第二个参数使用,以获取请求的详细信息。它可以作为常量引用(仅适用于非并发回调)或值传递,并可用于访问请求正文:

server.route("/test3", QHttpServerRequest::Method::Post, this,
             [] (QHttpServerRequest request, QHttpServerResponder &&responder) {
                responder.write(request.body(), "text/plain"_ba);
             });

pathPattern 中的任何占位符 ("<arg>" ) 都会自动转换,以匹配处理程序的参数类型。支持的类型包括整数、浮点数、QStringQByteArrayQUrlQUrl 类可用作最后一个参数,以处理pathPattern 的结束,通过分割可支持任意数量的参数。可使用QHttpServerRouter::addConverter() 添加自定义转换器。

每种注册类型都有一个相关的 regex,用于匹配和转换pathPattern 中的占位符。这些 regex 模式组合在一起,构建出整个路径的解析器。然后,生成的解析器将用于验证路径是否与模式匹配。如果解析成功,就会使用转换后的参数调用相应的函数。如果解析失败,则尝试下一个已注册的回调。如果所有回调都解析失败,则调用 missingHandler。

在下面的示例中,请求路径中替换"<arg>" 的值被转换为int ,因为 lambda 期望使用int 参数。当 HTTP 请求与路由匹配时,转换后的值将传递给 lambda 的page 参数:

QHttpServer server;
server.route("/showpage/<arg>", this, [] (int page) { return getPage(page); });

如果成功,该函数将返回一个指向新创建的 Rule 的指针,否则返回一个nullptr 。该指针可用于在任何自定义的QHttpServerRouter 类上设置参数:

auto rule = server.route<MyRule>("/test4", this, [] () {return "";});
rule->setParameter("test");

请求默认在QHttpServer 的线程内按顺序处理。如果需要并发处理,请求处理程序可返回QFuture<QHttpServerResponse>

server.route("/feature/<arg>", [] (int ms) {
    return QtConcurrent::run(pool, [ms] () {
        QThread::msleep(ms);
        return QHttpServerResponse("the future is coming");
    });
});

QtConcurrent::run()的 lambda 会并发执行,但所有网络通信都在QHttpServer 的所属线程中执行。

返回期货的路由只能在 HTTP/2 连接上完全并发执行。早期版本的 HTTP 不支持不同响应的交错部分:响应必须按照请求的顺序完整返回。因此,即使路由处理程序返回QFuture<void>,在处理完当前请求之前,也不会处理 HTTP/1 连接上的下一个传入请求。不过,不同连接上的路由处理程序可以同时执行。

让路由处理程序在并发运行中执行工作,对所有版本的 HTTP 都有好处,因为QHttpServer 所属的线程将从并发运行执行的工作中解脱出来。

QHttpServerRequest 由于传递给slot 的变量可能会在 future 结束前退出作用域,因此在返回 future 时必须用值捕获。

server.route("/test4", QHttpServerRequest::Method::Post, this,
             [] (QHttpServerRequest request) {
                return QtConcurrent::run(pool, [request]() {
                    return QHttpServerResponse("text/plain"_ba, request.body());
                }
             });

如果slot 在返回 future 时通过引用捕获QHttpServerRequestQHttpServerResponder ,则会导致断言,并解释为何禁止。

并非所有平台都支持将QHttpServerResponder 移入传递给 QConcurrent::run 的可变 lambda 中,因此解决方法是将QHttpServerResponder 移入 std::shared_ptr 中并复制它。

server.route("/concurrent-multipart-back/<arg>",
             [](QString message, QHttpServerResponder &&responder) {
                return QtConcurrent::run(pool,
                    [=, r = std::make_shared<QHttpServerResponder>(std::move(responder))] {
                        QByteArray ba = message.toUtf8();
                        r->writeBeginChunked("text/plain"_ba);
                        for (ushort i = 1; i < 8; ++i) {
                            r->writeChunk(ba);
                        }
                        r->writeEndChunked(ba);
                    });
            });

另请参见 QHttpServerRouter::addRuleaddAfterRequestHandler

template <typename Rule = QHttpServerRouterRule, typename Functor> Rule *QHttpServer::route(const QString &pathPattern, Functor &&handler)

QHttpServer::route 的重载,为pathPatternQHttpServerRequest::Method::AnyKnown 创建规则。所有请求都会被转发到handler ,后者可以是函数指针、不可变 lambda 或其他任何带有 const 调用操作符的可复制可调用对象。该规则将一直有效,直到QHttpServer 被销毁。

这是一个重载函数。

template <typename Rule = QHttpServerRouterRule, typename Functor> Rule *QHttpServer::route(const QString &pathPattern, QHttpServerRequest::Methods method, Functor &&handler)

QHttpServer::route 的重载,为pathPatternmethod 创建规则。所有请求都会被转发到handler ,后者可以是函数指针、不可变 lambda 或其他任何带有 const 调用操作符的可复制可调用对象。该规则将一直有效,直到QHttpServer 被销毁。

这是一个重载函数。

template <typename Rule = QHttpServerRouterRule, typename Functor> Rule *QHttpServer::route(const QString &pathPattern, const QObject *context, Functor &&slot)

QHttpServer::route 的重载,为pathPattern 和方法QHttpServerRequest::Method::AnyKnown 创建一个规则。所有请求均转发至contextslot

这是一个重载函数。

QHttpServerRouter *QHttpServer::router()

返回指向路由器对象的指针。

const QHttpServerRouter *QHttpServer::router() const

返回指向常量路由器对象的指针。

template <typename Functor> void QHttpServer::setMissingHandler(const QObject *context, Functor &&slot)

为未处理的请求设置一个处理程序。

所有未处理的请求都将转发到contextslot

slot 必须实现签名void (*)(const QHttpServerRequest &, QHttpServerResponder &)slot 也可以是函数指针、不可变 lambda 或任何其他带有 const 调用操作符的可复制可调用对象。在这种情况下,context 将是一个上下文对象。处理程序将一直有效,直到上下文对象被销毁。

默认处理程序的回复状态为404 Not Found

另请参阅 clearMissingHandler

© 2026 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.