当前位置: 首页 > news >正文

SpringBoot接入微信公众号【服务号】

SpringBoot接入微信公众号【服务号】

一、服务号注册

注册地址:https://mp.weixin.qq.com/cgi-bin/registermidpage?action=index&lang=zh_CN
在这里插入图片描述
注册流程参考:https://kf.qq.com/touch/faq/150804UVr222150804quq6B7.html?platform=15

二、服务号配置

基本配置

用于服务配置
在这里插入图片描述
在这里插入图片描述

访问及服务配置

在这里插入图片描述

网页授权配置

在这里插入图片描述

三、核心代码

  • 基于WxJava - 微信开发 Java SDK
  • 实现关注、取关逻辑
  • 实现消息被动回复
  • 实现个人信息网页授权
  • 提供基本业务功能

微信开发者文档:https://developers.weixin.qq.com/doc/offiaccount/Getting_Started/Overview.html

WxJava开源地址:https://gitee.com/binary/weixin-java-tools?_from=gitee_search

引入pom依赖

<dependency><groupId>com.github.binarywang</groupId><artifactId>weixin-java-mp</artifactId><version>4.5.0</version>
</dependency>

yml配置文件

# 微信公众号配置
wx:mp:appId: wx1111111appSecret: 111111111111# 配置消息回调地址接入公众号时需要的tokentoken: add2222aesKey: xxxxserver: https://www.baidu.com/

属性配置类

package com.qiangesoft.wechat.config;import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;/*** 微信公众号相关配置属性** @author qiangesoft* @date 2023-09-07*/
@Data
@Component
@ConfigurationProperties(WxMpProperties.PREFIX)
public class WxMpProperties {public static final String PREFIX = "wx.mp";/*** 公众号开发信息:appId*/private String appId;/*** 公众号开发信息:appSecret*/private String appSecret;/*** 服务器配置:token*/private String token;/*** 服务器配置:消息加解密密钥EncodingAESKey*/private String aesKey;/*** 服务器配置:微信服务器地址*/private String server;}

bean配置类

