• MFC 发起 HTTP Post 请求 发送MES消息


    获取Token

    首先获取WebApi 的Token
    在这里插入图片描述
    执行请求Token函数
    在这里插入图片描述

    int CHttpClientJXJST::ExecuteRequest()
    {
    	//设置连接超时时间为20s
        m_pSession->SetOption(INTERNET_OPTION_CONNECT_TIMEOUT, 1000 * 20);
        m_pSession->SetOption(INTERNET_OPTION_CONNECT_BACKOFF, 1000); // 设置连接后退时间
        m_pSession->SetOption(INTERNET_OPTION_CONNECT_RETRIES, 3);    // 设置连接重试次数
    
        //通过网络会话对象创建一个 HTTP 连接对象,连接到 http://111.75.253.00 服务器,端口为8080
        //m_pConnection = m_pSession->GetHttpConnection(TEXT("111.75.253.00"), (INTERNET_PORT)8000);
    	m_pConnection = m_pSession->GetHttpConnection(TEXT(theApp.m_oHardParaEx.m_sMesHttp), (INTERNET_PORT)8000);
    
        // 使用该连接对象创建一个 HTTP 文件对象,用于在服务器上打开一个请求,使用 HTTP POST 方法,指定请求的 URL 为 "/api/token/getToken"
    	m_pFile = m_pConnection->OpenRequest(CHttpConnection::HTTP_VERB_POST, theApp.m_oHardParaEx.m_sMesURL,
                                              NULL, 1, NULL, TEXT("HTTP/1.1"), INTERNET_FLAG_RELOAD);
    
        // 设置需要提交的数据,包括请求头信息和 POST 数据
        //CString szHeaders = TEXT("Content-Type:application/json;charset=utf-8");
        //CString strFormData = TEXT("username=switchdevice&password=1234567");
    	CString szHeaders = TEXT("Content-Type: application/x-www-form-urlencoded\r\n");
    	m_pFile->AddRequestHeaders(szHeaders);
    
       // 设置表单数据
    	//CString strFormData = TEXT("username=switchdevice&password=1234567");
    	CString strFormData = TEXT("username=")+theApp.m_oHardParaEx.m_sMesUser+("&password=")+theApp.m_oHardParaEx.m_sMesPassWord;
    
    	try 
    	{
    			// 发送请求
    		m_pFile->SendRequest(NULL, 0, (LPVOID)(LPCTSTR)strFormData, strFormData.GetLength());
    
    			 // 如果请求成功,继续执行其他操作
    	} catch (CInternetException* pEx) {
    		// 处理异常
    		TCHAR szError[1024];
    		pEx->GetErrorMessage(szError, 1024);
    		// 在这里进行异常处理,例如输出错误信息或者进行其他适当的操作
    		AfxMessageBox(szError);
    		pEx->Delete(); // 删除异常对象
    	}
    
    
    		// 查询返回的状态码
        DWORD dwRet;
        m_pFile->QueryInfoStatusCode(dwRet);
    
    	
    	strFilePath = theApp.m_sRunPath + _T("\\sys\\response.JSON");
        if (dwRet != HTTP_STATUS_OK)
        {
    		msg =_T("");
            CString errText;
            errText.Format(_T("POST出错,错误码:%d"), dwRet);
            AfxMessageBox(errText);
        }
        else
        {
    		
            int len = m_pFile->GetLength();
    		char buf[2000];
    		int numread;
    		
    		CFile MesFile( strFilePath, CFile::modeCreate | CFile::modeWrite | CFile::typeBinary);
    
    		// 初始化 strFile 为空字符串
    		CString strFile;
    
    		// 循环读取数据
    		while ((numread = m_pFile->Read(buf, sizeof(buf) - 1)) > 0)
    		{
    			// 添加 '\0' 到 buf 数组中读取的最后一个字符的位置
    			buf[numread] = '\0';
    
    			// 追加数据到 strFile
    			strFile += buf;
    
    			// 写入数据到文件
    			MesFile.Write(buf, numread);
    		}
    		MesFile.Close();
    		//读取JSON文件
    		GetMsg(strFilePath);
        }	
    
        return SUCCESS;
    }
    

    将获取的Token写入JSON文件

    CString CHttpClientJXJST::GetMsg(CString filePath)
    {
    	
    	try {
            // 创建一个 CFile 对象
            CFile JsonFile;
            // 打开文件
            if (!JsonFile.Open(filePath, CFile::modeRead))
    		{
                AfxMessageBox(_T("Failed to open JSON file."));
                return 0;
            }
    
            // 获取文件大小
            ULONGLONG fileSize = JsonFile.GetLength();
            // 创建一个缓冲区来存储文件内容
            char* buffer = new char[fileSize + 1];
            // 读取文件内容到缓冲区
            JsonFile.Read(buffer, (UINT)fileSize);
            // 添加字符串结尾标志
            buffer[fileSize] = '\0';
            // 关闭文件
            JsonFile.Close();
    
            // 使用 RapidJSON 解析 JSON 字符串
            rapidjson::Document document;
            document.Parse(buffer);
    
            // 检查解析是否成功
            if (document.HasParseError()) 
    		{
                AfxMessageBox(_T("JSON parse error: ") + CString(rapidjson::GetParseError_En(document.GetParseError())));
                delete[] buffer;
                return 0;
            }
    
            // 检查是否存在 msg 和 timestamp 字段
            if (document.HasMember("msg") && document.HasMember("timestamp")) 
    		{
                // 获取 msg 和 timestamp 值
                msg = CString(document["msg"].GetString());
                timestamp = document["timestamp"].GetUint64();
    
    
                // 释放缓冲区内存
                delete[] buffer;
            } 
    		else 
    		{
                AfxMessageBox(_T("JSON does not contain msg and timestamp fields."));
                delete[] buffer;
                return 0;
            }
        } catch (CFileException* pEx)
    	{
            // 处理文件操作异常
            TCHAR szCause[255];
            pEx->GetErrorMessage(szCause, 255);
            AfxMessageBox(_T("File operation error: ") + CString(szCause));
            pEx->Delete();
    		return 0;
            
        }
    	return msg;
    
    }
    

    在这里插入图片描述

    将测试参数发送到http

    首先将测试参数写入到TestData.JSON文件

    void CHttpClientJXJST::WirteJsonData(CString m_snCode,CString m_moBill,CString m_result,CXMLData* pData)
    {
    	strFilePath = theApp.m_sRunPath + _T("\\sys\\TestData.JSON");
        CFileException fileException;
        CFile JSONDataFile;
    
        // 尝试打开文件
        if (!JSONDataFile.Open(strFilePath, CFile::modeCreate | CFile::modeWrite | CFile::typeBinary, &fileException))
        {
            AfxMessageBox(_T("打开TestData.JSON文件失败"));
            return;
        }
    
    	// 创建一个空的 JSON 文档
    	Document document;
    	document.SetObject();
    
    	// 将 deviceCode 字段添加到文档中
    	Value deviceCode(StringToConstChar(CStringToString(theApp.m_oHardParaEx.m_sMesDeviceCode)), document.GetAllocator());
    	// 将 processCode 字段添加到文档中
    	Value processCode(StringToConstChar(CStringToString(theApp.m_oHardParaEx.m_sMesGX)), document.GetAllocator());
    	// 将 snCode 字段添加到文档中
    	Value snCode(StringToConstChar(CStringToString(m_snCode)), document.GetAllocator());
    	//将  jobNo 字段添加到文档中
    	Value jobNo(StringToConstChar(CStringToString(theApp.m_oHardParaEx.m_sMesJobNo)), document.GetAllocator());
    
    	// 获取当前时间
    	CTime currentTime = CTime::GetCurrentTime();
    	// 格式化日期时间为字符串
    	CString m_sDateTime = currentTime.Format(_T("%Y-%m-%d %H:%M:%S"));
    	//时间
    	Value date(StringToConstChar(CStringToString(m_sDateTime)), document.GetAllocator());
    	//姓名
    	Value user(StringToConstChar(CStringToString(theApp.m_oHardParaEx.m_sMesTestName)), document.GetAllocator());
    	//生产单号
    	Value moBill(StringToConstChar(CStringToString(m_moBill)), document.GetAllocator());
    
    	//返回结果
    	Value result(StringToConstChar(CStringToString(m_result)), document.GetAllocator());
    
    	// 设置 JSON 字段
    	document.AddMember("deviceCode", deviceCode, document.GetAllocator());		// 设备编号
    	document.AddMember("processCode", processCode, document.GetAllocator());	 // 工序编号
    	document.AddMember("snCode", snCode, document.GetAllocator());				// 检测条码
        document.AddMember("jobNo", jobNo, document.GetAllocator());				// 员工工号
        document.AddMember("date", date, document.GetAllocator());					// 时间
        document.AddMember("user", user, document.GetAllocator());					// 检测人名称
        document.AddMember("moBill", moBill, document.GetAllocator());				// 生产订单号
        document.AddMember("result", result, document.GetAllocator());				// 返回结果
    
    
    	 // 创建一个数组并添加到 JSON 文档中
    	Value dataArray(kArrayType);
    	
    	int n = pData->m_oXMLItems.GetSize( );
    	int i = 0;
    
    
    	for(int i=0;i<n;i++)
    	{
    		
    		Value test(kObjectType);
    		// 获取测试项目的关键字和值
    		
    		if(pData->m_oXMLItems.GetAt(i)!=NULL)
    		{
    
    			CString skey = pData->m_oXMLItems[i]->sKey;			//检测项目编码
    			CString stestName =pData->m_oXMLItems[i]->sTestName;//检测项目名称
    			CString sminVal=pData->m_oXMLItems[i]->sMinVal;		//下限值
    			CString smaxVal=pData->m_oXMLItems[i]->sMaxVal;		//上限值
    			CString stestValue =pData->m_oXMLItems[i]->sTestVal;//检测项目值
    			CString sresultInfo =pData->m_oXMLItems[i]->sResultInfo;//检测结果
    			CString sbadCode =pData->m_oXMLItems[i]->sBadCode;
    
    			//检测项目编码
    			Value testCode(StringToConstChar(CStringToString(skey)), document.GetAllocator());
    			Value testName(StringToConstChar(CStringToString(stestName)), document.GetAllocator());
    			Value minVal(StringToConstChar(CStringToString(sminVal)), document.GetAllocator());
    			Value maxVal(StringToConstChar(CStringToString(smaxVal)), document.GetAllocator());
    			Value testValue(StringToConstChar(CStringToString(stestValue)), document.GetAllocator());
    			Value resultInfo(StringToConstChar(CStringToString(sresultInfo)), document.GetAllocator());
    			Value badCode(StringToConstChar(CStringToString(sbadCode)), document.GetAllocator());
    
    			test.AddMember("testCode", testCode, document.GetAllocator());
    			test.AddMember("testName",testName, document.GetAllocator());
    			test.AddMember("minVal", minVal, document.GetAllocator());
    			test.AddMember("maxVal", maxVal, document.GetAllocator());
    			test.AddMember("testVal",testValue, document.GetAllocator());
    			test.AddMember("resultInfo", resultInfo, document.GetAllocator());
    			test.AddMember("badCode", badCode, document.GetAllocator());
    
    			dataArray.PushBack(test, document.GetAllocator());
    		}
    
    		
    	}
        document.AddMember("data", dataArray, document.GetAllocator());
        // 将 JSON 文档写入文件
        StringBuffer buffer;
        PrettyWriter<StringBuffer> writer(buffer);
        document.Accept(writer);
        CStringA jsonStr(buffer.GetString());
        // 将字符串写入文件
        try
        {
            JSONDataFile.Write(jsonStr, jsonStr.GetLength());
            JSONDataFile.Close();
        }
        catch (CFileException* e)
        {
            // 处理文件写入错误
            TCHAR szError[1024];
            e->GetErrorMessage(szError, 1024);
            TRACE(_T("Failed to write JSON file: %s\n"), szError);
            e->Delete();
        }
    }
    

    生成的JSON 数据大致如下
    在这里插入图片描述

    rapidjson 库需要将CString 进行类型转换才能使用,将CString 转换为const char*

    std::string CHttpClientJXJST::CStringToString(const CString& cstr)
    {
    	  // 使用 CStringA 构造函数将 CString 转换为 ANSI 字符串
        CStringA strA(cstr);
        // 使用 ANSI 字符串构造 std::string
        return std::string(strA.GetString());
    }
    
    
    const char* CHttpClientJXJST::StringToConstChar(const std::string& str)
    {
    	 return str.c_str();
    }
    

    发送JSON 参数到http中,并且获取返回结果写入TestFinish.JSON文件

    void CHttpClientJXJST::TestFinishRequest()
    {
        // 使用该连接对象创建一个 HTTP 文件对象,用于在服务器上打开一个请求,使用 HTTP POST 方法,指定请求的 URL 为 "/api/mom/device/saveData"
    	m_pFile = m_pConnection->OpenRequest(CHttpConnection::HTTP_VERB_POST, theApp.m_oHardParaEx.m_sMesURL2,
                                              NULL, 1, NULL, TEXT("HTTP/1.1"), INTERNET_FLAG_RELOAD);
    
    	 // 设置请求头信息
    	CString szHeaders = TEXT("Content-Type: application/json;charset=utf-8\r\n");
    	szHeaders += TEXT("Authorization: ") + msg + TEXT("\r\n"); // 使用 msg 变量作为 Authorization 头的值
    	m_pFile->AddRequestHeaders(szHeaders);
    	
    
    	//读取JSON文件            //单独创建一个JSON文件保存数据
    	strFilePath = theApp.m_sRunPath + _T("\\sys\\TestData.JSON");
    
    
    	CStringA strJsonData =ReadJSONFile(strFilePath);
    	
    
    	  // 设置请求体数据为 JSON 格式
        DWORD dwDataLen = strJsonData.GetLength();
    
    
    	// 设置请求体数据为 JSON 格式
    	//DWORD dwDataLen = strJsonData.GetLength() * sizeof(TCHAR);
    
    	// 发送请求
    	//m_pFile->SendRequest(NULL, 0, (LPVOID)(LPCTSTR)strJsonData, dwDataLen);
    
    	try 
    	{
    		// 发送请求
    		m_pFile->SendRequest(NULL, 0, (LPVOID)(LPSTR)strJsonData.GetBuffer(), dwDataLen);
    		// 如果请求成功,继续执行其他操作
    	} 
    	catch (CInternetException* pEx) 
    	{
    		// 处理异常
    		TCHAR szError[1024];
    		pEx->GetErrorMessage(szError, 1024);
    		// 在这里进行异常处理,例如输出错误信息或者进行其他适当的操作
    		AfxMessageBox(szError);
    		pEx->Delete(); // 删除异常对象
    	}
    
    
    	// 查询返回的状态码
    	DWORD dwRet;
    	m_pFile->QueryInfoStatusCode(dwRet);
    
    
    	strFilePath = theApp.m_sRunPath + _T("\\sys\\TestFinish.JSON");
        if (dwRet != HTTP_STATUS_OK)
        {
            CString errText;
            errText.Format(_T("POST出错,错误码:%d"), dwRet);
            AfxMessageBox(errText);
        }
        else
        {
    		
            int len = m_pFile->GetLength();
    		char buf[2000];
    		int numread;
    		
    		CFile MesFile( strFilePath, CFile::modeCreate | CFile::modeWrite | CFile::typeBinary);
    
    		// 初始化 strFile 为空字符串
    		CString strFile;
    
    		// 循环读取数据
    		while ((numread = m_pFile->Read(buf, sizeof(buf) - 1)) > 0)
    		{
    			// 添加 '\0' 到 buf 数组中读取的最后一个字符的位置
    			buf[numread] = '\0';
    
    			// 追加数据到 strFile
    			strFile += buf;
    			// 写入数据到文件
    			MesFile.Write(buf, numread);
    		}
    		MesFile.Close();
        }
    }
    

    读取TestFinish.JSON文件判断返回结果是否正确

    CString CHttpClientJXJST::GetFinishResult(CString filePath)
    {
    	m_sResult=_T("");
    	
    	try {
            // 创建一个 CFile 对象
            CFile JsonFile;
            // 打开文件
            if (!JsonFile.Open(filePath, CFile::modeRead))
    		{
                AfxMessageBox(_T("Failed to open JSON file."));
                return 0;
            }
    
            // 获取文件大小
            ULONGLONG fileSize = JsonFile.GetLength();
            // 创建一个缓冲区来存储文件内容
            char* buffer = new char[fileSize + 1];
            // 读取文件内容到缓冲区
            JsonFile.Read(buffer, (UINT)fileSize);
            // 添加字符串结尾标志
            buffer[fileSize] = '\0';
            // 关闭文件
            JsonFile.Close();
    
            // 使用 RapidJSON 解析 JSON 字符串
            rapidjson::Document document;
            document.Parse(buffer);
    
            // 检查解析是否成功
            if (document.HasParseError()) 
    		{
                AfxMessageBox(_T("JSON parse error: ") + CString(rapidjson::GetParseError_En(document.GetParseError())));
                delete[] buffer;
                return 0;
            }
            // 检查是否存在 msg 
            if (document.HasMember("msg")) 
    		{
    			// 获取 msg 字段的值
    			const rapidjson::Value& msgValue = document["msg"];
    			m_sResult = CStringA(document["msg"].GetString());
    			if (msgValue.IsString()) 
    			{
    			
    				// 获取字符串的长度
    				size_t length = msgValue.GetStringLength();
    				 // 获取字符串的首指针
    				const char* msgString = msgValue.GetString();
    				 // 计算需要的缓冲区大小
    				int bufferSize = MultiByteToWideChar(CP_UTF8, 0, msgString, -1, nullptr, 0);
    				// 分配缓冲区
    				wchar_t* utf16Buffer = new wchar_t[bufferSize];
    				 // 进行编码转换
    				MultiByteToWideChar(CP_UTF8, 0, msgString, -1, utf16Buffer, bufferSize);
    				 // 将 wchar_t* 转换为 CString
    				 m_sResult = CString(utf16Buffer);
    				   // 释放内存
    				delete[] utf16Buffer;
    			
    			}
    			else 
    			{
    				// 如果值不是字符串类型,进行相应的错误处理
    				AfxMessageBox(_T("Value of 'msg' is not a string."));
    			}
    
    		
                // 释放缓冲区内存
                delete[] buffer;
            } 
    		else 
    		{
                AfxMessageBox(_T("JSON does not contain msg and timestamp fields."));
                delete[] buffer;
                return 0;
            }
        } catch (CFileException* pEx)
    	{
            // 处理文件操作异常
            TCHAR szCause[255];
            pEx->GetErrorMessage(szCause, 255);
            AfxMessageBox(_T("File operation error: ") + CString(szCause));
            pEx->Delete();
    		return 0;
            
        }
    	return m_sResult;
    
    }
    

    在这里插入图片描述在这里插入图片描述

    Mes发送失败的错误日志

    void CHttpClientJXJST::OutputLog(CString msg)
    {
    	try{
    		strFilePath = theApp.m_sRunPath + _T("\\sys\\log.txt");
    		//设置文件的打开参数
    		CStdioFile outFile(strFilePath, CFile::modeNoTruncate | CFile::modeCreate | CFile::modeWrite | CFile::typeText);
    		CString msLine;
    		CTime CurTime = CTime::GetCurrentTime();
    		msLine = CurTime.Format("[%Y-%B-%d %A, %H:%M:%S] ") + msg;
    		msLine += "\n";
     
    		//在文件末尾插入新纪录
    		outFile.SeekToEnd();
    		outFile.WriteString( msLine );
    		outFile.Close();
    	}
    	catch(CFileException *fx)
    	{
    		fx->Delete();
    	}
    }
    

    在这里插入图片描述

    类函数

    #pragma once
    #include "HttpClient.h"
    #include   // 包含 MFC 核心头文件
    #include  // 包含 MFC Windows 类的头文件
    #include "rapidjson/document.h"
    #include "rapidjson/error/en.h"
    #include "rapidjson/stringbuffer.h"
    #include "rapidjson/writer.h"
    #include "rapidjson/istreamwrapper.h"
    #include "rapidjson/prettywriter.h"
    #include "rapidjson/filereadstream.h"
    
    #include 
    
    #include  // 包含 CString 头文件
    #include 
    using namespace rapidjson;
    using namespace std;
    
    
    
    class CXMLData;
    class CHttpClientJXJST :
    	public CHttpClient
    {
    public:
    	CHttpClientJXJST(void);
    	~CHttpClientJXJST(void);
    
    public:
    	int ExecuteRequest(); //开启程序请求http 
    	//测试完成请求http
    	void TestFinishRequest();//测试完成请求http 返回结果
    	CString GetFinishResult(CString filePath);//读取JOSN 文件 获取msg->token
    	CString GetMsg(CString filePath);//读取JOSN 文件 获取msg->token
    	//WirteJsonData 文件
    	//1.检测条码 snCode
    	//2.生产单号 moBill
    	//3.总判定结果 result
    	void WirteJsonData(CString m_snCode,CString m_moBill,CString m_result,CXMLData* pData);//写入JSON文件数据
    	CStringA ReadJSONFile(const CString& filePath);
    	std::string CStringToString(const CString& cstr);//CString 转换为std::string
    	const char* StringToConstChar(const std::string& str);//std::string 转换为const char*
    	void OutputLog(CString msg);//错误日志
    public:
    	CString msg;//Token
    	ULONGLONG timestamp;//时间戳
    	//获取文件路径
    	CString strFilePath;//JSON文件路径
    	CString m_sResult;//读取的返回结果
    };
    

    父类函数

    在这里插入图片描述

  • 相关阅读:
    高维前缀和和子集dp(状压dp的一种)
    NSS [鹤城杯 2021]Middle magic
    opencv从入门到精通 哦吼01
    大二C#实现酒店管理系统(C端展示、前台操作、登记入住、入住管理、职位管理、公告系统等)
    【正则表达式】
    Ubuntu1804 安装后无法使用root登录解决方法
    【剑指 Offer 21. 调整数组顺序使奇数位于偶数前面】
    Python | 武理刷题2
    SpringCloudAlibaba_2
    为什么我的MySQL会抖一下?
  • 原文地址:https://blog.csdn.net/weixin_45672157/article/details/139256796