Content Table

SpringMVC 获取 Request 和 Response

SpringMVC 中在任意地方取得 HttpServletRequestHttpServletResponse

  1. 在 web.xml 中注册 RequestContextListener (SpringMVC 4 不需要这一步)

    1
    2
    3
    4
    5
    <listener>  
    <listener-class>
    org.springframework.web.context.request.RequestContextListener
    </listener-class>
    </listener>
  2. 获取 HttpServletRequestHttpServletResponse

    1
    2
    3
    4
    5
    6
    public static String testRequestAndResponse() {
    HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
    HttpServletResponse response = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getResponse();

    return request.getParameter("name");
    }

升级 Xcode8 后 Qt 出错

错误提示:

Project ERROR: Xcode not set up properly. You may need to confirm the license agreement by running /usr/bin/xcodebuild.

解决办法:

  1. 打开 Qt_install_folder/5.7/clang_64/mkspecs/features/mac/default_pre.prf

  2. 修改

    1
    isEmpty($$list($$system("/usr/bin/xcrun -find xcrun 2>/dev/null")))

    1
    isEmpty($$list($$system("/usr/bin/xcrun -find xcodebuild 2>/dev/null")))

具体请看 http://stackoverflow.com/questions/33728905/qt-creator-project-error-xcode-not-set-up-properly-you-may-need-to-confirm-t

Qt 自定义日志工具

C++ 中比较不错的日志工具有 log4cxxlog4qt 等,但是它们都不能和 qDebug(), qInfo() 等有机的结合在一起,所以在 Qt 中使用总觉得不够舒服,感谢 Qt 提供了 qInstallMessageHandler() 这个函数,使用这个函数可以安装自定义的日志输出处理函数,把日志输出到文件,控制台等,具体的使用可以查看 Qt 的帮助文档。

Qt 访问网络的 HttpClient

Qt 使用 QNetworkAccessManager 访问 HTTP 服务,这里对其进行了简单的封装,使用流行的 Fluent 风格 API,简化 GET、POST、PUT、DELETE、上传、下载等操作。

在执行请求前设置需要的参数和回调函数:

  • 调用 header() 设置请求头

  • 调用 param() 设置参数,使用 Form 表单的方式提交请求,GET 请求的 query parameters 也可以用它设置

  • 调用 json() 设置 JSON 字符串的 request body,Content-Type 为 application/json

    当然也可以不是 JSON 格式,因使用 request body 的情况多数是使用 JSON 格式传递复杂对象,故命名为 json()

  • 调用 success() 注册请求成功的回调函数

  • 调用 fail() 注册请求失败的回调函数

  • 调用 complete() 注册请求结束的回调函数

然后根据请求的类型调用 get(), post(), put(), remove(), download(), upload() 执行 HTTP 请求。

success(), fail(), complete() 的回调函数是可选的,根据需要注册对应的回调函数,也可以一个都不注册

例如使用 HttpClient 执行 GET 请求的代码可以简化为:

1
2
3
HttpClient("http://localhost:8080/api/rest").success([](const QString &response) {
qDebug().noquote() << response;
}).get();

Qt 访问网络

Qt 中访问网络使用 QNetworkAccessManager,它的 API 是异步,这样在访问网络的时候不需要启动一个线程,在线程里执行请求的代码。

需要注意一点的是,请求响应的对象 QNetworkReply 需要我们自己手动的删除,一般都会在 QNetworkAccessManager::finished 信号的曹函数里使用 reply->deleteLater() 删除,不要直接 delete reply

本文的最终结果为实现调用一个函数就能访问网络:

1
2
3
4
5
QNetworkAccessManager *manager = new QNetworkAccessManager();

NetworkUtil::get(manager, "http://www.baidu.com", [](const QString &response) {
qDebug() << response;
});

Qt 创建圆角、无边框、有阴影、可拖动的窗口

程序窗口的边框,标题栏等是系统管理的,Qt 不能对其进行定制,为了实现定制的边框、标题栏、关闭按钮等,需要把系统默认的边框、标题栏去掉,然后使用 Widget 来模拟它们。这里介绍使用 QSS + QGraphicsDropShadowEffect 来创建圆角、无边框、有阴影、可拖动的窗口。

核心技术要点:

  • 启用 QSS: setAttribute(Qt::WA_StyledBackground, true)

    我们继承 QWidget 实现的 Widget 默认是不启用 QSS 的,为了启用 QSS,需要调用 setAttribute(Qt::WA_StyledBackground, true)

  • 使用 border-radius 创建圆角效果

    顶级窗口有些 QSS 不生效,例如 border-radius,所以把要显示圆角的 Widget 上放在另一个顶级 Widget 中,变为非顶级窗口

  • 顶级窗口需要去掉边框,背景设置为透明

    • 去掉边框: setWindowFlags(Qt::FramelessWindowHint);
    • 背景透明: setAttribute(Qt::WA_TranslucentBackground);
  • 使用鼠标事件实现拖动

  • 使用 QGraphicsDropShadowEffect 创建阴影

    很遗憾,QSS 不支持阴影