使用 Spring Boot 快速构建企业微信 JS-SDK 权限签名后端服务

使用 Spring Boot 快速构建企业微信 JS-SDK 权限签名后端服务

本篇文章将介绍如何使用 Spring Boot 快速构建一个用于支持企业微信 JS-SDK 权限校验的后端接口,并提供一个简单的 HTML 页面进行功能测试。适用于需要在企业微信网页端使用扫一扫、定位、录音等接口的场景。


一、项目目标

我们希望实现一个包含以下功能的服务:

  • 提供获取企业微信 access_token 的接口
  • 提供获取部门成员信息的接口(需要带 token)
  • 提供 JS-SDK 前端初始化所需签名参数的接口(wx.config() 配置)
  • 提供一个前端页面用于测试扫码、定位、数据表格展示等功能

二、开发环境与依赖

  • JDK 17
  • IDEA
  • Spring Boot 3.2.5
  • Maven 3.x

三、项目结构

DemoAPI
├── pom.xml                       		  // 项目依赖配置
├── src
│   └── main
│       ├── java
│       │   └── org.example
│       │       ├── Main.java             // 项目启动类
│       │       ├── WeComController.java  // 控制器:处理请求
│       │       └── WeComService.java     // 服务类:处理逻辑
│       └── resources
│           └── static
│               └── index.html            // 测试前端页面

说明: 本项目未配置 application.yml,Spring Boot 默认即可运行。


四、完整功能实现

第一步:修改 pom.xml,添加 Spring Boot 配置

pom.xml 中我们引入了:

<dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-devtools</artifactId><scope>runtime</scope></dependency>
</dependencies>

可能遇到的问题:

  • 依赖下载失败,可通过加速器优化下载速度。
  • 注意 Spring Boot 3.x 要使用 JDK 17+。

第二步:刷新依赖

你可以点击 IntelliJ 右侧 “Maven” 工具窗口的刷新按钮(🔄),或者右键 pom.xml → Add as Maven Project,IDE 会自动下载 Spring Boot 依赖。

第三步:修改你的 Main.java,变成 Spring Boot 启动类

package org.example;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplication
public class Main {public static void main(String[] args) {SpringApplication.run(Main.class, args);}
}

问题回顾: 如果你忘记添加 @SpringBootApplication,将导致 ApplicationContext 启动失败,同时控制台可能提示找不到 Web 容器类(如 Tomcat)或无法创建 Controller Bean。解决办法:确保注解已加。

第四步:创建一个服务类 WeComService.java

提供 access_token 缓存获取、jsapi_ticket 缓存、JS-SDK 签名生成逻辑:

String raw = String.format("jsapi_ticket=%s&noncestr=%s&timestamp=%d&url=%s",jsapiTicket, nonceStr, timestamp, url);MessageDigest md = MessageDigest.getInstance("SHA-1");
md.update(raw.getBytes(StandardCharsets.UTF_8));

注意:

  • 签名计算必须严格按参数顺序和格式
  • access_tokenjsapi_ticket 建议缓存,避免频繁请求
  • 返回格式需包括 appIdtimestampnonceStrsignature

JS-SDK 参数生成

  • 参数组成:jsapi_ticketnonceStrtimestampurl
  • 算法:SHA-1(raw字符串) 生成签名
  • 返回结构:包含 appIdtimestampnonceStrsignature

第五步:控制器类 WeComController.java

提供如下接口:

接口地址请求方法功能描述
/wecom/tokenGET获取 access_token
/wecom/department/usersGET获取指定部门的成员列表
/wecom/js-sdk-configGET获取 JS-SDK 初始化配置信息

常见问题:

  • 若自动注入失败,请确认 @Service@RestController 注解是否添加
  • 如果依赖注入失败,控制台会提示 UnsatisfiedDependencyException

第六步:创建前端测试页面 index.html

功能:

  • 获取 Token 并展示
  • 获取部门成员并展示表格(含滚动条)
  • 初始化 JS SDK,支持扫码、定位等测试按钮
