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

web人脸登录

1,需要腾讯人脸第三方
腾讯人脸第三方申请步骤
2,相关表结构设计

create database faceDB;use faceDB;
-- 人脸表
create table face(
fid int primary key auto_increment COMMENT '主键',
face_base longtext COMMENT '图片数据 base_64编码',
create_time datetime COMMENT '插入时间',
vef_num int COMMENT '验证次数',
face_name varchar(100) COMMENT '人脸名称',
remark varchar(200) COMMENT '人脸备注',
face_status int COMMENT '人脸是否可用,(0==可用,1,不可用)',
update_extend1 varchar(300) COMMENT '扩展字段1',
update_extend2 varchar(300) COMMENT '扩展字段2',
update_extend3 varchar(300) COMMENT '扩展字段3'
);
-- 验证日志表
create table face_vef_log(
lid int primary key auto_increment COMMENT '主键',
vef_time datetime COMMENT '验证时间',
vef_code int COMMENT '返回code',
vef_msg varchar(200) COMMENT '返回的消息',
login_name varchar(100) COMMENT '验证人'
);

3,相关配置

tencentcloudapi:# 你的 secretIdsecretId: 你腾讯云的secretId# 你的 secretKeysecretKey: 你腾讯云的secretKey# 请求官方地址 不变endpoint: iai.tencentcloudapi.com#地域 可不变region: ap-shanghai
package com.face.config;import com.auth0.jwt.exceptions.AlgorithmMismatchException;
import com.auth0.jwt.exceptions.SignatureVerificationException;
import com.auth0.jwt.exceptions.TokenExpiredException;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.face.utils.JwtUtils;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.Map;/*** @author tanyongpeng* <p>des</p>**/
@Component
@Slf4j
public class FaceConfig implements HandlerInterceptor {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {String face_token = request.getHeader("face_token");Map<String,Object> infoMap = new HashMap<>();try{//token验证DecodedJWT tokenInfo = JwtUtils.getTokenInfo(face_token);//添加返回信息infoMap.put("msg","验证成功");return true;}catch (SignatureVerificationException e){e.printStackTrace();infoMap.put("msg","无效签名");}catch (TokenExpiredException e){infoMap.put("msg","token已过期");}catch (AlgorithmMismatchException e){infoMap.put("msg","算法不一致");}catch (Exception e){infoMap.put("msg","无效签名");}ObjectMapper objectMapper = new ObjectMapper();String mapInfoJson = objectMapper.writeValueAsString(infoMap);response.setContentType("application/json;charset=UTF-8");response.setCharacterEncoding("UTF-8");PrintWriter writer = response.getWriter();writer.write(mapInfoJson);return false;}
}
package com.face.server;import com.face.bean.result.FaceResult;
import com.face.utils.TimeUtils;
import com.tencentcloudapi.common.Credential;
import com.tencentcloudapi.common.exception.TencentCloudSDKException;
import com.tencentcloudapi.common.profile.ClientProfile;
import com.tencentcloudapi.common.profile.HttpProfile;
import com.tencentcloudapi.iai.v20180301.IaiClient;
import com.tencentcloudapi.iai.v20180301.models.CompareFaceRequest;
import com.tencentcloudapi.iai.v20180301.models.CompareFaceResponse;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;import java.util.HashMap;
import java.util.Map;/*** @author tanyongpeng* <p>调用腾讯接口</p>**/
@Component
@Data
@Slf4j
public class FaceContrastServer {@Value("${tencentcloudapi.secretId}")private String secretId;@Value("${tencentcloudapi.secretKey}")private String secretKey;@Value("${tencentcloudapi.endpoint}")private String endpoint;@Value("${tencentcloudapi.region}")private String region;//第一张是数据库图片,第二张是登录时验证图片public FaceResult faceContrast(String imageA, String imageB){FaceResult faceResult = new FaceResult();try{Credential cred = new Credential(secretId, secretKey);HttpProfile httpProfile = new HttpProfile();httpProfile.setEndpoint(endpoint);ClientProfile clientProfile = new ClientProfile();clientProfile.setHttpProfile(httpProfile);IaiClient client = new IaiClient(cred, region, clientProfile);CompareFaceRequest req = new CompareFaceRequest();req.setImageA(imageA);req.setImageB(imageB);CompareFaceResponse resp = client.CompareFace(req);faceResult.setScore(resp.getScore());faceResult.setCode(FaceResult.SUCCESS_CODE);} catch (TencentCloudSDKException e) {faceResult.setCode(FaceResult.FACE_ERROR);faceResult.setMsg(e.getMessage());}return faceResult;}
}

4,人脸注册,登录后端代码

package com.face.service.impl;import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;import com.face.bean.Face;
import com.face.bean.result.FaceResult;
import com.face.mapper.FaceMapper;
import com.face.server.FaceContrastServer;
import com.face.service.FaceService;
import com.face.utils.JwtUtils;
import com.face.utils.TimeUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;/**
* @author typsusan
* @description 针对表【face】的数据库操作Service实现
* @createDate 2022-07-17 03:33:50
*/
@Service
public class FaceServiceImpl extends ServiceImpl<FaceMapper, Face>implements FaceService {@AutowiredFaceContrastServer faceContrastServer;@Overridepublic FaceResult vef(String imageBase) {imageBase = JSONUtil.parseObj(imageBase).getStr("imageBase");List<Face> faceList = lambdaQuery().orderByDesc(Face::getVefNum).list();FaceResult faceState = null;// 如果人脸库为空,则第一次登录为录入人脸if (faceList.size() == 0){return initFace(imageBase);}else {int faceLength = faceList.size();for (Face face : faceList) {FaceResult faceResult = faceContrastServer.faceContrast(face.getFaceBase(), imageBase);// 是否比对成功if (faceResult.getCode() == FaceResult.SUCCESS_CODE ){// 相似度是否大于80if (faceResult.getScore() > FaceResult.SATISFY_SCORE){if (face.getFaceStatus() == 0){// 成功lambdaUpdate().set(Face::getVefNum,face.getVefNum()+1).eq(Face::getFid,face.getFid()).update();faceResult.setMsg(TimeUtils.timeQuantum()+"好,"+face.getFaceName());faceResult.setName(face.getFaceName());Map<String,String> map = new HashMap<>();map.put("score",String.valueOf(faceResult.getScore()));map.put("faceName",faceResult.getName());faceResult.setToken(JwtUtils.genereteToken(map));return faceResult;}else {// 失败 人脸被禁用lambdaUpdate().set(Face::getVefNum,face.getVefNum()+1).eq(Face::getFid,face.getFid()).update();faceResult.setMsg(face.getFaceName()+",当前人脸被禁用");faceResult.setName(face.getFaceName());faceResult.setCode(FaceResult.FORBIDDEN_FACE);faceState = faceResult;// 就算上一张人脸被禁用还得往下执行// 可能当前用户存在多张人脸,if (faceLength == 1){return faceResult;}faceLength --;}}else {// 人脸库没有检测到人脸if (faceLength == 1){// 判断当前人脸是否被禁用,如被禁用,提示被禁用// 禁用优先级大于 没有检测到人脸return faceState != null?faceState:FaceResult.error(FaceResult.NOT_FOUND_FACE,"人脸库不存在该人脸",faceResult.getScore());}faceLength --;}}else {// 接口返回异常return faceResult;}}}// 空异常return FaceResult.error(FaceResult.NULL_ERROR,"空指针异常");}public FaceResult initFace(String imageBase){FaceResult faceResult = new FaceResult();Face face = new Face();face.setFaceBase(imageBase);face.setCreateTime(new Date());face.setVefNum(0);face.setFaceName("admin");face.setFaceStatus(0);boolean save = save(face);faceResult.setCode(FaceResult.INIT_FACE);faceResult.setMsg("人脸初始化"+(save?"成功":"失败")+","+(save?"请验证登录":"请稍后再试"));faceResult.setName(face.getFaceName());return faceResult;}
}

5,前端代码

/*** 获取 浏览器 拍照的权限*/
/*** 获取浏览器权限* @param option*/
function getCamera(option) {option.thisCancas = document.getElementById(option.canvasId);option.thisContext = option.thisCancas.getContext("2d");option.thisVideo = document.getElementById(option.videoId);option.thisVideo.style.display = "block";// 获取媒体属性,旧版本浏览器可能不支持mediaDevices,我们首先设置一个空对象if (navigator.mediaDevices === undefined) {navigator.mediaDevices = {};}// 一些浏览器实现了部分mediaDevices,我们不能只分配一个对象// 使用getUserMedia,因为它会覆盖现有的属性。// 这里,如果缺少getUserMedia属性,就添加它。if (navigator.mediaDevices.getUserMedia === undefined) {navigator.mediaDevices.getUserMedia = function (constraints) {// 首先获取现存的getUserMedia(如果存在)var getUserMedia =navigator.webkitGetUserMedia ||navigator.mozGetUserMedia ||navigator.getUserMedia;// 有些浏览器不支持,会返回错误信息// 保持接口一致if (!getUserMedia) {//不存在则报错return Promise.reject(new Error("getUserMedia is not implemented in this browser"));}// 否则,使用Promise将调用包装到旧的navigator.getUserMediareturn new Promise(function (resolve, reject) {getUserMedia.call(navigator, constraints, resolve, reject);});};}var constraints = {audio: false,video: {width: option.videoWidth,height: option.videoHeight,transform: "scaleX(-1)",},};navigator.mediaDevices.getUserMedia(constraints).then(function (stream) {// 旧的浏览器可能没有srcObjectif ("srcObject" in option.thisVideo) {option.thisVideo.srcObject = stream;} else {// 避免在新的浏览器中使用它,因为它正在被弃用。option.thisVideo.src = window.URL.createObjectURL(stream);}option.thisVideo.onloadedmetadata = function (e) {option.thisVideo.play();};}).catch((err) => {console.log(err);});return option
}/*** 绘制图片* 返回格式为base64* @param option*/
function draw(option){option.thisContext.drawImage(option.thisVideo,0,0,option.videoWidth,option.videoHeight);return option.thisCancas.toDataURL("image/png");
}export default {getCamera,draw
}
<template><div><div class="login"></div><!--登录中间块--><div class="login-mid"><div class="login-mid-top"><div class="shadow-top-left"></div><div class="shadow-top-right"></div></div><div class="login-mid-mid"><!--捕获人脸区域--><div class="videoCamera-canvasCamera"><videoid="videoCamera":width="videoWidth":height="videoHeight"autoplay></video><canvasstyle="display: none"id="canvasCamera":width="videoWidth":height="videoHeight"></canvas><!--人脸特效区域--><div v-if="faceImgState" class="face-special-effects-2"></div><div v-else class="face-special-effects"></div></div><!--按钮区域--><div class="face-btn"><button @click="faceVef()">{{faceImgState?'正在识别中...':'开始识别'}}</button></div><!--消息区域--><div class="msg"><div class="server-msg">{{msg}}</div><div class="welcome">Welcome to face recognition</div></div></div><div class="login-mid-bot"><div class="shadow-bot-left"></div><div class="shadow-bot-right"></div></div></div></div></template>
<script>
import $camera from '../../camera/index.js'
export default {data() {return {videoWidth: 200,videoHeight: 200,msg:'',faceImgState:false,faceOption:{}};},mounted() {//调用摄像头this.faceOption = $camera.getCamera({videoWidth: 200,videoHeight: 200,thisCancas: null,thisContext: null,thisVideo: null,canvasId:'canvasCamera',videoId:'videoCamera'});//this.getCompetence();},methods: {// 调用后台接口faceVef(){// 开始绘制图片let imageBase = $camera.draw(this.faceOption)if (this.faceImgState){return}this.faceImgState = trueif (imageBase === '' || imageBase === null || imageBase === undefined){this.$message.error("图片数据为空")}else {this.$http.post("/face/vef",{imageBase}).then(res =>{console.log(res)this.faceImgState = false// 跳转首页if (res.data.code === 200){// 关闭摄像头this.faceOption.thisVideo.srcObject.getTracks()[0].stop();localStorage.setItem("face_token",res.data.token);localStorage.setItem("username",res.data.name);this.$message.success(res.data.msg)this.$router.push("/home")}if (res.data.code === 201){this.$message.success(res.data.msg)}},onerror =>{this.faceImgState = false})}}},
};
</script>
<style>
@import "./index.css";
</style>

6,实现实例

参考:项目后端地址face-easy
参考:项目前端地址face-ui

相关文章:

web人脸登录

1&#xff0c;需要腾讯人脸第三方 腾讯人脸第三方申请步骤 2&#xff0c;相关表结构设计 create database faceDB;use faceDB; -- 人脸表 create table face( fid int primary key auto_increment COMMENT 主键, face_base longtext COMMENT 图片数据 base_64编码, create_tim…...

C++数字

目录 一、什么是数字 二、定义数字 三、数学运算 四、随机数 一、什么是数字 通常&#xff0c;当我们需要用到数字时&#xff0c;我们会使用原始的数据类型&#xff0c;如 int、short、long、float 和 double 等等。这些用于数字的数据类型&#xff0c;其可能的值和数值范围…...

【python】用plotly绘制正二十面体

文章目录顶点棱实现正二十面体plotly 的 Python 软件包是一个开源的代码库&#xff0c;它基于 plot.js&#xff0c;而后者基于 d3.js。我们实际使用的则是一个对 plotly 进行封装的库&#xff0c;名叫 cufflinks&#xff0c;能让你更方便地使用 plotly 和 Pandas 数据表协同工作…...

[Datawhale][CS224W]图机器学习(五)

这里写目录标题一、Deepwalk1.1 预备知识1.2 Deepwalk介绍1.3 Embedding1.4 word2Vec 词向量&#xff0c;词嵌入1.5 random Walk随机游走1.6 DeepWalk 核心代码Random WalkWord2vecDeepWalk应用1.7 DeepWalk优缺点二、Node2Vec2.1 图嵌入2.2 Node2Vec优化目标顶点序列采样策略2…...

Windows部署Jar包的三种方式

文章目录1、cmd命令启动2、bat脚本启动2.1 启动jar包2.2 关闭服务3、使用WinSW3.1 重命名3.2 xml配置3.3 安装服务3.4 卸载服务3.5 启动和停止服务1、cmd命令启动 这种方式比较简单&#xff0c;但是窗口关闭后服务也就被杀死了&#xff0c;命令如下 java -jar xxx.jar2、bat脚…...

【图像分类】卷积神经网络之AlexNet网络模型结构详解

写在前面: 首先感谢兄弟们的关注和订阅,让我有创作的动力,在创作过程我会尽最大能力,保证作品的质量,如果有问题,可以私信我,让我们携手共进,共创辉煌。 1. 前言 LeNet5网络模型提出之后,卷积神经网络在很长一段时间都没有长足的发展,主要有以下两个原因: 1.1 训…...

学习动漫插画的网络班排行榜

很多小伙伴不知道动漫插画培训机构哪个好&#xff0c;找不到靠谱的插画班&#xff0c;今天给大家整理了国内动漫插画培训机构排名&#xff01; 一&#xff1a;动漫插画培训机构排名 1、轻微课&#xff08;五颗星&#xff09; 主打课程有日系插画、游戏原画、古风插画、动漫漫画…...

SpringCloud第五讲 Nacos注册中心-服务注册到Nacos

1.引入依赖&#xff1a; 在父工程中添加spring-cloud-alibaba的管理依赖 <!-- Nacos的管理依赖--><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-alibaba-dependencies</artifactId><version…...

IP地理位置定位技术原理是什么

IP地理位置定位技术的原理是基于IP地址的网络通信原理和基础上的。它利用IP地址所包含的一些信息&#xff0c;如网络前缀和地址段&#xff0c;以及ISP的IP地址归属地数据库&#xff0c;来推测IP地址所对应的地理位置。具体来说&#xff0c;IP地址是由32位二进制数字组成的&…...

j-vxe-table 下拉搜索选择框数据加载过多导致前端崩溃问题

Jeeg-boot j-vxe-table 下拉搜索选择框数据加载过多导致前端崩溃问题 最近用到了Jeeg-boot j-vxe-table的组件&#xff0c;这组件时真J8难用&#xff0c;还好多BUG&#xff0c;想用个slot插槽也用不了&#xff0c;好像官方写了个基础就没怎么管了。&#x1f611; 问题&#xf…...

Java国际化ResourceBundle详解

在Java开发中&#xff0c;ResourceBundle是一种方便地管理本地化资源的机制。它可以使得程序能够根据当前系统环境的语言和国家/地区来自动加载相应的本地化资源文件&#xff0c;从而避免了硬编码和减少了重复的代码。以下是使用ResourceBundle的基本步骤&#xff1a; 1. 准备…...

一文高端Android性能优化-总结篇

以下从几个方面来总结一下Android的性能优化&#xff1a;1&#xff1a;界面卡顿优化2&#xff1a;内存优化3&#xff1a;App启动优化界面卡顿优化Android的界面为每秒60帧&#xff0c;即必须在16ms内完成1帧的绘制&#xff0c;如果某个方法耗时过程&#xff0c;导致16ms内无法完…...

深入讲解CFS组调度!(上)

注&#xff1a;本文缩写说明 一、CFS组调度简介 1.1. 存在的原因 总结来说是希望不同分组的任务在高负载下能分配可控比例的CPU资源。为什么会有这个需求呢&#xff0c;比如多用户计算机系统每个用户的所有任务划分到一个分组中&#xff0c;A用户90个相同任务&#xff0c;而B…...

大数据实操项目分享:餐饮智能推荐服务在线实习项目

项目背景&#xff1a;在“互联网"背景下&#xff0c;餐饮企业的经营方式发生了很大的变革&#xff1a;团购和020拓宽了销售 渠道&#xff0c;电子点餐、店内WIFI等信息技术提升了服务水平&#xff0c;大数据、私人定制更好地满足了细分市场的需求等。但是与此同时&#xf…...

代码随想录day38

动态规划五部曲 确定dp数组以及下标的含义确定递推公式dp数组如何初始化确定遍历顺序举例推导dp数组 509. 斐波那契数 https://leetcode.cn/problems/fibonacci-number/ class Solution {public int fib(int n) {if(n0) return 0;if(n<3) return 1;int[] dp new int[n]…...

《计算机网络:自顶向下方法》实验5:TCP

Q1 包含HTTP POST消息的TCP报文段的序号是多少?注意:为了发现POST 命令, 你需要在wireshark底部的报文内容域窗口中去查找,查找数据中包含 “POST”的段。 如图所示,由报文中的POST 和 HTTP/1.1可知,其包含HTTP POST消息; TCP报文段的序号可见TCP报文: Sequence Number:…...

【踩坑指南】Stable Diffusion 服务器端部署笔记

文章目录下载github文件配置环境ckpt文件权重下载生成图像NSFW检查&#xff08;瑟图过滤&#xff09;下载github文件 https://github.com/CompVis/stable-diffusion 这个网址&#xff0c;下载压缩包解压&#xff0c;也可以用git clone下载 配置环境 这一步坑最多&#xff0c…...

[qiankun]-多页签缓存

[qiankun]-多页签缓存环境功能需求多页签缓存方案方案1.主服务进行html替换方案2.微服务vnode 替换方案3.每个微服务都不卸载微服务加载方式的选择微服务的路由路径选择微服务的缓存工具微服务的容器使用tab作为微服务的挂载容器使用微服务路由作为微服务的挂载容器场景描述微服…...

2|电子技术|数字电子技术基础|雨课堂习题|考前回顾

A/DD/A转化横向与阵列 相乘&#xff0c;竖向为或阵列 相加&#xff01;功率放大电路克服交越失真&#xff0c;是在乙类的基础上增加两个二极管&#xff0c;使微导通&#xff0c;使三极管导通时间大于半个周期&#xff0c;小于一个周期&#xff0c;构成甲乙类工作状态。选择填空…...

vue+echarts:圆形柱状图设置角度和最大值

第020个点击查看专栏目录本示例是显示圆形的柱状图&#xff0c;angleAxis设置一个max&#xff0c; angleAxis上startAngle&#xff1a;90 &#xff0c; 将0点设置为最顶点。 文章目录示例效果示例源代码&#xff08;共100行&#xff09;相关资料参考专栏介绍示例效果 示例源代码…...

【JavaEE】-- HTTP

1. HTTP是什么&#xff1f; HTTP&#xff08;全称为"超文本传输协议"&#xff09;是一种应用非常广泛的应用层协议&#xff0c;HTTP是基于TCP协议的一种应用层协议。 应用层协议&#xff1a;是计算机网络协议栈中最高层的协议&#xff0c;它定义了运行在不同主机上…...

MySQL 隔离级别:脏读、幻读及不可重复读的原理与示例

一、MySQL 隔离级别 MySQL 提供了四种隔离级别,用于控制事务之间的并发访问以及数据的可见性,不同隔离级别对脏读、幻读、不可重复读这几种并发数据问题有着不同的处理方式,具体如下: 隔离级别脏读不可重复读幻读性能特点及锁机制读未提交(READ UNCOMMITTED)允许出现允许…...

Docker 运行 Kafka 带 SASL 认证教程

Docker 运行 Kafka 带 SASL 认证教程 Docker 运行 Kafka 带 SASL 认证教程一、说明二、环境准备三、编写 Docker Compose 和 jaas文件docker-compose.yml代码说明&#xff1a;server_jaas.conf 四、启动服务五、验证服务六、连接kafka服务七、总结 Docker 运行 Kafka 带 SASL 认…...

用docker来安装部署freeswitch记录

今天刚才测试一个callcenter的项目&#xff0c;所以尝试安装freeswitch 1、使用轩辕镜像 - 中国开发者首选的专业 Docker 镜像加速服务平台 编辑下面/etc/docker/daemon.json文件为 {"registry-mirrors": ["https://docker.xuanyuan.me"] }同时可以进入轩…...

AI病理诊断七剑下天山,医疗未来触手可及

一、病理诊断困局&#xff1a;刀尖上的医学艺术 1.1 金标准背后的隐痛 病理诊断被誉为"诊断的诊断"&#xff0c;医生需通过显微镜观察组织切片&#xff0c;在细胞迷宫中捕捉癌变信号。某省病理质控报告显示&#xff0c;基层医院误诊率达12%-15%&#xff0c;专家会诊…...

纯 Java 项目(非 SpringBoot)集成 Mybatis-Plus 和 Mybatis-Plus-Join

纯 Java 项目&#xff08;非 SpringBoot&#xff09;集成 Mybatis-Plus 和 Mybatis-Plus-Join 1、依赖1.1、依赖版本1.2、pom.xml 2、代码2.1、SqlSession 构造器2.2、MybatisPlus代码生成器2.3、获取 config.yml 配置2.3.1、config.yml2.3.2、项目配置类 2.4、ftl 模板2.4.1、…...

Kubernetes 节点自动伸缩(Cluster Autoscaler)原理与实践

在 Kubernetes 集群中&#xff0c;如何在保障应用高可用的同时有效地管理资源&#xff0c;一直是运维人员和开发者关注的重点。随着微服务架构的普及&#xff0c;集群内各个服务的负载波动日趋明显&#xff0c;传统的手动扩缩容方式已无法满足实时性和弹性需求。 Cluster Auto…...

DAY 26 函数专题1

函数定义与参数知识点回顾&#xff1a;1. 函数的定义2. 变量作用域&#xff1a;局部变量和全局变量3. 函数的参数类型&#xff1a;位置参数、默认参数、不定参数4. 传递参数的手段&#xff1a;关键词参数5 题目1&#xff1a;计算圆的面积 任务&#xff1a; 编写一…...

快速排序算法改进:随机快排-荷兰国旗划分详解

随机快速排序-荷兰国旗划分算法详解 一、基础知识回顾1.1 快速排序简介1.2 荷兰国旗问题 二、随机快排 - 荷兰国旗划分原理2.1 随机化枢轴选择2.2 荷兰国旗划分过程2.3 结合随机快排与荷兰国旗划分 三、代码实现3.1 Python实现3.2 Java实现3.3 C实现 四、性能分析4.1 时间复杂度…...

spring boot使用HttpServletResponse实现sse后端流式输出消息

1.以前只是看过SSE的相关文章&#xff0c;没有具体实践&#xff0c;这次接入AI大模型使用到了流式输出&#xff0c;涉及到给前端流式返回&#xff0c;所以记录一下。 2.resp要设置为text/event-stream resp.setContentType("text/event-stream"); resp.setCharacter…...