STM32玩转物联网实战篇:3.1.ESP8266 WIFI模块WEBClient通信示例详解GET、POST(心知天气、Onenet)

本文主要是介绍STM32玩转物联网实战篇:3.1.ESP8266 WIFI模块WEBClient通信示例详解GET、POST(心知天气、Onenet),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

1、准备开发板

开发板功能区分布图

在这里插入图片描述

开发板俯视图

在这里插入图片描述

2、HTTP协议介绍

HTTP协议简介

    HTTP(HyperText Transfer Protocol)协议,即超文本传输协议,是一种用于分布式、协作式和超媒体信息系统的应用层协议。HTTP 协议是基于 TCP/IP 协议的网络应用层协议。
    HTTP是一个客户端终端(用户)和服务器端(网站)请求和应答的标准(TCP)。通过使用网页浏览器、网络爬虫或者其它的工具,客户端发起一个HTTP请求到服务器上指定端口(默认端口为80)。服务器接收到请求之后,通过接收到的信息判断响应方式,并且给予客户端相应的响应,完成整个 HTTP 数据交互流程。

HTTP 工作原理

HTTP 请求/响应的步骤
1. 客户端连接到Web服务器一个HTTP客户端,通常是浏览器,与Web服务器的HTTP端口(默认为80)建立一个TCP套接字连接。
2. 发送HTTP请求通过TCP套接字,客户端向Web服务器发送一个文本的请求报文,一个请求报文由请求行、请求头部、空行和数据包4部分组成。
3. 服务器接受请求并返回HTTP响应Web服务器解析请求,定位请求资源。服务器将资源复本写到TCP套接字,由客户端读取。一个响应由状态行、响应头部、空行和响应数据4部分组成。
4. 释放连接TCP连接若connection 模式为close,则服务器主动关闭TCP连接,客户端被动关闭连接,释放TCP连接;若connection 模式为keepalive,则该连接会保持一段时间,在该时间内可以继续接收请求;
5. 客户端浏览器解析HTML内容客户端浏览器首先解析状态行,查看表明请求是否成功的状态代码。然后解析每一个响应头,响应头告知以下为若干字节的HTML文档和文档的字符集。客户端浏览器读取响应数据HTML,根据HTML的语法对其进行格式化,并在浏览器窗口中显示。

HTTP协议请求头Request Headers

客户端发送一个HTTP请求到服务器的请求头主要包括:请求行、请求头部、空行、数据包
如下图是一个 POST 请求的信息:
在这里插入图片描述

HTTP 协议响应信息 Response

在这里插入图片描述

HTTP 协议状态码

状态代码类别原因短语
1xxInfomational(信息性状态码)接收的请求正在处理
2xxSuccess(成功状态码)请求正常处理完毕
3xxRedirection(重定向状态码)需要进行附加操作以完成请求
4xxClient Error(客户端错误状态码)服务器无法处理请求
5xxServer Error(服务器错误状态码)服务器处理请求出错

3、在MDK中编写代码

WebClient客户端代码
web_strdup将字符串复制到新开辟的内存空间
webclient_session_create创建webclient客户端
webclient_header_fields_add将请求句柄封装到客户端缓存区
webclient_header_fields_get解析响应数据的单一消息报头
webclient_header_length_response获取请求头的长度
webclient_handle_response获取服务器响应的状态码
webclient_data_analysis获取服务器返回的数据包
HTTP请求方法
webclient_get_method客户端GET请求方法
webclient_post_method客户端POST请求方法

修改ESP8266.c代码中的NET_DEVICE_LinkServer_Init函数(代码在上一章)