wx.config({appId: config.appId,timestamp: config.timestamp,nonceStr: config.nonceStr,signature: config.signature,jsApiList: ["scanQRCode", "getLocation"]
});wx.ready(function() {alert("✅ 企业微信 JS SDK 初始化成功");
});

失败处理:

wx.error(function (err) {alert("❌ SDK 初始化失败: " + JSON.stringify(err));
});

页面结构清晰,所有逻辑通过 window.onload 初始化即可。

第七步:运行你的 Spring Boot 应用

在 IntelliJ 中右键 Main.java → Run ‘Main’,或点击绿色的 ▶ 按钮。

看到类似:

Tomcat started on port(s): 8080
Started Main in x.xxx seconds

说明服务已成功启动。

第八步:界面展示

http://localhost:8080/index.html

在这里插入图片描述

运行 & 测试(可选)

启动 Spring Boot 项目后,浏览器访问可访问下面的接口:

http://localhost:8080/wecom/token
http://localhost:8080/wecom/department/users?id=1


六、常见问题总结

问题说明解决办法
SDK 初始化失败签名无效、时间戳不一致等保证 URL 不带 #,参数顺序正确
Bean 注入失败启动报错找不到 Controller Bean检查是否缺少 @SpringBootApplication@Service 注解
依赖无法拉取Maven 仓库连接慢配置阿里云镜像源,提高稳定性
HTML 无法访问资源路径未设置正确放到 resources/static/ 下由 Spring Boot 自动映射

❌ 错误核心提示:

APPLICATION FAILED TO STARTWeb application could not be started as there was no
org.springframework.boot.web.servlet.server.ServletWebServerFactory bean defined in the context.

原因解释:Spring Boot 应用是一个 Web 项目,但 缺少内嵌 Servlet 容器(比如 Tomcat)依赖,也就是没有 ServletWebServerFactory,Spring Boot 启动 Web 服务失败。

最常见的原因:

  • pom.xml 中 缺失或拼错了 spring-boot-starter-web 依赖
  • Maven 没有下载成功依赖(网络或仓库问题)
  • 没有添加 @SpringBootApplication

七、后续可扩展方向

  • 接入企业微信身份认证(OAuth2)
  • 支持更多 JS API(如录音、语音识别、打开地图)
  • 使用 Redis 缓存 token,提升性能与健壮性
  • 前后端分离,使用 Vue、React 等框架

八、结语

通过本项目我们实现了从零搭建一个企业微信 JS-SDK 权限校验服务,具备了完整的后端支持和前端测试页面。如果想正常使用企业微信的扫描等功能需要在企业微信内部访问,那么就需要设置 IP 白名单、域名、网页授权及JS-SDK、企业微信授权登录和应用主页等。


九、推荐

Maven Central(Maven 中央仓库 Web 版)

这是最常用、几乎所有 Java 开发者都会用的网站 —— 一个图形化的 Maven 中央仓库检索平台:

👉 网站地址:
🌐 https://mvnrepository.com

使用 Spring Initializr 官网 创建项目(图形化窗口版)

这个网站会自动帮你生成一个可运行的 Spring Boot 项目,并打包成一个 zip 文件。解压 zip,然后用 IDEA 打开即可。

👉 地址:
🌐 https://start.spring.io


附录:完整文件(可自行补全代码)

pom.xml ✅

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>org.example</groupId><artifactId>DemoAPI</artifactId><version>1.0-SNAPSHOT</version><packaging>jar</packaging><!-- Spring Boot 父项目 --><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>3.2.5</version><relativePath/></parent><properties><maven.compiler.source>17</maven.compiler.source><maven.compiler.target>17</maven.compiler.target><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding></properties><dependencies><!-- Spring Boot Web 模块(包含内嵌 Tomcat) --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!-- 开发工具(自动重启,非必须) --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-devtools</artifactId><scope>runtime</scope></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build>
</project>

index.html ✅

