【Linux小项目---2】前端按钮和实现响应

文章目录

    • 上传图片:
    • 查看指定图片信息:
    • 查看所有图片信息:
    • 查看图片内容:
    • 删除指定图片:
    • MD5校验和自动生成时间:
    • 小BUG:


上传图片:

  • 按钮通过html实现
  • 通过httplib官方文档提供的方式获取filename
  • 进行参数合法化校验
  • 构造json格式的image,插入数据库
  • 将图片使用C++文件流的方式保存到本地磁盘
                Json::Value resp_json;
                Json::FastWriter fw;

                cout<<"上传图片"<<endl;

                auto size = req.files.size();
                bool ret = req.has_file("filename");

                if(!ret)
                {
                    resp_json["ok"] = false;
                    resp_json["reason"] = "没有该图片!";
                    resp.status = 400;
                    resp.set_content(fw.write(resp_json), "application/json");
                    return;
                }

                const auto& file = req.get_file_value("filename");
                // file.filename;
                // file.content_type;
                auto body = req.body.substr(file.offset, file.length);

                Json::Value image;

                string Time;
                GetNowTime(Time);

                image["image_name"] = file.filename;
                image["image_size"] = (int)file.length;
                image["upload_time"] = Time;
                image["md5"] = StringMD5(body);
                image["image_type"] = file.content_type;
                image["image_path"] = base_path + file.filename;

                //插入数据库
                it.Insert(image);

				...

                //保存文件到磁盘
                ofstream outfile;
                outfile.open(image["image_path"].asCString());

                outfile<<body;

                cout<<"保存成功"<<endl;

                //构造响应
                resp_json["ok"] = true;
                resp.set_content(fw.write(resp_json), "text/html");

【Linux小项目---2】前端按钮和实现响应_第1张图片
【Linux小项目---2】前端按钮和实现响应_第2张图片
【Linux小项目---2】前端按钮和实现响应_第3张图片
【Linux小项目---2】前端按钮和实现响应_第4张图片


查看指定图片信息:

  • 从请求获取图片ID
  • 从数据库查询信息
  • 返回响应
            //1.先获取到图片ID
            int image_id = std::stoi(req.matches[1]);

            //2.根据ID查询数据库
            Json::Value image;

            it.SelectOne(image_id, &image);
			
			...
			
			//3.查询结果返回给客户端
            resp_json["ok"]=true;
            resp.set_content(fw.write(image),"application/json");

在这里插入图片描述


查看所有图片信息:

  • 从数据库中查询信息
  • 返回响应
            //1.调用数据库接口来获取数据
            image_table it(mysql);
            Json::Value images;

            it.SelectAll(&images);

			...

			//2.构造响应结果返回客户端
            resp.set_content(fw.write(images),"application/json");

【Linux小项目---2】前端按钮和实现响应_第5张图片


查看图片内容:

  • 从请求中获取图片ID
  • 前往数据库查找文件路径
  • 将图片内容读取到缓冲区
  • 将缓冲区响应回去
  • Read函数中使用fread按字节读
            //1.先获取到图片ID
            int image_id = std::stoi(req.matches[1]);

            //2.找到数据库对应的目录
            Json::Value image;

            it.SelectOne(image_id,&image);
			
			...

			//3.根据路径找到文件内容,读取
            int t=stoi(image["image_size"].asString());

            string image_body;

            File::Read(image["image_path"].asString(),image_body,t);

【Linux小项目---2】前端按钮和实现响应_第6张图片


删除指定图片:

  • 从请求中获取图片ID
  • 从数据库中查询文件路径
  • 从数据库中删除
  • 从本地磁盘删除
  • 返回响应
	  // 1. 根据图片 id 去数据库中查到对应的目录
      int image_id = std::stoi(req.matches[1]);

      cout<<"删除ID为:"<<image_id<<"的图片"<<endl;

      // 2. 查找到对应文件的路径
      Json::Value image;

      bool ret = it.SelectOne(image_id, &image);

      if (!ret) 
      {
        cout<<"删除图片失败!"<<endl;

        resp_json["ok"] = false;
        resp_json["reason"] = "删除图片失败";
        resp.status = 404;
        resp.set_content(writer.write(resp_json), "application/json");
        return;
      }

      // 3. 数据库进行删除操作
      ret = it.Delete(image_id);

      if (!ret) 
      {
        cout<<"删除图片失败!"<<endl;
        resp_json["ok"] = false;
        resp_json["reason"] = "删除图片失败";
        resp.status = 404;
        resp.set_content(writer.write(resp_json), "application/json");
        return;
      }

      // 4. 删除磁盘上的文件
      unlink(image["image_path"].asCString());
      
      // 5. 构造响应
      resp_json["ok"] = true;
      resp.status = 200;
      resp.set_content(writer.write(resp_json), "application/json");

【Linux小项目---2】前端按钮和实现响应_第7张图片
【Linux小项目---2】前端按钮和实现响应_第8张图片
【Linux小项目---2】前端按钮和实现响应_第9张图片


MD5校验和自动生成时间:

时间代码来源于:https://blog.csdn.net/weixin_34237596/article/details/86038716

void GetNowTime(string& Time)
{
    //方法一:

    // time_t timer;//time_t就是long int 类型
    // struct tm *tblock;
    // timer = time(NULL);
    // tblock = localtime(&timer);

    // Time=asctime(tblock);

    //方法二:
    struct timeval tv;
    char mytime[20] = "";

    gettimeofday(&tv,NULL);
    strftime(mytime,sizeof(mytime),"%Y-%m-%d %T",localtime(&tv.tv_sec));

    Time=mytime;
}
std::string StringMD5(const std::string& str) 
{
    const int MD5LENTH = 16;
    unsigned char MD5result[MD5LENTH];

    // 调用 openssl 的函数计算 md5
    MD5((const unsigned char*)str.c_str(),str.size(),MD5result);

    // 转换成字符串的形式方便存储和观察
    char output[1024] = {0};
    int offset = 0;

    for (int i = 0; i < MD5LENTH; ++i) 
    {
        offset += sprintf(output + offset, "%x", MD5result[i]);
    }

    return std::string(output);
}

【Linux小项目---2】前端按钮和实现响应_第10张图片


小BUG:

  • 自增主键虽好,但是也有小问题
  • id自动增长,但是中途如果有删除图片,id不会更新
  • 比如123456,删除6,再插入,图片id为7
  • 构造插入语句时插入图片的id由null改为行号+1
		sprintf(sql, "select * from image_table");

		int ret = mysql_query(_mysql,sql);

		if(ret!=0)
		{
			cout<<mysql_error(_mysql)<<endl;
		 	cout<<"查询失败"<<endl;
		 	return false;
		}

    	MYSQL_RES* result = mysql_store_result(_mysql);

		int lineno=mysql_num_rows(result);
  • 数据库本来为12356(就是因为中间有删除)
  • 删除后变为123
  • 预期结果:插入图片id为4
    【Linux小项目---2】前端按钮和实现响应_第11张图片
  • 之前设置编码格式为utf8总报错,明明没有问题
  • 今天突然就好了
  • 我猜可能是VS Code中Remote SSH的BUG,只修改hpp不修改cpp,保存之后编译的不是新的代码
  • 哪怕在cpp删掉分号在加上,保存,就可以编译最新的代码

【Linux小项目---2】前端按钮和实现响应_第12张图片


你可能感兴趣的:(操作系统)