用Qt实现基于网络请求的用户登录(二)
来源:互联网 发布:数据脱敏的主要方法 编辑:程序博客网 时间:2024/05/24 03:43
上一篇文章介绍了在Qt中与网络请求相关的类,以及在Qt中生成和解析Json。这一篇文章,将基于实例展示如何应用这些类实现网络请求,以及Json的生成和解析体现在哪里。
先回顾一下需要解决的问题:
问题:用户联网登录
1.提供登录界面(客户端),输入用户名和密码;
2.将用户名和密码发送给服务器端,并进行相关查询,如果用户合法,返回用户信息;
3.对返回的用户信息进行解析。- 假设:
已经有了服务器和存储着用户名和密码数据库。服务器当接收到客服端的请求的时候,先在数据库中进行查询操作,然后返回用户信息。
其中,客户端与服务器进行通信用到的接口信息如下所示:
【url】 /xxx1/xxx2/
【请求方式】 post
【请求参数说明】
{“username”:6到15个字符, 数字和字母的组合,非空,唯一
“passwd”:6到20个字符,非空}
【样例说明】
{“passwd”:”123456”,”username”:”haha”}
【返回信息】
{“code”:84,”message”:”登陆失败,验证码输入错误”}
{“code”:4,”message”:”账号异常”}
{“code”:5,”message”:”密码错误”}
{“code”:6,”message”:”用户名不存在”}
一、客户端界面
二、实现步骤
1.生成QNetworkRequest对象,设置请求头、请求所用API所需实参、url等信息;
在这里根据请求方式是post还是get,请求所用API所需实参的设置分两种情况:
①manager.post(request,data)
其中data为形如
"data={"username": "haha","passwd": 123456}"
这样的QByteArray。
②manager.get(request)
参数直接在设置request的URL的时候设置(post要另设置URL):
request.setUrl(QUrl("http://xxx1/xxx2?username="+username+"&passwd="+passwd));
2.准备解析处理QNetworkReply的slot;
3.生成QNetworkAccessManager,发送request,并将返回来的reply委托给该slot处理(实现上就是一条connect语句)
三、代码实现
1.在.pro中添加netwotk模块
因为与网络请求相关的那些类在这个模块里面
QT += core gui //原来存在的QT += network //添加的
2.login.h文件
#ifndef LOGIN_H#define LOGIN_H#include <QMainWindow>#include <QtNetwork/QNetworkAccessManager>#include <QtNetwork/QNetworkRequest>#include <QtNetwork/QNetworkReply>namespace Ui {class Login;}class Login : public QMainWindow{ Q_OBJECTpublic: explicit Login(QWidget *parent = 0); ~Login();private slots: void finishRequest(QNetworkReply*); //处理reply的slot void on_OKButton_clicked();private: Ui::Login *ui; QNetworkAccessManager manager; //manager 相关注意点见后文 QNetworkRequest request; //request };#endif // LOGIN_H
3.login.cpp
#include "login.h"#include "ui_login.h"#include <QMessageBox>#include <QByteArray>#include <QString>#include <QJsonDocument>#include <QJsonArray>#include <QJsonParseError>#include <QJsonValue>#include <QJsonObject>#include <QDebug>#include <iostream>Login::Login(QWidget *parent) : QMainWindow(parent), ui(new Ui::Login){ ui->setupUi(this);}Login::~Login(){ delete ui;}void Login::on_OKButton_clicked(){ //获取用户名、密码 QString username = ui->usrLineEdit->text(); QString password = ui->pwdLineEdit->text(); if(username.isEmpty() || password.isEmpty()) { QMessageBox::warning(this,"Warning","Username or password is empty!",QMessageBox::Yes); ui->usrLineEdit->clear(); ui->pwdLineEdit->clear(); } else{ //通过QJsonObject得到post需要的参数data, data形式为: "data={"username": "haha","passwd": 123456}" QJsonObject json; json.insert("username",username); json.insert("passwd",password); QJsonDocument document; document.setObject(json); QByteArray byte_array = document.toJson(QJsonDocument::Compact); QByteArray data; data.append("data="+byte_array); //设置request request.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded"); //上面语句固定这么写,要不然会报错“contest—type is missing” request.setRawHeader("XXX3", "XXX4"); request.setUrl(QUrl("http://xxx1/xxx2/")); //"http:"不要少 //manager发送请求,并接收reply,委托给slot处理 manager.post(request,data); connect(&manager,SIGNAL(finished(QNetworkReply*)),this,SLOT(finishRequest(QNetworkReply*))); }}void Login::finishRequest(QNetworkReply *reply){ if (reply->error()){ qDebug()<<"Error!"<<endl; }else{ //解析reply中携带的Json QByteArray byte_array = reply->readAll(); //Json ducument QJsonParseError json_error; QJsonDocument parse_document = QJsonDocument::fromJson(byte_array, &json_error); if(json_error.error == QJsonParseError::NoError) { if(parse_document.isObject()) { QJsonObject obj = parse_document.object(); if(obj.contains("code")) { QJsonValue code_value = obj.take("code"); int code_value_int = code_value.toInt(); if(code_value_int == 3) { QJsonValue message_value = obj.take("message"); qDebug()<<message_value<<endl; //输出:QJsonValue(string, "登录成功") } else { QJsonValue message_value = obj.take("message"); qDebug()<< message_value<<endl; QString error_message = message_value.toString(); QMessageBox::warning(this,"Error",error_message,QMessageBox::Yes); ui->usrLineEdit->clear(); ui->pwdLineEdit->clear(); } } } } } reply->deleteLater();}
四、实现时遇到的问题
1.试图直接生成Json document
post(request,data)请求中所用到的data为形如
"data={"username": "haha","passwd": 123456}"
的Json document,由于是一QByteArray的形式保存的,所以就想着能不能直接生成这样的QByteArray,从而绕过QJsonObject、 QJsonDocument, 实验结果是不可以。
//想通过QByteArray直接生成Json document,结果是不可以 QByteArray data; data.append("username="+username); data.append("passwd="+password);
2.将manager 和 request设为了全局变量
在这个例子中,只有一次网络请求,因此看不出这样做有什么问题。但是,当程序中有好几个网络请求的时候,这些网络请求共用一套manager和request,就会出现问题了。因为connect语句,只要manager接收到reply,就会触发所有connect语句,所有的解析Json的slot都有可能被委托到。这样就会出现,为什么我发出网络请求的是第二部分,却会是第一部分的slot有所反应= =
如果一开始使用的是全局变量,简单地将用到全局变量manager 和 request的地方改为局部变量
QNetworkAccessManager manager1; QNetworkRequest request1;
出现的结果是,根本就没有网络请求成功的迹象。应该使用指针:
QNetworkAccessManager *manager1 = new QNetworkAccessManager(); QNetworkRequest *request1= new QNetworkRequest();
原因参看:http://bbs.csdn.net/topics/391077810
但如果并不是由全局变量改为局部变量,采用第一种方式好像不会有什么问题。
参考资料:
网络请求基础相关:
Qt中网络请求相关类相关:
Qt实现网络数据传输: http://blog.sina.com.cn/s/blog_a6fb6cc90101fg0i.html
Post与get的区别: http://www.cnblogs.com/findumars/p/5574299.html
Qt网络编程之实例一GET方式: http://blog.csdn.net/chenlong12580/article/details/7392766
解决finished信号无法触发槽函数是看到的:
QNetworkAccessManager的finished信号无法触发槽函数: http://bbs.csdn.net/topics/391077810
QNetworkAccessManager : https://tieba.baidu.com/p/4089426961
Json相关:
Qt之JSON生成与解析: http://blog.sina.com.cn/s/blog_a6fb6cc90101gnxm.html
Json教程:http://www.w3school.com.cn/json/index.asp
http://www.w3school.com.cn/json/json_syntax.asp
- 用Qt实现基于网络请求的用户登录(二)
- 用Qt实现基于网络请求的用户登录(一)
- 【Qt编程】基于Qt的词典开发系列<八>--用户登录及API调用的实现
- 网络编程学习笔记二(实现一个基于简单TCP的用户注册程序)
- Java 实现基于UDP的用户登录
- 基于Qt的SocketIO客户端实现 【二】向服务器发送请求
- JFinal学习笔记(二) 实现简单的用户登录
- QT实现用户登录功能
- 基于QT的多线程视频监控的实现(二)
- Qt+Caffe+OpenCV——【一个基于VGG网络的人脸识别考勤系统】(二)创建一个登录界面和主窗口
- 用php实现用户的登录并且有邮箱的验证(二)
- Qt(二)--- 使用Qt完成QQ登录界面的输入文本框的实现
- 基于Qt实现的163音乐登录界面
- Linux下基于EPOLL 模型,实现用户登录,客户端采用QT
- Android开发之网络请求通信专题(二):基于HttpClient的文件上传下载
- 基于ionic2的跨平台项目(二)网络请求及使用实体类
- 实现登录:很好用的Android/Java网络请求http第三方开源类库
- Android实战简易教程-第二十三枪(基于Baas的用户注册和登录模块实现!)
- 数据结构---多项式的乘积与和(PTA)
- vivado xilinx 网盘资料
- Linux IPC 2之管道
- 我理解的Handler,messageQueue,Looper,Messager,HandlerThread.
- Go Get安装一些第三方库-网络问题
- 用Qt实现基于网络请求的用户登录(二)
- 大数据Sqoop_09
- 0x5f3759df的数学原理 ----一种快速开方根求倒原理
- JS阻止事件冒泡兼容各浏览器
- 分布式系统的高效运维要点
- 截取视频图片
- poj 1236 Network of Schools 强连通分量
- POJ3259 判断是否存在负权环
- CCF-20161201-中间数(100分)