<!DOCTYPE html>
<html lang="zh">
<head><meta charset="UTF-8"><title>企业微信接口测试</title><style>body {font-family: "微软雅黑", sans-serif;margin: 20px;}table {border-collapse: collapse;width: 100%;margin-top: 10px;}th, td {border: 1px solid #ccc;padding: 6px 12px;text-align: center;}th {background-color: #f5f5f5;}pre {background-color: #eee;padding: 10px;}.scroll-box {max-height: 160px;overflow-y: auto;border: 1px solid #ccc;}</style><!-- 引入企业微信 JS SDK --><script src="https://res.wx.qq.com/open/js/jweixin-1.2.0.js"></script><script>// 初始化企业微信 JS SDKasync function initWeComJsSdk() {const url = window.location.href.split('#')[0];const res = await fetch('/wecom/js-sdk-config?url=' + encodeURIComponent(url));const config = await res.json();wx.config({beta: true,debug: false,appId: config.appId,timestamp: config.timestamp,nonceStr: config.nonceStr,signature: config.signature,jsApiList: ["scanQRCode", "getLocation"]});wx.ready(function () {console.log("企业微信 JS SDK 就绪");alert("✅ 企业微信 JS SDK 初始化成功!");document.getElementById('scanBtn').onclick = function () {wx.scanQRCode({needResult: 1,scanType: ["qrCode", "barCode"],success: function (res) {alert("扫码结果:" + res.resultStr);}});};document.getElementById('locBtn').onclick = function () {wx.getLocation({type: 'wgs84',success: function (res) {alert("当前位置:经度 " + res.longitude + ",纬度 " + res.latitude);}});};});wx.error(function (err) {console.error("JS SDK 初始化失败:", err);alert("❌ 企业微信 JS SDK 初始化失败!\n" + JSON.stringify(err));});}async function getToken() {const res = await fetch('/wecom/token');const token = await res.text();document.getElementById('token').innerText = token;}async function getUsers() {const deptId = document.getElementById('dept').value || '1';const res = await fetch(`/wecom/department/users?id=${deptId}`);const json = await res.json();document.getElementById('result').innerText = JSON.stringify(json, null, 2);if (json.userlist) {renderTable(json.userlist);} else {document.getElementById('userTableBody').innerHTML = "<tr><td colspan='6'>无成员数据</td></tr>";}}function renderTable(users) {const tbody = document.getElementById("userTableBody");tbody.innerHTML = "";users.forEach(user => {const row = document.createElement("tr");row.innerHTML = `<td>${user.name}</td><td>${user.userid}</td><td>${(user.department || []).join(',')}</td><td>${user.isleader === 1 ? '是' : '否'}</td><td>${translateStatus(user.status)}</td><td>${user.telephone || ''}</td>`;tbody.appendChild(row);});}function translateStatus(status) {switch (status) {case 1: return "正常";case 2: return "已禁用";case 4: return "未激活";default: return "未知";}}window.onload = function () {initWeComJsSdk();};</script>
</head>
<body><h1>企业微信接口测试</h1><!-- 获取 Token -->
<button onclick="getToken()">获取 Token</button>
<p>Token:<code id="token">(点击上面按钮)</code></p><!-- 获取部门成员 -->
<hr>
<label>部门 ID:</label>
<input type="text" id="dept" value="1">
<button onclick="getUsers()">获取部门成员</button><!-- 显示返回数据 -->
<h3>接口返回数据:</h3>
<pre id="result">(点击按钮查看 JSON)</pre><!-- 成员列表表格 -->
<h3>成员列表表格:</h3>
<div class="scroll-box"><table><thead><tr><th>姓名</th><th>用户ID</th><th>部门</th><th>是否领导</th><th>状态</th><th>座机</th></tr></thead><tbody id="userTableBody"></tbody></table>
</div><!-- 企业微信 JS API 按钮 -->
<h3>企业微信功能测试:</h3>
<button id="scanBtn">扫一扫</button>
<button id="locBtn">获取当前位置</button></body>
</html>

Main.java ✅

package org.example;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;/*** ==================================================* This class ${NAME} is responsible for [功能描述].** @author Darker* @version 1.0* ==================================================*/@SpringBootApplication
public class Main {public static void main(String[] args) {SpringApplication.run(Main.class, args);}
}

WeComService.java ✅

package org.example;import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.util.UriComponentsBuilder;
import org.springframework.http.ResponseEntity;import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.util.Formatter;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;import java.time.Instant;/*** ==================================================* This class WeComService is responsible for [功能描述].** @author Darker* @version 1.0* ==================================================*/@Service
public class WeComService {private static final String CORP_ID = "你的企业微信ID";private static final String SECRET = "你的自建应用的Secret";private static final String TOKEN_URL = "https://qyapi.weixin.qq.com/cgi-bin/gettoken";private String accessToken;private long expireTime = 0;// jsapi_ticket(缓存 2 小时)private String jsapiTicket;private long ticketExpire = 0;public String getAccessToken() {long now = Instant.now().getEpochSecond();if (accessToken != null && now < expireTime) {return accessToken;}// 请求新的 tokenRestTemplate restTemplate = new RestTemplate();UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(TOKEN_URL).queryParam("corpid", CORP_ID).queryParam("corpsecret", SECRET);ResponseEntity<WeComTokenResponse> response = restTemplate.getForEntity(builder.toUriString(), WeComTokenResponse.class);WeComTokenResponse body = response.getBody();if (body != null && body.getAccess_token() != null) {this.accessToken = body.getAccess_token();this.expireTime = now + body.getExpires_in() - 60; // 提前60秒过期return accessToken;}throw new RuntimeException("无法获取 access_token");}public Map<String, Object> getJsSdkConfig(String url) {String jsapiTicket = getJsApiTicket(); // 用下面方法实现String nonceStr = UUID.randomUUID().toString().replace("-", "");long timestamp = System.currentTimeMillis() / 1000;String raw = String.format("jsapi_ticket=%s&noncestr=%s&timestamp=%d&url=%s",jsapiTicket, nonceStr, timestamp, url);String signature;try {MessageDigest md = MessageDigest.getInstance("SHA-1");md.update(raw.getBytes(StandardCharsets.UTF_8));signature = bytesToHex(md.digest());} catch (Exception e) {throw new RuntimeException("签名失败", e);}Map<String, Object> result = new HashMap<>();result.put("appId", CORP_ID);result.put("timestamp", timestamp);result.put("nonceStr", nonceStr);result.put("signature", signature);return result;}private String bytesToHex(byte[] bytes) {Formatter formatter = new Formatter();for (byte b : bytes) {formatter.format("%02x", b);}String result = formatter.toString();formatter.close();return result;}public String getJsApiTicket() {long now = System.currentTimeMillis() / 1000;if (jsapiTicket != null && now < ticketExpire) {return jsapiTicket;}String token = getAccessToken();String url = "https://qyapi.weixin.qq.com/cgi-bin/get_jsapi_ticket?access_token=" + token;RestTemplate restTemplate = new RestTemplate();Map<String, Object> res = restTemplate.getForObject(url, Map.class);if (res != null && res.get("ticket") != null) {jsapiTicket = (String) res.get("ticket");ticketExpire = now + ((Integer) res.get("expires_in")) - 60;return jsapiTicket;}throw new RuntimeException("获取 jsapi_ticket 失败");}// 内部类用于接收 JSON 响应public static class WeComTokenResponse {private String access_token;private int expires_in;public String getAccess_token() {return access_token;}public void setAccess_token(String access_token) {this.access_token = access_token;}public int getExpires_in() {return expires_in;}public void setExpires_in(int expires_in) {this.expires_in = expires_in;}}
}

WeComController.java ✅

package org.example;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;
import org.springframework.http.ResponseEntity;
import org.springframework.web.util.UriComponentsBuilder;/*** ==================================================* This class WeComController is responsible for [功能描述].** @author Darker* @version 1.0* ==================================================*/@RestController
@RequestMapping("/wecom")
public class WeComController {@Autowiredprivate WeComService weComService;// GET 接口:/wecom/token@GetMapping("/token")public String getToken() {return weComService.getAccessToken();}@GetMapping("/department/users")public Object getDepartmentUsers(@RequestParam("id") String departmentId) {String token = weComService.getAccessToken();String url = "https://qyapi.weixin.qq.com/cgi-bin/user/list";UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(url).queryParam("access_token", token).queryParam("department_id", departmentId);RestTemplate restTemplate = new RestTemplate();ResponseEntity<Object> response = restTemplate.getForEntity(builder.toUriString(), Object.class);return response.getBody();}// GET 接口:/wecom/js-sdk-config?url=xxx@GetMapping("/js-sdk-config")public Object getJsSdkConfig(@RequestParam("url") String url) {return weComService.getJsSdkConfig(url);}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/77204.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

工程师 - FTDI SPI converter

中国网站&#xff1a;FTDIChip- 首页 UMFT4222EV-D UMFT4222EV-D - FTDI 可以下载Datasheet。 UMFT4222EVUSB2.0 to QuadSPI/I2C Bridge Development Module Future Technology Devices International Ltd. The UMFT4222EV is a development module which uses FTDI’s FT4222H…

rcore day6

批处理系统 (Batch System) 出现于计算资源匮乏的年代&#xff0c;其核心思想是&#xff1a; 将多个程序打包到一起输入计算机&#xff1b;当一个程序运行结束后&#xff0c;计算机会 自动 执行下一个程序 应用程序难免会出错&#xff0c;如果一个程序的错误导致整个操作系统都…

Linux系统学习Day2——在Linux系统中开发OpenCV

一、OpenCV简介 OpenCV&#xff08;Open Source Computer Vision Library&#xff09;是一个开源的跨平台计算机视觉和机器学习库&#xff0c;广泛应用于图像处理、视频分析、物体检测等领域。它提供了丰富的算法和高效的工具集&#xff0c;支持C、Python等多种语言&#xff0c…

SAP Overview

SAP—企业运营的数字化引擎 在数字化转型的浪潮中&#xff0c;SAP以其全面的企业应用软件套件&#xff0c;为全球企业提供了强大的运营支持。SAP的模块化解决方案覆盖了企业运作的每一个关键环节&#xff0c;从销售到仓库管理&#xff0c;每个模块都是针对特定业务需求精心设计…

Kafka 中的幂等机制

Kafka 中的 幂等性&#xff08;Idempotence&#xff09; 是生产者端的重要机制&#xff0c;旨在确保即使在网络抖动、重试、Broker 重启等情况下&#xff0c;同一条消息不会被重复写入到 Topic 中。这是实现可靠消息传递、避免重复消费的关键手段之一。 ✅ 什么是幂等性&#…

用c语言写一个linux进程之间通信(聊天)的简单程序

使用talk 用户在同一台机器上talk指令格式如下&#xff1a; ​ talk 用户名ip地址 [用户终端号] 如果用户只登录了一个终端&#xff0c;那么可以不写用户终端号&#xff0c;如&#xff1a; talk userlocalhost可以使用who指令来查看当前有哪些用户登录&#xff0c;他的终端号…

深入探索Scala:从基础到进阶的全面总结

在大数据技术领域&#xff0c;Scala语言凭借其独特优势占据重要地位。它与Spark紧密相连&#xff0c;为大数据计算提供强大支持。今天&#xff0c;让我们一同深入回顾Scala从基础到进阶的关键知识点。 Scala开发环境搭建是入门的第一步&#xff0c;需确保JDK安装成功&#xff0…

【每日一个知识点】分布式数据湖与实时计算

在现代数据架构中&#xff0c;分布式数据湖&#xff08;Distributed Data Lake&#xff09; 结合 实时计算&#xff08;Real-time Computing&#xff09; 已成为大数据处理的核心模式。数据湖用于存储海量的结构化和非结构化数据&#xff0c;而实时计算则确保数据能够被迅速处理…

GPT-5、o3和o4-mini即将到来

原计划有所变更: 关于我们应有何期待的一些零散想法。 深度研究(Deep Research)确实强大但成本高昂且速度较慢(当前使用o3模型)。即将推出的o4-mini在性能上可能与o3相近,但将突破这些限制,让全球用户——甚至免费用户(尽管会有速率限制)——都能用上世界顶级AI研究助…

Spring Cloud LoadBalancer负载均衡+算法切换

目录 介绍核心功能负载均衡启动两个支付服务订单模块引入依赖LoadBalanced 注解启动订单服务测试结果 负载均衡算法切换总结 介绍 Spring Cloud LoadBalancer 是 Spring Cloud 提供的客户端负载均衡解决方案&#xff0c;提供更现代化的 API 和更好的 Spring 生态系统集成。它支…

Chrome 浏览器插件收录

1. Responsive Viewer 可以在同个窗口内&#xff0c;针对同一网站&#xff0c;添加多个不同设备屏幕显示。 在前端开发&#xff0c;需要多端适配&#xff0c;尤其是移动端响应式适配的网站开发中&#xff0c;可以同时测试多个不同屏幕的适配效果。 2. VisBug 提供工具栏&#x…

SQL 函数概述

SQL 函数概述 SQL 函数可以分为几大类&#xff0c;不同数据库系统可能有略微不同的实现。以下是主要的 SQL 函数分类&#xff1a; 1. 聚合函数 (Aggregate Functions) COUNT() - 计算行数 SUM() - 计算总和 AVG() - 计算平均值 MIN() - 找最小值 MAX() - 找最大值 GROUP…

MySQL学习笔记九

第十一章使用数据处理函数 11.1函数 SQL支持函数来处理数据但是函数的可移植性没有SQL强。 11.2使用函数 11.2.1文本处理函数 输入&#xff1a; SELECT vend_name,UPPER(vend_name) AS vend_name_upcase FROM vendors ORDER BY vend_name; 输出&#xff1a; 说明&#…

认识vue中的install和使用场景

写在前面 install 在实际开发中如果你只是一个简单的业务实现者&#xff0c;那么大部分时间你是用不到install的&#xff0c;因为你用到的基本上都是别人封装好的插件、组件、方法、指令等等&#xff0c;但是如果你需要给公司的架构做建设&#xff0c;install就是你避不开的一个…

【SpringCloud】构建分布式系统的利器

一、引言 在当今数字化时代&#xff0c;随着业务规模的不断扩大和用户量的急剧增长&#xff0c;单体应用逐渐暴露出诸多局限性&#xff0c;如可扩展性差、维护困难等。分布式系统应运而生&#xff0c;而 Spring Cloud 则成为了构建分布式系统的热门框架之一。它提供了一系列丰…

mkdir通配符详解

在 mkdir 命令中使用通配符可以简化批量创建目录的操作。通配符如 {} 和 * 可以用来生成多个目录名称&#xff0c;从而减少重复输入。以下是一些常见的使用方法和示例。 使用 {} 通配符 {} 通配符可以用来生成一系列的目录名称&#xff0c;语法如下&#xff1a; mkdir dir_{…

Transformer的Word Embedding

一、Transformer 中的词嵌入是什么&#xff1f; 1. 定义与作用 • 词嵌入&#xff08;Word Embedding&#xff09;&#xff1a;将离散的词语映射为低维连续向量&#xff0c;捕捉语义和语法信息。 • 在 Transformer 中的位置&#xff1a; • 输入层&#xff1a;每个词通过嵌入…

Linux 进程间通信:信号机制

Linux 进程间通信&#xff1a;信号机制 在多进程操作系统中&#xff0c;进程之间的通信至关重要&#xff0c;尤其是在Linux系统中&#xff0c;信号&#xff08;Signal&#xff09;作为一种特殊的进程间通信方式&#xff0c;广泛用于进程之间的协调和控制。信号可以看作是操作系…

基于TRIZ创新方法论的九屏法分析系统

1. 文件头与库导入 # -*- coding: utf-8 -*- import streamlit as st import pandas as pd import numpy as np import plotly.graph_objects as go from datetime import datetime from sklearn.ensemble import RandomForestRegressor ​​作用​​&#xff1a;设置文件编码…

【LangChain框架组成】 LangChain 技术栈的模块化架构解析

目录 整体架构概述 整体架构层级划分 模块详细解析 1. 部署与服务层&#xff08;LangServe & Deployments&#xff09; 2. 应用模板层&#xff08;Templates & Committee Architectures&#xff09; 3. 核心功能层&#xff08;LangChain&#xff09; 4. 社区扩展…