ESP8266_RETTYPE NET_DEVICE_LinkServer_Init(void)
{unsigned char errCount = 0, errType = 0;char cfgBuffer[70];switch(netDeviceInfo.initStep){case 0:if(ESP8266_Net_Mode_Choose(STA) == ESP8266_OK)netDeviceInfo.initStep++;break;case 1:if(ESP8266_Enable_MultipleId(DISABLE) == ESP8266_OK)netDeviceInfo.initStep++;break;case 2:if(ESP8266_JoinAP(netDeviceInfo.staName,netDeviceInfo.staPass) == ESP8266_OK)netDeviceInfo.initStep++;break;case 3://注释掉这一行,因为请求的网址不同
//			if(ESP8266_Link_Server(enumTCP,netDeviceInfo.staIPAddress,netDeviceInfo.staPort,Single_ID_0) == ESP8266_OK)netDeviceInfo.initStep++;break;default:netDeviceInfo.netWork = 1;errType = 3;break;}return errType;}

在webclient.h中编写以下代码

#ifndef __WEBCLIENT_H_
#define __WEBCLIENT_H_
#include "sys.h"#ifndef WEBCLIENT_OK
#define WEBCLIENT_OK 0
#endif#ifndef WEBCLIENT_NOK
#define WEBCLIENT_NOK 1
#endiftypedef struct __webclient_header
{char* buffer;unsigned int length;                      /* content header buffer size */unsigned int size;                        /* maximum support header size */
}webclient_header;typedef struct __webclient_session
{	webclient_header* header;    /* webclient response header information */int resp_status;int content_length;
}webclient_session;void webclient_get_method(void);
void webclient_post_method(void);#endif

在webclient.c中编写以下代码

#include "webclient.h"
#include "ESP8266.h"
#include "usart.h"
#include "StringUtil.h"//将字符串复制到新开辟的内存空间
char* web_strdup(const char* s)
{uint16_t len = strlen(s) + 1;char* tmp = (char*)malloc(len);if (!tmp)return NULL;memcpy(tmp, s, len);return tmp;
}//创建webclient客户端
webclient_session* webclient_session_create(uint16_t header_sz)
{webclient_session* session;/* create session */session = (webclient_session*)calloc(1, sizeof(webclient_session));if (session == NULL){printf("webclient create failed, no memory for webclient session!");return NULL;}/* initialize the socket of session */session->content_length = -1;session->header = (webclient_header*)calloc(1, sizeof(webclient_header));if (session->header == NULL){printf("webclient create failed, no memory for session header buffer!");free(session->header);free(session);session = NULL;return NULL;}session->header->size = header_sz;session->header->buffer = (char*)calloc(1, header_sz);if (session->header->buffer == NULL){printf("webclient create failed, no memory for session header buffer!");free(session->header);free(session);session = NULL;return NULL;}return session;
}//将请求句柄封装到客户端缓存区
unsigned char webclient_header_fields_add(webclient_session* session, const char* fmt, ...)
{int length;va_list args;va_start(args, fmt);length = vsnprintf(session->header->buffer + session->header->length, session->header->size - session->header->length, fmt, args);if (length < 0){printf("add fields header data failed, return length(%d) error.", length);return WEBCLIENT_NOK;}va_end(args);session->header->length += length;if (session->header->length >= session->header->size){printf("not enough header buffer size(%d)!", session->header->size);return WEBCLIENT_NOK;}return WEBCLIENT_OK;
}//解析响应数据的单一消息报头
const char* webclient_header_fields_get(webclient_session* session, const char* fields)
{char* resp_buf = NULL;size_t resp_buf_len = 0;char* dataPtr;char* mime_ptr = NULL;resp_buf = session->header->buffer;dataPtr = strstr(resp_buf,fields);if(dataPtr != NULL){mime_ptr = strstr(dataPtr,":");if(mime_ptr != NULL){mime_ptr += 1;while (*mime_ptr && (*mime_ptr == ' ' || *mime_ptr == '\t'))mime_ptr++;return mime_ptr;}}return NULL;
}//获取请求头的长度
unsigned int webclient_header_length_response(webclient_session* session)
{return (strlen(session->header->buffer) - session->content_length - 4);
}//获取服务器响应的状态码
unsigned char webclient_handle_response(webclient_session* session)
{int rc = 0;char* mime_buffer = NULL;char* mime_ptr = NULL;const char* transfer_encoding;int i;if(webclient_header_fields_get(session, "Content-Length") != NULL){session->content_length = atoi(webclient_header_fields_get(session, "Content-Length"));}session->header->length = webclient_header_length_response(session);/* get HTTP status code */mime_ptr = web_strdup(session->header->buffer);if (strstr(mime_ptr, "HTTP/1.")){char* ptr = mime_ptr;ptr += strlen("HTTP/1.x");printf("ptr: %s\r\n", ptr);while (*ptr && (*ptr == ' ' || *ptr == '\t'))ptr++;/* Terminate string after status code */for (i = 0; ((ptr[i] != ' ') && (ptr[i] != '\t')); i++);ptr[i] = '\0';session->resp_status = (int)strtol(ptr, NULL, 10);}if (mime_ptr){free(mime_ptr);}return session->resp_status;
}//获取服务器返回的数据包
uint8_t* webclient_data_analysis(webclient_session* session)
{char* dataptr;char* mime_ptr = session->header->buffer;//printf("session->header->buffer:%s\r\n",session->header->buffer);dataptr = strstr(mime_ptr,"\r\n\r\n");if(dataptr != NULL){dataptr += 4;return (uint8_t*)dataptr;}return NULL;
}//客户端GET请求方法
void webclient_get_method(void)
{webclient_session* session;uint8_t uwRet = WEBCLIENT_NOK;uint8_t *dataPtr;session = webclient_session_create(RX_BUF_MAX_LEN);if(session == NULL){printf("创建客户端失败\r\n");goto __exit;}//	webclient_header_fields_add(session,"GET http://%s:%s/getBinFile?IMEI=868626044941824 HTTP/1.1\r\n",netDeviceInfo.staIPAddress,netDeviceInfo.staPort);
//	webclient_header_fields_add(session,"\r\n");
//	GET https://api.seniverse.com/v3/weather/now.json?key=smtq3n0ixdggurox&location=nanning&language=zh-Hans&unit=c HTTP/1.1\r\n	webclient_header_fields_add(session,"GET https://api.seniverse.com/v3/weather/now.json?key=smtq3n0ixdggurox&location=nanning&language=en&unit=c HTTP/1.1\r\n");webclient_header_fields_add(session,"Host:www.baidu.com\r\n");webclient_header_fields_add(session,"\r\n");if(ESP8266_DisconnectServer(0) != ESP8266_OK)	//断开服务器连接,goto __exit;if(ESP8266_Link_Server(enumTCP,"api.seniverse.com","80",Single_ID_0) == ESP8266_OK)	//连接服务器{uwRet = ESP8266_SendData(DISABLE,(uint8_t*)session->header->buffer,session->header->length,Single_ID_0);	//发送数据if(uwRet == WEBCLIENT_OK)	//发送成功{dataPtr = ESP8266_GetIPD(DISABLE,2000);	//解析服务器返回的数据if(dataPtr != NULL){memset(session->header->buffer,0,session->header->size);session->header->length = 0;memcpy(session->header->buffer,dataPtr,session->header->size);if(webclient_handle_response(session) == 200)	//解析服务器返回的状态码{printf("strlen(session->header->buffer):%d\r\n",strlen(session->header->buffer));printf("session->header->length:%d\r\n",session->header->length);dataPtr = webclient_data_analysis(session);		//获取服务器返回的数据if(dataPtr != NULL){if(strstr((char*)dataPtr,"+IPD,"))		//查找是否有IPD头{dataPtr = Filter_string((char*)dataPtr,(char*)"+IPD,",(char*)":");	//过滤IPD头if(dataPtr!=NULL){printf("dataPtr:%s\r\n",dataPtr);//printf("session->content_length:%d\r\n",session->content_length);}}else{printf("dataPtr:%s\r\n",dataPtr);}}}}}}__exit:if(session->header->buffer != NULL){free(session->header->buffer);session->header->buffer=NULL;}if(session != NULL){free(session);session = NULL;}
}//客户端POST请求方法
void webclient_post_method(void)
{webclient_session* session;uint8_t uwRet = WEBCLIENT_NOK;uint8_t *dataPtr;session = webclient_session_create(RX_BUF_MAX_LEN);if(session == NULL){printf("创建客户端失败\r\n");goto __exit;}//	webclient_header_fields_add(session,"GET http://%s:%s/getBinFile?IMEI=868626044941824 HTTP/1.1\r\n",netDeviceInfo.staIPAddress,netDeviceInfo.staPort);
//	webclient_header_fields_add(session,"\r\n");
//	GET https://api.seniverse.com/v3/weather/now.json?key=smtq3n0ixdggurox&location=nanning&language=zh-Hans&unit=c HTTP/1.1\r\n	webclient_header_fields_add(session,"POST /devices/583402349/datapoints HTTP/1.1\r\n");webclient_header_fields_add(session,"api-key:rBIh6FFxeyW=kVJyybB2FzD5QAQ=\r\n");webclient_header_fields_add(session,"Host: api.heclouds.com\r\n");webclient_header_fields_add(session,"Content-Length:66\r\n");webclient_header_fields_add(session,"\r\n");webclient_header_fields_add(session,"{\"datastreams\":[{\"id\":\"test_stream\",\"datapoints\":[{\"value\":30}]}]}");if(ESP8266_DisconnectServer(0) != ESP8266_OK)	//断开服务器连接goto __exit;if(ESP8266_Link_Server(enumTCP,"api.heclouds.com","80",Single_ID_0) == ESP8266_OK)	//连接服务器{uwRet = ESP8266_SendData(DISABLE,(uint8_t*)session->header->buffer,session->header->length,Single_ID_0);	//发送数据if(uwRet == WEBCLIENT_OK)	//发送成功{dataPtr = ESP8266_GetIPD(DISABLE,2000);	//解析服务器返回的数据if(dataPtr != NULL){memset(session->header->buffer,0,session->header->size);session->header->length = 0;memcpy(session->header->buffer,dataPtr,session->header->size);if(webclient_handle_response(session) == 200)	//解析服务器返回的状态码{printf("strlen(session->header->buffer):%d\r\n",strlen(session->header->buffer));printf("session->header->length:%d\r\n",session->header->length);dataPtr = webclient_data_analysis(session);		//获取服务器返回的数据if(dataPtr != NULL){if(strstr((char*)dataPtr,"+IPD,"))		//查找是否有IPD头{dataPtr = Filter_string((char*)dataPtr,(char*)"+IPD,",(char*)":");	//过滤IPD头if(dataPtr!=NULL){printf("dataPtr:%s\r\n",dataPtr);//printf("session->content_length:%d\r\n",session->content_length);}}else{printf("dataPtr:%s\r\n",dataPtr);}}}}}}__exit:if(session->header->buffer != NULL){free(session->header->buffer);session->header->buffer=NULL;}if(session != NULL){free(session);session = NULL;}
}

在StringUtil.h中编写以下代码

#ifndef __STRING_UTIL_h
#define __STRING_UTIL_h
#include "string.h"
#include <ctype.h>
#include <stdlib.h>
#include "usart.h"int find_end(char * usart_buffer, int number);
int Find_string(char *pcBuf,char *left,char *right, char *pcRes);
void smart_array(unsigned char* addr,unsigned char *ip);
void Hex2Str(char *pbDest, char *pbSrc, int nLen);
unsigned char* Filter_string(char* pcBuf, char* left, char* right);
#endif

在StringUtil.c中编写以下代码

#include "StringUtil.h"/**
*@brief	 	ip网络地址转换
*@param		adr:地址 ip:ip
*@return	无
*/
void smart_array(unsigned char* addr,unsigned char *ip)
{int i;char taddr[30];char * nexttok;char num;strcpy(taddr,(char *)addr);nexttok = taddr;for(i = 0; i < 4 ; i++){nexttok = strtok(nexttok,".");
//		if(nexttok[0] == '0' && nexttok[1] == 'x') num = atoi16(nexttok+2,0x10);
//		else num = atoi16(nexttok,10);ip[i] = num;nexttok = NULL;}
}
/***********************************************************函数名称:Find_string(char *pcBuf,char*left,char*right, char *pcRes)函数功能:寻找特定字符串入口参数:char *pcBuf 为传入的字符串char*left   为搜索字符的左边标识符  例如:"["char*right  为搜索字符的右边标识符  例如:"]"char *pcRes 为输出转存的字符串数组返回值:用来校验是否成功,无所谓的。备注: left字符需要唯一,right字符从left后面开始唯一即可服务器下发命令举例:+MQTTPUBLISH: 0,0,0,0,/device/NB/zx99999999999999_back,6,[reastrobot]此函数会操作内存空间  强烈建议 提前清空buf   memset(Find_token,0x00,sizeof(Find_token));
***********************************************************/
int Find_string(char *pcBuf,char *left,char *right, char *pcRes)
{char *pcBegin = NULL;char *pcEnd = NULL;pcBegin = strstr(pcBuf, left);               //找到第一次出现的位置pcEnd = strstr(pcBegin+strlen(left), right); //找到右边标识第一次出现位置if(pcBegin == NULL || pcEnd == NULL || pcBegin > pcEnd){printf("string name not found!\n");return 0;}else{pcBegin += strlen(left);memcpy(pcRes, pcBegin, pcEnd-pcBegin);return 1;}
}//+IPD, 268:hello world\r\n
//过滤left和right之间的字符串,返回过滤之后的字符串
unsigned char* Filter_string(char* pcBuf, char* left, char* right)
{char* ptrIPD;ptrIPD = strstr((char*)pcBuf, left);				//搜索“left”头if (ptrIPD == NULL)										{//						UsartPrintf(USART_DEBUG, "\"left\" not found\r\n");}else{ptrIPD = strstr(ptrIPD, right);							//找到'right'if (ptrIPD != NULL){ptrIPD+=strlen(right);return (unsigned char*)(ptrIPD);}elsereturn NULL;}
}//int Smart_array(char *pcBuf,char *fu)
//{
//memcpy(&citc_server_ip[0],back_ip,strstr(back_ip,".")-back_ip);
//  char *pcBegin = NULL;
//	int8_t len =0;
//	pcBegin = strstr(pcBuf, fu);//找到第一次出现的位置
//	memcpy(&pcRes[i], pcBuf,pcBegin-pcBuf);
//	}
//	 len= strlen(pcBuf);
//	 pcBegin = strstr(pcBuf, fu);//找到第一次出现的位置
//	 memcpy(&pcRes[0], pcBuf,pcBegin-pcBuf);
//}//寻找字符后面最近的结束符
//int find_end(char * usart_buffer, int number) {
//  int i;
//  for (i = 0; i < 100; i++) {
//    if ((usart_buffer[number + i] == '/') && (usart_buffer[number + i + 1] == '>')) {
//      return number + i+2 ;   //如果有换行符  需要加4
//    }
//  }
//}//智能查找和匹配字符串
int8_t Find_AttributeStringAll(char *pcBuf, char *pcRest,uint16_t row,uint8_t col, char *left, char *right,uint8_t *Num)
{char pcFind[20] = {0};char *pcBegin = NULL;char *pcEnd = NULL;pcEnd  = pcBuf;while(1){memset(pcFind,0,20);pcBegin = strstr(pcEnd+1, left);if((pcBegin == NULL) || (strcmp(pcBegin,"}") == 0)){printf("找到指定字符 !\n");return 1;}else{pcEnd = strstr(pcBegin+strlen(left), right);if ((pcEnd == NULL) || (pcBegin > pcEnd)){printf("Mail name not found!\n");return -1;}else{if(*Num>row){return 1;}else{pcBegin += strlen(left);memcpy(pcFind, pcBegin, pcEnd - pcBegin);memset(pcRest+*Num*col,0,col);memcpy(pcRest+*Num*col,pcFind,sizeof(pcFind));(*Num) ++;}}}}
}void Hex2Str(char *pbDest, char *pbSrc, int nLen)
{char    ddl,ddh;int i;for (i=0; i<nLen; i++){ddh = 48 + pbSrc[i] / 16;ddl = 48 + pbSrc[i] % 16;if (ddh > 57) ddh = ddh + 7;if (ddl > 57) ddl = ddl + 7;pbDest[i*2] = ddh;pbDest[i*2+1] = ddl;}pbDest[nLen*2] = '\0';
}void Str2Hex(char* str, char* hex)
{const char* cHex = "0123456789ABCDEF";int i=0;for(int j =0; j < strlen(str); j++){unsigned int a =  (unsigned int) str[j];hex[i++] = cHex[(a & 0xf0) >> 4];hex[i++] = cHex[(a & 0x0f)];}hex[i] = '\0';
}

在main.c中编写以下代码

/* USER CODE BEGIN 0 */#define REQUEST_METHOD 	0	//0:GET请求,1:POST请求
/* USER CODE END 0 */int main(void)
{/* USER CODE BEGIN 1 */unsigned char* dataPtr = NULL;uint32_t request_time = 0;uint32_t netErr_time = 0;ESP8266_RETTYPE uwRet = ESP8266_NOK;uint32_t total_len=0;/* USER CODE END 1 *//* MCU Configuration--------------------------------------------------------*//* Reset of all peripherals, Initializes the Flash interface and the Systick. */HAL_Init();/* USER CODE BEGIN Init *//* USER CODE END Init *//* Configure the system clock */SystemClock_Config();/* USER CODE BEGIN SysInit *//* USER CODE END SysInit *//* Initialize all configured peripherals */MX_GPIO_Init();MX_DMA_Init();MX_LPUART1_UART_Init();MX_USART1_UART_Init();MX_TIM2_Init();/* USER CODE BEGIN 2 */TIM_Interupt_Enable(); //使能串口中断USART_Interupt_Enable(); //使能定时器中断/* USER CODE END 2 *//* Infinite loop *//* USER CODE BEGIN WHILE */while (1){/* USER CODE END WHILE *//* USER CODE BEGIN 3 */if(!netDeviceInfo.netWork)	//如果网络未连接{if(NET_DEVICE_Init() == ESP8266_OK)	{printf("初始化成功\r\n");}}if(time2Count - request_time >= 10000)		//(1ms * 2000)相当于延时2秒钟{if(netDeviceInfo.netWork)//如果网络连接成功{
#if REQUEST_METHODwebclient_get_method();	
#elsewebclient_post_method();
#endif}}}/* USER CODE END 3 */
}

4、实验现象

实现的功能
1、上电自动连接WIFI
2、如果是POST请求,则请求POST接口(我这里用的是ONENET的POST接口)
3、如果是GET请求,则请求GET接口(我这里用的是心知天气的GET接口)

POST请求(Onenet物联网平台)
在这里插入图片描述
GET请求(心知天气)
在这里插入图片描述

这篇关于STM32玩转物联网实战篇:3.1.ESP8266 WIFI模块WEBClient通信示例详解GET、POST(心知天气、Onenet)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/424678

相关文章

C++使用栈实现括号匹配的代码详解

《C++使用栈实现括号匹配的代码详解》在编程中,括号匹配是一个常见问题,尤其是在处理数学表达式、编译器解析等任务时,栈是一种非常适合处理此类问题的数据结构,能够精确地管理括号的匹配问题,本文将通过C+... 目录引言问题描述代码讲解代码解析栈的状态表示测试总结引言在编程中,括号匹配是一个常见问题,尤其是在

Debezium 与 Apache Kafka 的集成方式步骤详解

《Debezium与ApacheKafka的集成方式步骤详解》本文详细介绍了如何将Debezium与ApacheKafka集成,包括集成概述、步骤、注意事项等,通过KafkaConnect,D... 目录一、集成概述二、集成步骤1. 准备 Kafka 环境2. 配置 Kafka Connect3. 安装 D

Java中ArrayList和LinkedList有什么区别举例详解

《Java中ArrayList和LinkedList有什么区别举例详解》:本文主要介绍Java中ArrayList和LinkedList区别的相关资料,包括数据结构特性、核心操作性能、内存与GC影... 目录一、底层数据结构二、核心操作性能对比三、内存与 GC 影响四、扩容机制五、线程安全与并发方案六、工程

Java调用DeepSeek API的最佳实践及详细代码示例

《Java调用DeepSeekAPI的最佳实践及详细代码示例》:本文主要介绍如何使用Java调用DeepSeekAPI,包括获取API密钥、添加HTTP客户端依赖、创建HTTP请求、处理响应、... 目录1. 获取API密钥2. 添加HTTP客户端依赖3. 创建HTTP请求4. 处理响应5. 错误处理6.

Android 悬浮窗开发示例((动态权限请求 | 前台服务和通知 | 悬浮窗创建 )

《Android悬浮窗开发示例((动态权限请求|前台服务和通知|悬浮窗创建)》本文介绍了Android悬浮窗的实现效果,包括动态权限请求、前台服务和通知的使用,悬浮窗权限需要动态申请并引导... 目录一、悬浮窗 动态权限请求1、动态请求权限2、悬浮窗权限说明3、检查动态权限4、申请动态权限5、权限设置完毕后

Spring Cloud LoadBalancer 负载均衡详解

《SpringCloudLoadBalancer负载均衡详解》本文介绍了如何在SpringCloud中使用SpringCloudLoadBalancer实现客户端负载均衡,并详细讲解了轮询策略和... 目录1. 在 idea 上运行多个服务2. 问题引入3. 负载均衡4. Spring Cloud Load

Springboot中分析SQL性能的两种方式详解

《Springboot中分析SQL性能的两种方式详解》文章介绍了SQL性能分析的两种方式:MyBatis-Plus性能分析插件和p6spy框架,MyBatis-Plus插件配置简单,适用于开发和测试环... 目录SQL性能分析的两种方式:功能介绍实现方式:实现步骤:SQL性能分析的两种方式:功能介绍记录

在 Spring Boot 中使用 @Autowired和 @Bean注解的示例详解

《在SpringBoot中使用@Autowired和@Bean注解的示例详解》本文通过一个示例演示了如何在SpringBoot中使用@Autowired和@Bean注解进行依赖注入和Bean... 目录在 Spring Boot 中使用 @Autowired 和 @Bean 注解示例背景1. 定义 Stud

oracle DBMS_SQL.PARSE的使用方法和示例

《oracleDBMS_SQL.PARSE的使用方法和示例》DBMS_SQL是Oracle数据库中的一个强大包,用于动态构建和执行SQL语句,DBMS_SQL.PARSE过程解析SQL语句或PL/S... 目录语法示例注意事项DBMS_SQL 是 oracle 数据库中的一个强大包,它允许动态地构建和执行

如何通过海康威视设备网络SDK进行Java二次开发摄像头车牌识别详解

《如何通过海康威视设备网络SDK进行Java二次开发摄像头车牌识别详解》:本文主要介绍如何通过海康威视设备网络SDK进行Java二次开发摄像头车牌识别的相关资料,描述了如何使用海康威视设备网络SD... 目录前言开发流程问题和解决方案dll库加载不到的问题老旧版本sdk不兼容的问题关键实现流程总结前言作为