文章目录
- 获取Token
- 将获取的Token写入JSON文件
- 将测试参数发送到http
- 首先将测试参数写入到TestData.JSON文件
- rapidjson 库需要将CString 进行类型转换才能使用,将CString 转换为const char*
- 发送JSON 参数到http中,并且获取返回结果写入TestFinish.JSON文件
- 读取TestFinish.JSON文件判断返回结果是否正确
- 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 <afx.h> // 包含 MFC 核心头文件
#include <afxwin.h> // 包含 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 <iostream>
#include <atlstr.h> // 包含 CString 头文件
#include <string>
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;//读取的返回结果
};