package com.qiangesoft.wechat.config;import com.qiangesoft.wechat.core.handler.LogHandler;
import com.qiangesoft.wechat.core.handler.event.SubscribeHandler;
import com.qiangesoft.wechat.core.handler.event.UnsubscribeHandler;
import com.qiangesoft.wechat.core.handler.message.ImageHandler;
import com.qiangesoft.wechat.core.handler.message.LocationHandler;
import com.qiangesoft.wechat.core.handler.message.MessageHandler;
import com.qiangesoft.wechat.core.handler.message.VoiceHandler;
import com.qiangesoft.wechat.core.interceptor.MessageInterceptor;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.api.WxConsts;
import me.chanjar.weixin.mp.api.WxMpMessageRouter;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.api.impl.WxMpServiceImpl;
import me.chanjar.weixin.mp.config.WxMpConfigStorage;
import me.chanjar.weixin.mp.config.impl.WxMpDefaultConfigImpl;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;/*** 微信公众号配置** @author qiangesoft* @date 2023-09-07*/
@Slf4j
@Configuration
@RequiredArgsConstructor
public class WxMpConfiguration {/*** 微信公众号配置信息*/private final WxMpProperties wxMpProperties;/*** 日志处理器*/private final LogHandler logHandler;/*** 订阅事件处理器*/private final SubscribeHandler subscribeHandler;/*** 取消订阅事件处理器*/private final UnsubscribeHandler unsubscribeHandler;/*** 语音消息处理器*/private final VoiceHandler voiceHandler;/*** 文本消息处理器*/private final MessageHandler messageHandler;/*** 图片消息处理器*/private final ImageHandler imageHandler;/*** 位置消息处理器*/private final LocationHandler locationHandler;/*** 消息拦截器*/private final MessageInterceptor messageInterceptor;/*** 声明实例** @return*/@Beanpublic WxMpService wxMpService() {WxMpService wxMpService = new WxMpServiceImpl();wxMpService.setWxMpConfigStorage(wxMpConfigStorage());return wxMpService;}/*** 配置存储方式** @return*/@Beanpublic WxMpConfigStorage wxMpConfigStorage() {WxMpDefaultConfigImpl configStorage = new WxMpDefaultConfigImpl();// 公众号appIdconfigStorage.setAppId(wxMpProperties.getAppId());// 公众号appSecretconfigStorage.setSecret(wxMpProperties.getAppSecret());// 公众号TokenconfigStorage.setToken(wxMpProperties.getToken());// 公众号EncodingAESKeyconfigStorage.setAesKey(wxMpProperties.getAesKey());return configStorage;}/*** 配置公众号的事件路由* <p>* 1.用户发消息* 2.关注事件* 3.取消关注事件* ......*/@Beanpublic WxMpMessageRouter messageRouter(WxMpService wxMpService) {WxMpMessageRouter newRouter = new WxMpMessageRouter(wxMpService);// 记录所有消息事件的日志newRouter.rule().async(false).handler(this.logHandler).next();// 文本消息newRouter.rule().async(false).msgType(WxConsts.XmlMsgType.TEXT).interceptor(this.messageInterceptor).handler(this.messageHandler).end();// 语音消息newRouter.rule().async(false).msgType(WxConsts.XmlMsgType.VOICE).handler(this.voiceHandler).end();// 图片消息newRouter.rule().async(false).msgType(WxConsts.XmlMsgType.IMAGE).handler(this.imageHandler).end();// 位置消息newRouter.rule().async(false).msgType(WxConsts.XmlMsgType.LOCATION).handler(this.locationHandler).end();// 关注事件newRouter.rule().async(false).msgType(WxConsts.XmlMsgType.EVENT).event(WxConsts.EventType.SUBSCRIBE).handler(this.subscribeHandler).end();// 取消关注事件newRouter.rule().async(false).msgType(WxConsts.XmlMsgType.EVENT).event(WxConsts.EventType.UNSUBSCRIBE).handler(this.unsubscribeHandler).end();return newRouter;}
}

网页授权接入配置

下载验证文件放于项目目录
在这里插入图片描述
在这里插入图片描述

package com.qiangesoft.wechat.controller;import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.io.ClassPathResource;
import org.springframework.http.HttpHeaders;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;/*** 微信接入控制器* ps:(JS接口安全域名、网页授权域名需要获取MP_verify_eerrereeee.txt)* <a href="https://mp.weixin.qq.com/cgi-bin/settingpage?t=setting/function&action=function&token=854866943&lang=zh_CN">...</a>** @author qiangesoft* @date 2023-09-11*/
@Slf4j
@Api(tags = "微信接入")
@RestController
@RequestMapping("/wechat")
public class WxAccessController {/*** 获取安全凭证* ps:例如[http://主机:端口/wechat/MP_verify_eerrereeee.txt]** @param fileName* @param response*/@ApiOperation(value = "安全凭证")@GetMapping("/{fileName}")public void security(@PathVariable String fileName, HttpServletResponse response) {InputStream is = null;OutputStream os = null;try {// 获取文件ClassPathResource classPathResource = new ClassPathResource(fileName);String filename = classPathResource.getFilename();is = classPathResource.getInputStream();byte[] bytes = is.readAllBytes();response.setCharacterEncoding("UTF-8");response.addHeader(HttpHeaders.CONTENT_DISPOSITION, "attachment;filename=" + URLEncoder.encode(filename, StandardCharsets.UTF_8));response.addHeader(HttpHeaders.CONTENT_LENGTH, bytes.length + "");response.setContentType("application/octet-stream");os = response.getOutputStream();os.write(bytes);} catch (IOException e) {e.printStackTrace();} finally {if (os != null) {try {os.close();} catch (IOException e) {e.printStackTrace();}}if (is != null) {try {is.close();} catch (IOException e) {e.printStackTrace();}}}}
}

微信请求验证及被动消息回复

package com.qiangesoft.wechat.controller;import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.mp.api.WxMpMessageRouter;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.bean.message.WxMpXmlMessage;
import me.chanjar.weixin.mp.bean.message.WxMpXmlOutMessage;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;/*** 微信消息控制器* ps:请求验证、接收消息被动回复等** @author qiangesoft* @date 2023-09-07*/
@Slf4j
@Api(tags = "微信消息")
@RestController
@RequestMapping("/wechat/message")
public class WxMessageController {@Autowiredprivate WxMpService wxMpService;@Autowiredprivate WxMpMessageRouter wxMpMessageRouter;@ApiOperation(value = "验证接口")@GetMappingpublic String validate(@RequestParam String signature,@RequestParam String timestamp,@RequestParam String nonce,@RequestParam String echostr) {// 校验消息是否来自微信if (!wxMpService.checkSignature(timestamp, nonce, signature)) {throw new IllegalArgumentException("非法请求,可能属于伪造的请求!");}return echostr;}@ApiOperation(value = "接收消息")@PostMapping(produces = "application/xml; charset=UTF-8")public String handleMessage(@RequestBody String requestBody,@RequestParam String signature,@RequestParam String timestamp,@RequestParam String nonce,@RequestParam String openid,@RequestParam(name = "encrypt_type", required = false) String encType,@RequestParam(name = "msg_signature", required = false) String msgSignature) {// 校验消息是否来自微信if (!wxMpService.checkSignature(timestamp, nonce, signature)) {throw new IllegalArgumentException("非法请求,可能属于伪造的请求!");}// 消息处理【被动消息回复】String message = null;if (encType == null) {// 明文传输WxMpXmlMessage inMessage = WxMpXmlMessage.fromXml(requestBody);WxMpXmlOutMessage outMessage = wxMpMessageRouter.route(inMessage);if (outMessage == null) {return null;}message = outMessage.toXml();} else if ("aes".equalsIgnoreCase(encType)) {// aes加密WxMpXmlMessage inMessage = WxMpXmlMessage.fromEncryptedXml(requestBody, wxMpService.getWxMpConfigStorage(), timestamp, nonce, msgSignature);WxMpXmlOutMessage outMessage = wxMpMessageRouter.route(inMessage);if (outMessage == null) {return null;}message = outMessage.toEncryptedXml(wxMpService.getWxMpConfigStorage());}return message;}
}

用户信息网页授权

package com.qiangesoft.wechat.controller;import com.qiangesoft.wechat.config.WxMpProperties;
import com.qiangesoft.wechat.dto.UserDTO;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.api.WxConsts;
import me.chanjar.weixin.common.bean.WxOAuth2UserInfo;
import me.chanjar.weixin.common.bean.oauth2.WxOAuth2AccessToken;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.common.service.WxOAuth2Service;
import me.chanjar.weixin.mp.api.WxMpService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;/*** 微信用户控制器* ps:获取用户信息、授权网页用户信息等** @author qiangesoft* @date 2023-09-11*/
@Slf4j
@Api(tags = "微信用户")
@Controller
@RequestMapping("/wechat/user")
public class WxUserController {@Autowiredprivate WxMpProperties wxMpProperties;@Autowiredprivate WxMpService wxMpService;@ApiOperation(value = "个人信息")@GetMapping("/mine")public String mine() {WxOAuth2Service oAuth2Service = wxMpService.getOAuth2Service();// 构建授权urlString authorizationUrl = oAuth2Service.buildAuthorizationUrl(wxMpProperties.getServer() + "wechat/user/callback", WxConsts.OAuth2Scope.SNSAPI_USERINFO, null);return "redirect:" + authorizationUrl;}@ApiOperation(value = "个人信息网页授权回调")@GetMapping("/callback")public String callback(String code, Model model) throws WxErrorException {WxOAuth2UserInfo userInfo = this.getUserInfo(code);String openid = userInfo.getOpenid();// todo 通过openid拿取业务系统详细用户信息 IWxUserServiceUserDTO userDTO = new UserDTO();userDTO.setOpenId(openid);userDTO.setNickName(userInfo.getNickname());model.addAttribute("user", userDTO);return "mine";}/*** 获取微信用户信息** @param code* @return* @throws WxErrorException*/private WxOAuth2UserInfo getUserInfo(String code) throws WxErrorException {WxOAuth2Service oAuth2Service = wxMpService.getOAuth2Service();// 利用code获取accessTokenWxOAuth2AccessToken accessToken = oAuth2Service.getAccessToken(code);// 利用accessToken获取用户信息WxOAuth2UserInfo userInfo = oAuth2Service.getUserInfo(accessToken, null);return userInfo;}
}

消息拦截器

package com.qiangesoft.wechat.core.interceptor;import me.chanjar.weixin.common.api.WxConsts;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.common.session.WxSessionManager;
import me.chanjar.weixin.mp.api.WxMpMessageInterceptor;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.bean.message.WxMpXmlMessage;
import org.springframework.stereotype.Component;import java.util.Map;/*** 对微信公众号消息进行预处理、过滤等操作,根据具体业务需求决定是否允许继续执行后面的路由处理方法* <p>* 1.如果要中止消息的继续处理,需要返回 false* 2.在执行完当前拦截器操作后,允许消息的继续处理,返回 true** @author qiangesoft* @date 2023-09-07*/
@Component
public class MessageInterceptor implements WxMpMessageInterceptor {@Overridepublic boolean intercept(WxMpXmlMessage wxMessage, Map<String, Object> context, WxMpService wxMpService, WxSessionManager sessionManager) throws WxErrorException {String msgType = wxMessage.getMsgType();String content = wxMessage.getContent();// 文本处理if (msgType.equals(WxConsts.XmlMsgType.TEXT)) {if (content.contains("混蛋")) {String newContent = content.replace("混蛋", "***");wxMessage.setContent(newContent);}return true;}// todo 音频、视频处理return true;}
}

消息事件处理器

1.关注事件处理器
package com.qiangesoft.wechat.core.handler.event;import com.qiangesoft.wechat.core.builder.TextOutMessageBuilder;
import com.qiangesoft.wechat.entity.WxUser;
import com.qiangesoft.wechat.service.IWxUserService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.api.WxConsts;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.common.session.WxSessionManager;
import me.chanjar.weixin.mp.api.WxMpMessageHandler;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.bean.message.WxMpXmlMessage;
import me.chanjar.weixin.mp.bean.message.WxMpXmlOutMessage;
import org.springframework.stereotype.Component;import java.util.Map;/*** 微信公众号用户关注处理器** @author qiangesoft* @date 2023-09-07*/
@Slf4j
@Component
@RequiredArgsConstructor
public class SubscribeHandler implements WxMpMessageHandler {private final IWxUserService wxUserService;@Overridepublic WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage, Map<String, Object> context, WxMpService wxMpService, WxSessionManager sessionManager) throws WxErrorException {if (!wxMessage.getMsgType().equals(WxConsts.EventType.SUBSCRIBE)) {return null;}String openId = wxMessage.getFromUser();// 微信关注用户WxUser wxUser = wxUserService.getByOpenId(openId);if (wxUser == null) {wxUser = new WxUser();wxUser.setOpenId(openId);wxUser.setAttentionFlag(true);wxUserService.save(wxUser);} else {wxUser.setAttentionFlag(true);wxUserService.updateById(wxUser);}String outContent = "您好,欢迎关注xxx!";return new TextOutMessageBuilder().build(outContent, wxMessage, wxMpService);}
}
2.取关事件处理器
package com.qiangesoft.wechat.core.handler.event;import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.qiangesoft.wechat.core.builder.TextOutMessageBuilder;
import com.qiangesoft.wechat.entity.WxUser;
import com.qiangesoft.wechat.service.IWxUserService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.api.WxConsts;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.common.session.WxSessionManager;
import me.chanjar.weixin.mp.api.WxMpMessageHandler;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.bean.message.WxMpXmlMessage;
import me.chanjar.weixin.mp.bean.message.WxMpXmlOutMessage;
import org.springframework.stereotype.Component;import java.util.Map;/*** 微信公众号用户取消关注处理器** @author qiangesoft* @date 2023-09-07*/
@Slf4j
@Component
@RequiredArgsConstructor
public class UnsubscribeHandler implements WxMpMessageHandler {private final IWxUserService wxUserService;@Overridepublic WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage, Map<String, Object> context, WxMpService wxMpService, WxSessionManager sessionManager) throws WxErrorException {if (!wxMessage.getMsgType().equals(WxConsts.EventType.UNSUBSCRIBE)) {return null;}String openId = wxMessage.getFromUser();// 取消关注LambdaUpdateWrapper<WxUser> updateWrapper = new LambdaUpdateWrapper<>();updateWrapper.eq(WxUser::getOpenId, openId).set(WxUser::getAttentionFlag, false);wxUserService.update(updateWrapper);String outContent = "已取消关注xxx,再见!";return new TextOutMessageBuilder().build(outContent, wxMessage, wxMpService);}
}
3.文本消息处理器
package com.qiangesoft.wechat.core.handler.message;import com.qiangesoft.wechat.core.builder.TextOutMessageBuilder;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.api.WxConsts;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.common.session.WxSessionManager;
import me.chanjar.weixin.mp.api.WxMpMessageHandler;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.bean.message.WxMpXmlMessage;
import me.chanjar.weixin.mp.bean.message.WxMpXmlOutMessage;
import org.springframework.stereotype.Component;import java.util.Map;/*** 文本消息处理器** @author qiangesoft* @date 2023-09-07*/
@Slf4j
@Component
public class MessageHandler implements WxMpMessageHandler {@Overridepublic WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage, Map<String, Object> context, WxMpService wxMpService, WxSessionManager sessionManager) throws WxErrorException {if (!wxMessage.getMsgType().equals(WxConsts.XmlMsgType.TEXT)) {return null;}// 接收的消息内容String content = wxMessage.getContent();log.info("Received wechat text message, content [{}] !", content);String outContent = "您好,欢迎访问xxx!";if (content.contains("你好") || content.contains("您好")) {outContent = "您好";}return new TextOutMessageBuilder().build(outContent, wxMessage, wxMpService);}
}
4.日志记录处理器
package com.qiangesoft.wechat.core.handler;import com.alibaba.fastjson2.JSONObject;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.common.session.WxSessionManager;
import me.chanjar.weixin.mp.api.WxMpMessageHandler;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.bean.message.WxMpXmlMessage;
import me.chanjar.weixin.mp.bean.message.WxMpXmlOutMessage;
import org.springframework.stereotype.Component;import java.util.Map;/*** 微信公众号日志记录处理器** @author qiangesoft* @date 2023-09-07*/
@Slf4j
@Component
public class LogHandler implements WxMpMessageHandler {@Overridepublic WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage, Map<String, Object> context, WxMpService wxMpService, WxSessionManager sessionManager) throws WxErrorException {log.info("Received wechat message, content is [{}]", JSONObject.toJSONString(wxMessage));return null;}
}

源码地址

地址:https://gitee.com/qiangesoft/boot-business/tree/master/boot-business-wechat

相关文章:

SpringBoot接入微信公众号【服务号】

SpringBoot接入微信公众号【服务号】 一、服务号注册 注册地址&#xff1a;https://mp.weixin.qq.com/cgi-bin/registermidpage?actionindex&langzh_CN 注册流程参考&#xff1a;https://kf.qq.com/touch/faq/150804UVr222150804quq6B7.html?platform15 二、服务号配…...

2023 英特尔On技术创新大会直播 |探索视觉AI的无限可能

2023 英特尔On技术创新大会直播 | 探索视觉AI的无限可能 前言一未来的 AI&#xff1a;释放视觉 AI 真正潜力二AI技术突破、视觉Al挑战及前沿研究创新三全尺度视觉学习全尺度视觉学习示例1.GridConv 实现三维人体姿态估计更高准确率2.KW 预训练及迁移模型性能3.无数据增强稠密对…...

安卓视图基础

目录 设置视图的宽高 设置视图的间隔 设置视图的对齐方式 设置视图的宽高 设置视图的间隔 设置视图的对齐方式 <?xml version"1.0" encoding"utf-8"?> <LinearLayout xmlns:android"http://schemas.android.com/apk/res/android"a…...

电路设计(10)——超温报警电路的proteus仿真

1.题目背景 在现实生活中&#xff0c;常有一种工程技术&#xff0c;即带有自动温度补偿的设备&#xff0c;能在规定温度内正常工作。但是为了设备安全&#xff0c;需设定工作的上限温度&#xff0c;万一温控补偿失效&#xff0c;设备温度一旦超出上限温度时&#xff0c;便立即切…...

gerrit(1) | gerrit 简介

gerrit(1) | gerrit 简介 1. 目的 之前用过 gitlab CI/CD, github actions, 以及公司的配置管理员配置的 jenkins。 github 的 MR&#xff0c; github 的 PR&#xff0c; 虽然在用&#xff0c; 但仅限于参与开源项目或公司内的开源项目&#xff0c; OEM 项目中完全没在用。 …...

计算机视觉实战项目3(图像分类+目标检测+目标跟踪+姿态识别+车道线识别+车牌识别+无人机检测+A*路径规划+单目测距与测速+行人车辆计数等)

车辆跟踪及测距 该项目一个基于深度学习和目标跟踪算法的项目&#xff0c;主要用于实现视频中的目标检测和跟踪。该项目使用了 YOLOv5目标检测算法和 DeepSORT 目标跟踪算法&#xff0c;以及一些辅助工具和库&#xff0c;可以帮助用户快速地在本地或者云端上实现视频目标检测和…...

redis(5)

文章目录 一、redis 哨兵&#xff08;sentinel&#xff09;redis 集群介绍哨兵&#xff08;Sentinel&#xff09;工作原理sentinel 架构和故障转移sentinel中的三个定时任务 实时哨兵启动哨兵验证哨兵端口查看哨兵日志当前sentinel状态停止Redis Master测试故障转移恢复故障的m…...

Postgresql体系结构

client连接PostgreSQL过程&#xff1a; 1、客户端发起请求 2、主服务postmaster进程负责服务器是否接受客户端的host通信认证&#xff0c;服务器对客户端进行身份鉴别 3、主服务进程为该客户端单独fork一个客户端工作进程postgres 4、客户端与postgres进程建立通信连接&#xf…...

【Rust】——rust前言与安装rust

&#x1f383;个人专栏&#xff1a; &#x1f42c; 算法设计与分析&#xff1a;算法设计与分析_IT闫的博客-CSDN博客 &#x1f433;Java基础&#xff1a;Java基础_IT闫的博客-CSDN博客 &#x1f40b;c语言&#xff1a;c语言_IT闫的博客-CSDN博客 &#x1f41f;MySQL&#xff1a…...

基于SpringBoot的家电销售展示网页的设计与实现

文章目录 项目介绍主要功能截图&#xff1a;部分代码展示设计总结项目获取方式 &#x1f345; 作者主页&#xff1a;超级无敌暴龙战士塔塔开 &#x1f345; 简介&#xff1a;Java领域优质创作者&#x1f3c6;、 简历模板、学习资料、面试题库【关注我&#xff0c;都给你】 &…...

【Qt】—— 项⽬⽂件解析

目录 &#xff08;一&#xff09;.pro⽂件解析 &#xff08;二&#xff09;widget.h⽂件解析 &#xff08;三&#xff09;main.cpp⽂件解析 &#xff08;四&#xff09;widget.cpp⽂件解析 &#xff08;五&#xff09;widget.ui⽂件解析 &#xff08;一&#xff09;.pro⽂…...

【Linux】静态库和动态库

动静态库 一、静态库1. 静态库概念2. 制作静态库&#xff08;1&#xff09;朴素方法 --- 不打包&#xff08;2&#xff09;对静态库打包 3. 使用静态库&#xff08;1&#xff09;朴素方法 --- 直接使用&#xff08;2&#xff09;使用打包好的静态库 二、动态库1. 动态库概念2. …...

LeetCode 0292.Nim 游戏:脑筋急转弯

【LetMeFly】292.Nim 游戏&#xff1a;脑筋急转弯 力扣题目链接&#xff1a;https://leetcode.cn/problems/nim-game/ 你和你的朋友&#xff0c;两个人一起玩 Nim 游戏&#xff1a; 桌子上有一堆石头。你们轮流进行自己的回合&#xff0c; 你作为先手 。每一回合&#xff0c…...

ctfshow-web1~10-WP

web1 右键查看源码就能看到flag web2 打开网页提示无法查看源代码,右键也使用不了,那我们就在url前面加上view-source: view-source:http://83a83588-671e-4a94-9c6f-6857f9e20c2f.chall.ctf.show/ 访问后即可获得flag web3 右键源码也没看到信息,去查看一下请求头和响应…...

集合问题(并查集)

本题链接&#xff1a;登录—专业IT笔试面试备考平台_牛客网 题目&#xff1a; 样例1&#xff1a; 输入 4 5 9 2 3 4 5 输出 YES 0 0 1 1 样例2&#xff1a; 输入 3 3 4 1 2 4 输出 NO 思路&#xff1a; 这道题关键点在于。 当集合中有一个元素均存在于集合 A 和集合 B 的时…...

Ubuntu文件系统结构

Ubuntu文件系统结构 介绍 Ubuntu是一种备受欢迎的Linux发行版&#xff0c;其文件系统结构以及组织方式是每个使用者和系统管理员都应该了解的重要主题。本篇博客将带您深入探索Ubuntu文件系统的结构&#xff0c;以便更好地理解Linux操作系统的工作原理。 1. 根目录&#xff…...

vue element 组件 form深层 :prop 验证失效问题解决

此图源自官网 借鉴。 当我们简单单层验证的时候发现是没有问题的&#xff0c;但是有的时候可能会涉及到深层prop&#xff0c;发现在去绑定的时候就不生效了。例如我们在form单里面循环验证&#xff0c;在去循环数据验证。 就如下图的写法了 :prop"pumplist. i .device…...

前端开发:入门(一)

当我们开始学习前端开发时&#xff0c;首先接触到的是HTML&#xff08;超文本标记语言&#xff09;。HTML是构建网页结构的基础。 1. HTML&#xff08;超文本标记语言&#xff09; 介绍和基础语法 HTML&#xff0c;即超文本标记语言&#xff0c;是一种用于创建网页结构的标记…...

简单实验 java spring cloud 自定义负载均衡

1.概要 1.1 说明 这个是在前一个测试上的修改&#xff0c;所以这里只体现修改的内容。前一个测试的地址&#xff1a;检查实验 spring cloud nacos nacos-server-2.3.0-CSDN博客 1.2 记忆要点 1.2.1 引入对象 Autowired DiscoveryClient discoveryClient; 1.2.2 获取服务实…...

简单说说redis分布式锁

什么是分布式锁 分布式锁&#xff08;多服务共享锁&#xff09;在分布式的部署环境下&#xff0c;通过锁机制来让多客户端互斥的对共享资源进行访问/操作。 为什么需要分布式锁 在单体应用服务里&#xff0c;不同的客户端操作同一个资源&#xff0c;我们可以通过操作系统提供…...

避坑指南:Doris明细模型(Duplicate Key Model)的5个常见错误及优化方案

避坑指南&#xff1a;Doris明细模型(Duplicate Key Model)的5个常见错误及优化方案 在实时数据分析领域&#xff0c;Apache Doris凭借其卓越的性能和易用性赢得了众多企业的青睐。作为Doris中最基础也最常用的数据模型&#xff0c;明细模型&#xff08;Duplicate Key Model&…...

RX9 vs RX7:哪个更适合你的AU音频修复工作流?实测对比与安装教程

RX9 vs RX7&#xff1a;专业音频修复工具深度评测与实战指南 在数字音频处理领域&#xff0c;iZotope RX系列一直是音频修复的金标准。当最新版RX9与经典版RX7同时出现在插件列表中&#xff0c;专业音频工程师们常常面临选择困境——是升级到功能更强大的新版本&#xff0c;还是…...

高效使用Cursor Free VIP:5步全面解锁AI编程Pro功能终极指南

高效使用Cursor Free VIP&#xff1a;5步全面解锁AI编程Pro功能终极指南 【免费下载链接】cursor-free-vip [Support 0.45]&#xff08;Multi Language 多语言&#xff09;自动注册 Cursor Ai &#xff0c;自动重置机器ID &#xff0c; 免费升级使用Pro 功能: Youve reached yo…...

从风机并网振荡说起:手把手教你用Simulink设计VSG自适应阻尼,提升微网稳定性

新能源微网稳定性实战&#xff1a;基于Simulink的VSG自适应阻尼控制设计 当新能源发电占比超过30%时&#xff0c;微电网会面临一个尴尬的现状——传统同步发电机提供的旋转惯量大幅减少&#xff0c;系统变得像"玻璃杯"一样脆弱。去年参与某海岛微网项目时&#xff0c…...

KeymouseGo:让重复操作自动化的效率工具指南

KeymouseGo&#xff1a;让重复操作自动化的效率工具指南 【免费下载链接】KeymouseGo 类似按键精灵的鼠标键盘录制和自动化操作 模拟点击和键入 | automate mouse clicks and keyboard input 项目地址: https://gitcode.com/gh_mirrors/ke/KeymouseGo 在数字化工作环境中…...

提升 10 倍的学习效率,这款浏览器必装的AI插件为什么火了?

花了3 周时间写了一个浏览器插件&#xff0c;一个月陆陆续续下载量破 1000 啦 安装链接 为什么要做这个项目&#xff1f; 一开始我入门学习 langchain 大模型agent开发&#xff0c;在之前我不懂的问题需要在 google 上搜索非常多的资料 融会贯通以后才能得到答案&#xff0…...

大学物理电磁场公式

1,毕奥-萨伐尔定律 2,安培定律(电流连续性) 3,库伦定律 如果两个电荷电量为q1和q2,距离为r,它们受到相互间作用力F 同种电荷互相吸引,不同电荷相互排斥; 电荷作用力大小与电荷大小成正比,与距离平方成反比; 作用力方向与电荷连线方向相反或一致 4,法拉第定律 5…...

linux下的spi子系统

概念通信模式可以分为单工、半双工和全双工&#xff0c;单工通信指信号只在一个方向上传输&#xff0c;仅 能发送或接收&#xff0c;而半双工通信指信号可以在俩个方向上传输&#xff0c;但某一个时刻只允许发送或接收&#xff0c;而全双工通信指数据同时在俩个方向上传输&…...

Qt VS Tools配置全攻略:从安装到解决‘No Qt version assigned‘错误

Qt开发环境配置实战&#xff1a;从工具链搭建到疑难解析 Visual Studio作为主流的集成开发环境&#xff0c;与Qt框架的结合为C开发者提供了强大的生产力工具组合。但在实际项目配置过程中&#xff0c;"No Qt version assigned"这类基础错误却频繁困扰着开发者。本文…...

Unity 2022.3 项目里用MQTTnet 4.3.7,手把手教你从下载dll到跑通第一个订阅消息

Unity 2022.3 项目里用MQTTnet 4.3.7&#xff0c;手把手教你从下载dll到跑通第一个订阅消息 在物联网和实时数据通信领域&#xff0c;MQTT协议因其轻量级和高效性成为开发者首选。对于Unity开发者而言&#xff0c;如何在项目中快速集成MQTT功能是一个常见需求。本文将带你从零…...