做善事的网站/外贸商城建站
这里记录回顾一些知识,不然就快忘记啦。
- 环境:SpringBoot 2.0.4.RELEASE
- 需求:很多Controller方法,刚进来要先获取当前登录用户的信息,以便做后续的用户相关操作。
- 准备工作:前端每次请求都传token,后端封装一方法tokenUtils.getUserByToken(token),根据token解析得到currentUserInfo。
这是一个常见的业务需求,为实现这个需求,有以下几种解决方案:
一、最原始直接
即,每个Controller开始,先调用tokenUtils.getUserByToken(token),不够优雅。
二、AOP
AOP可以解决很多切面类问题,思路同Spring AOP来自定义注解实现审计或日志记录,将currentUser放到request里;比起拦截器稍重。
三、拦截器+方法参数解析器
使用mvc拦截器HandlerInterceptor+方法参数解析器HandlerMethodArgumentResolver最合适。
SpringMVC提供了mvc拦截器HandlerInterceptor,包含以下3个方法:
- preHandle
- postHandle
- afterCompletion
HandlerInterceptor经常被用来解决拦截事件,如用户鉴权等。另外,Spring也向我们提供了多种解析器Resolver,如用来统一处理异常的HandlerExceptionResolver,以及今天的主角 HandlerMethodArgumentResolver。HandlerMethodArgumentResolver是用来处理方法参数的解析器,包含以下2个方法:
- supportsParameter(满足某种要求,返回true,方可进入resolveArgument做参数处理)
- resolveArgument
知识储备已到位,接下来着手实现,主要分为三步走:
1. 自定义权限拦截器AuthenticationInterceptor拦截所有request请求,并将token解析为currentUser,最终放到request中;
2. 自定义参数注解@CurrentUser,添加至controller的方法参数user之上;
3. 自定义方法参数解析器CurrentUserMethodArgumentResolver,取出request中的user,并赋值给添加了@CurrentUser注解的参数user。
使用方式
要使用 HandlerMethodArgumentResolver
,需要遵循以下步骤:
- 创建一个自定义的
HandlerMethodArgumentResolver
实现类。 - 在该类中实现
supportsParameter()
方法和resolveArgument()
方法。 - 在 Spring Boot 应用程序中注册该类。
创建自定义的 HandlerMethodArgumentResolver 实现类
为了将 HTTP 请求参数转换为 Java 对象,我们需要创建一个自定义的 HandlerMethodArgumentResolver
实现类。在这个类中,我们需要实现 supportsParameter()
方法和 resolveArgument()
方法。
supportsParameter() 方法
在 supportsParameter()
方法中,我们需要检查方法参数是否与我们要转换的 Java 类型相同。如果是,返回 true
,否则返回 false
。
resolveArgument() 方法
在 resolveArgument()
方法中,我们需要将 HTTP 请求参数转换为 Java 对象。为此,我们可以使用 NativeWebRequest
对象来获取请求参数,然后将其转换为 Java 对象。
注册自定义的 HandlerMethodArgumentResolver 实现类
要在 Spring Boot 应用程序中使用自定义的 HandlerMethodArgumentResolver
实现类,我们需要将其注册到应用程序上下文中。为此,我们可以创建一个 @Configuration
类,并实现 WebMvcConfigurer
接口。在这个类中,我们需要重写 addArgumentResolvers()
方法,并将自定义的 HandlerMethodArgumentResolver
实现类添加到参数解析器列表中。
@Configuration
public class AppConfig implements WebMvcConfigurer {
@Override
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {
resolvers.add(new CustomHandlerMethodArgumentResolver());
}
}
3.1 自定义权限拦截器
自定义权限拦截器AuthenticationInterceptor,需实现HandlerInterceptor。在preHandle中调用tokenUtils.getUserByToken(token),获取到当前用户,最后塞进request中,如下:
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;import edp.core.utils.TokenUtils;
import edp.davinci.core.common.Constants;
import edp.davinci.model.User;public class AuthenticationInterceptor implements HandlerInterceptor {@Autowiredprivate TokenUtils tokenUtils;@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {String token = request.getHeader("Authorization");User user = tokenUtils.getUserByToken(token);request.setAttribute(Constants.CURRENT_USER, user);return true;}@Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {}@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {}
}
3.2 自定义参数注解
自定义方法参数上使用的注解@CurrentUser,代表被它注解过的参数的值都需要由方法参数解析器CurrentUserMethodArgumentResolver来“注入”,如下:
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;/*** 自定义 当前用户 注解* 注解 参数* 此注解在验证token通过后,获取当前token包含用户*/
@Target({ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
public @interface CurrentUser {
}
3.3 自定义方法参数解析器
自定义方法参数解析器CurrentUserMethodArgumentResolver,需实现HandlerMethodArgumentResolver。
import org.springframework.core.MethodParameter; import org.springframework.web.bind.support.WebDataBinderFactory; import org.springframework.web.context.request.NativeWebRequest; import org.springframework.web.context.request.RequestAttributes; import org.springframework.web.method.support.HandlerMethodArgumentResolver; import org.springframework.web.method.support.ModelAndViewContainer;import edp.core.annotation.CurrentUser; import edp.core.consts.Consts; import edp.davinci.model.User;/*** @CurrentUser 注解 解析器*/ public class CurrentUserMethodArgumentResolver implements HandlerMethodArgumentResolver {@Overridepublic boolean supportsParameter(MethodParameter parameter) {return parameter.getParameterType().isAssignableFrom(User.class)&& parameter.hasParameterAnnotation(CurrentUser.class);}@Overridepublic Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) {return (User) webRequest.getAttribute(Consts.CURRENT_USER, RequestAttributes.SCOPE_REQUEST);} }As we all know,拦截器定义好以后,在SpringMVC项目中,需要去SpringMVC的配置文件springmvc.xml添加该拦截器;但是在SpringBoot中,省去了很多配置文件,取而代之的是被注解@Configuration标识的配置类,SpringMVC配置文件对应的配置类需继承WebMvcConfigurationSupport。同理,解析器定义好以后,也需被添加到SpringMVC的配置文件或配置类中。最后,额外的一步,配置mvc。
3.4 配置MVC
定义MVC配置类,需继承WebMvcConfigurationSupport。分别在addInterceptors和addArgumentResolvers方法中,添加自定义的拦截器和参数解析器,如下:
import static edp.core.consts.Consts.EMPTY;import java.math.BigInteger; import java.util.ArrayList; import java.util.List;import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.http.MediaType; import org.springframework.http.converter.HttpMessageConverter; import org.springframework.web.method.support.HandlerMethodArgumentResolver; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;import com.alibaba.fastjson.serializer.SerializerFeature; import com.alibaba.fastjson.serializer.ValueFilter; import com.alibaba.fastjson.support.config.FastJsonConfig; import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter;import edp.davinci.core.common.Constants; import edp.davinci.core.inteceptor.AuthenticationInterceptor; import edp.davinci.core.inteceptor.CurrentUserMethodArgumentResolver;@Configuration public class WebMvcConfig extends WebMvcConfigurationSupport {@Value("${file.userfiles-path}")private String filePath;/*** 登录校验拦截器** @return*/@Beanpublic AuthenticationInterceptor loginRequiredInterceptor() {return new AuthenticationInterceptor();}/*** CurrentUser 注解参数解析器** @return*/@Beanpublic CurrentUserMethodArgumentResolver currentUserMethodArgumentResolver() {return new CurrentUserMethodArgumentResolver();}/*** 参数解析器** @param argumentResolvers*/@Overrideprotected void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {argumentResolvers.add(currentUserMethodArgumentResolver());super.addArgumentResolvers(argumentResolvers);}@Overrideprotected void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(loginRequiredInterceptor()).addPathPatterns(Constants.BASE_API_PATH + "/**").excludePathPatterns(Constants.BASE_API_PATH + "/login");super.addInterceptors(registry);}@Overridepublic void addResourceHandlers(ResourceHandlerRegistry registry) {registry.addResourceHandler("/**").addResourceLocations("classpath:/META-INF/resources/").addResourceLocations("classpath:/static/page/").addResourceLocations("classpath:/static/templates/").addResourceLocations("file:" + filePath);}@Overrideprotected void configureMessageConverters(List<HttpMessageConverter<?>> converters) {FastJsonHttpMessageConverter fastConverter = new FastJsonHttpMessageConverter();FastJsonConfig fastJsonConfig = new FastJsonConfig();fastJsonConfig.setSerializerFeatures(SerializerFeature.QuoteFieldNames,SerializerFeature.WriteEnumUsingToString,SerializerFeature.WriteMapNullValue,SerializerFeature.WriteDateUseDateFormat,SerializerFeature.DisableCircularReferenceDetect);fastJsonConfig.setSerializeFilters((ValueFilter) (o, s, source) -> {if (null != source && (source instanceof Long || source instanceof BigInteger) && source.toString().length() > 15) {return source.toString();} else {return null == source ? EMPTY : source;}});//处理中文乱码问题List<MediaType> fastMediaTypes = new ArrayList<>();fastMediaTypes.add(MediaType.APPLICATION_JSON_UTF8);fastConverter.setSupportedMediaTypes(fastMediaTypes);fastConverter.setFastJsonConfig(fastJsonConfig);converters.add(fastConverter);} }
多个场景案例
以下是一些场景案例,演示了如何使用 HandlerMethodArgumentResolver
解析不同类型的请求参数。
将 JSON 请求体转换为 Java 对象
假设有一个 POST 请求,其中包含以下 JSON 请求体:
{ "name": "John", "age": 30}
我们可以创建一个自定义的 HandlerMethodArgumentResolver
实现类来将这些参数转换为 Java 对象。
public class JsonHandlerMethodArgumentResolver implements HandlerMethodArgumentResolver
{
@Override
public boolean supportsParameter(MethodParameter parameter)
{
return parameter.hasParameterAnnotation(RequestBody.class);
}
@Override
public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception
{
String json = webRequest.getNativeRequest(HttpServletRequest.class).getReader().lines().collect(Collectors.joining(System.lineSeparator()));
ObjectMapper mapper = new ObjectMapper();
return mapper.readValue(json, parameter.getParameterType());
}
}
在这个示例中,我们创建了一个名为 JsonHandlerMethodArgumentResolver
的自定义 HandlerMethodArgumentResolver
实现类,并在其中解析 JSON 请求体。在 supportsParameter()
方法中,我们检查方法参数是否带有 @RequestBody
注解。在 resolveArgument()
方法中,我们从请求体中读取 JSON 数据,并使用 ObjectMapper
将其转换为 Java 对象。
将 XML 请求体转换为 Java 对象
假设有一个 POST 请求,其中包含以下 XML 请求体:
<user> <name>John</name> <age>30</age></user>
我们可以创建一个自定义的 HandlerMethodArgumentResolver
实现类来将这些参数转换为 Java 对象。
public class XmlHandlerMethodArgumentResolver implements HandlerMethodArgumentResolver
{
@Override
public boolean supportsParameter(MethodParameter parameter) {
return parameter.hasParameterAnnotation(RequestBody.class);
}
@Override
public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception
{
String xml = webRequest.getNativeRequest(HttpServletRequest.class).getReader().lines().collect(Collectors.joining(System.lineSeparator()));
JAXBContext jaxbContext = JAXBContext.newInstance(parameter.getParameterType());
Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
StringReader reader = new StringReader(xml);
return unmarshaller.unmarshal(reader);
}
}
在这个示例中,我们创建了一个名为 XmlHandlerMethodArgumentResolver
的自定义 HandlerMethodArgumentResolver
实现类,并在其中解析 XML 请求体。在 supportsParameter()
方法中,我们检查方法参数是否带有 @RequestBody
注解。在 resolveArgument()
方法中,我们从请求体中读取 XML 数据,并使用 JAXBContext
和 Unmarshaller
将其转换为 Java 对象。
将多个请求参数转换为 Java 对象
假设有一个 GET 请求,其中包含以下请求参数:
name=John&age=30
我们可以创建一个自定义的 HandlerMethodArgumentResolver
实现类来将这些参数转换为 Java 对象。
public class UserHandlerMethodArgumentResolver implements HandlerMethodArgumentResolver {
@Override
public boolean supportsParameter(MethodParameter parameter) {
return parameter.getParameterType().equals(User.class);
}
@Override
public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
String name = webRequest.getParameter("name");
int age = Integer.parseInt(webRequest.getParameter("age"));
User user = new User();
user.setName(name);
user.setAge(age);
return user;
}
}
在这个示例中,我们创建了一个名为 UserHandlerMethodArgumentResolver
的自定义 HandlerMethodArgumentResolver
实现类,并在其中解析多个请求参数。在 supportsParameter()
方法中,我们检查方法参数是否与 User
类型相同。在 resolveArgument()
方法中,我们从请求参数中获取数据,并将其转换为 User
对象。
注册自定义的 HandlerMethodArgumentResolver 实现类
要在 Spring Boot 应用程序中使用自定义的 HandlerMethodArgumentResolver
实现类,我们需要将其注册到应用程序上下文中。为此,我们可以创建一个 @Configuration
类,并实现 WebMvcConfigurer
接口。在这个类中,我们需要重写 addArgumentResolvers()
方法,并将自定义的 HandlerMethodArgumentResolver
实现类添加到参数解析器列表中。
@Configuration
public class AppConfig implements WebMvcConfigurer {
@Override
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {
resolvers.add(new JsonHandlerMethodArgumentResolver());
resolvers.add(new XmlHandlerMethodArgumentResolver());
resolvers.add(new UserHandlerMethodArgumentResolver());
}
}
现在,我们已经成功地创建了多个自定义的 HandlerMethodArgumentResolver
实现类,并将它们注册到 Spring Boot 应用程序中。这样,我们就能够轻松地处理不同类型的请求参数,并将它们转换为 Java 对象。
自定义注解来简化参数赋值。
例如,假设您有一个 @UserParam
注解,您可以使用以下代码来解析它:
public class UserHandlerMethodArgumentResolver implements HandlerMethodArgumentResolver {
@Override
public boolean supportsParameter(MethodParameter parameter) {
return parameter.getParameterAnnotation(UserParam.class) != null;
}
@Override
public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
UserParam userParam = parameter.getParameterAnnotation(UserParam.class);
String name = webRequest.getParameter(userParam.name());
int age = Integer.parseInt(webRequest.getParameter(userParam.age()));
User user = new User();
user.setName(name);
user.setAge(age);
return user;
}
}
在这个示例中,我们创建了一个 @UserParam
注解,并将其应用于方法参数上。然后,我们可以在 supportsParameter()
方法中检查方法参数是否带有 @UserParam
注解。在 resolveArgument()
方法中,我们从注解中获取参数名,并从请求参数中获取相应的值,然后将其转换为 User
对象。
要在 Spring Boot 应用程序中使用自定义注解,您需要将您的注解类添加到 @Configuration
类中,并将其添加到 addArgumentResolvers()
方法中:
@Configuration
public class AppConfig implements WebMvcConfigurer {
@Override
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {
resolvers.add(new UserHandlerMethodArgumentResolver());
}
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.PARAMETER)
public @interface UserParam {
String name() default "name";
String age() default "age";
}
}
现在,您就可以在 Spring Boot 应用程序中使用 @UserParam
注解来简化
参考
HandlerMethodArgumentResolver用于统一获取当前登录用户_metaobjecthandler获取token-CSDN博客
Spring Boot HandlerMethodArgumentResolver 使用和场景-Spring专区论坛-技术-SpringForAll社区
HandlerMethodArgumentResolver(四):自定参数解析器处理特定应用场景,介绍PropertyNamingStrategy的使用【享学Spring MVC】-腾讯云开发者社区-腾讯云
相关文章:

HandlerMethodArgumentResolver用于统一获取当前登录用户
这里记录回顾一些知识,不然就快忘记啦。 环境:SpringBoot 2.0.4.RELEASE需求:很多Controller方法,刚进来要先获取当前登录用户的信息,以便做后续的用户相关操作。准备工作:前端每次请求都传token࿰…...

记录 | mac打开终端时报错:login: /opt/homebrew/bin/zsh: No such file or directory [进程已完成]
mac打开终端时报错:login: /opt/homebrew/bin/zsh: No such file or directory [进程已完成],导致终端没有办法使用的情况 说明 zsh 没有安装或者是安装路径不对 可以看看 /bin 下有没有 zsh,若没有,肯定是有 bash 那就把终端默…...

anolisos8.8安装显卡+CUDA工具+容器运行时支持(containerd/docker)+k8s部署GPU插件
anolisos8.8安装显卡及cuda工具 一、目录 1、测试环境 2、安装显卡驱动 3、安装cuda工具 4、配置容器运行时 5、K8S集群安装nvidia插件 二、测试环境 操作系统:Anolis OS 8.8 内核版本:5.10.134-13.an8.x86_64 显卡安装版本:525.147.05 c…...

Golang 链表的创建和读取 小记
文章目录 链表的相关知识链表的创建:模拟方式建立链表的**递归创建** 链表的读取遍历读取递归读取 完整代码 链表的相关知识 链表有时会具有头节点,头节点的指针指向第一个节点的地址,其本身的数据域可以根据自己的选择进行赋值 接下来我将以将int转…...

实验记录:深度学习模型收敛速度慢有哪些原因
深度学习模型收敛速度慢有哪些原因? 学习率设置不当: 学习率是算法中一个重要的超参数,它控制模型参数在每次迭代中的更新幅度。如果学习率过大,可能会导致模型在训练过程中的振荡,进而影响到收敛速度;如果…...

Arris VAP2500 list_mac_address未授权RCE漏洞复现
0x01 产品简介 Arris VAP2500是美国Arris集团公司的一款无线接入器产品。 0x02 漏洞概述 Arris VAP2500 list_mac_address接口处命令执行漏洞,未授权的攻击者可通过该漏洞在服务器端任意执行代码,写入后门,获取服务器权限,进而控制整个web服务器。 0x03 复现环境 FOFA…...

【Jenkins】节点 node、凭据 credentials、任务 job
一、节点 node Jenkins在安装并初始化完成后,会有一个主节点(Master Node),默认情况下主节点可以同时运行的任务数是2,可以在节点配置中修改(系统管理/节点和云管理)。 Jenkins中的节点&#…...

华为OD机试 - 高效货运(Java JS Python C)
题目描述 老李是货运公司承运人,老李的货车额定载货重量为 wt。 现有两种货物: 货物 A 单件重量为 wa,单件运费利润为 pa货物 B 单件重量为 wb,单件运费利润为 pb老李每次发车时载货总重量刚好为货车额定的载货重量 wt,车上必须同时有货物 A 和货物 B ,货物A、B不可切割…...

基于python netmiko去ssh备份网络设备配置
自己为了便利写出来的基于python netmiko去ssh备份网络设备配置,用过secureCRT的脚本去备份设备配置,但是它没有图形化界面,使用不方便,自己就重新用python开发了一个,同时用pyinstaller打包成可执行程序(这…...

【CCF BDCI 2023】多模态多方对话场景下的发言人识别 Baseline 0.71 Slover 部分
【CCF BDCI 2023】多模态多方对话场景下的发言人识别 Baseline 0.71 Slover 部分 概述Solver 在多模态发言人识别中的作用Solver 在多模态发言人识别中的重要性Solver 的工作原理 二次规划二次规划的基本形式二次规划的特点二次规划在多模态发言中的应用 (我的理解) 代码详解数…...

爬虫工作量由小到大的思维转变---<第十二章 Scrapy之sql存储与爬虫高效性的平衡艺术>
前言: (本文仅属于技术性探讨,不属于教文) 刚好,前阵子团队还在闲聊这个问题呢。你知道吗,在数据收集这个行当里,怎么存数据这问题就跟“先有鸡还是先有蓝”一样,没完没了的循环往复。老规矩,咱们先搞清楚我们的“鸡…...

修改Docker0和容器的地址
修改Docker0和容器的地址 1. 需求 默认服务器安装完Docker-ce后会给docker0分配172.17.0.1/16地址. 公司新接入一个网段正好与172.17.0.1/16冲突,此时访问这台服务器的容器时就会发生网络不可达. 2. 解决方法 修改/etc/docker/daemon.json 加入一个自定义网段 vim /etc/d…...

弹性网络优化算法
3.3、Elastic-Net算法使用 这是scikit-learn官网给出的弹性网络回归的,损失函数公式,注意,它用的矩阵表示,里面用到范数运算。 min w 1 2 n samples ∣ ∣ X w − y ∣ ∣ 2 2 α ρ ∣ ∣ w ∣ ∣ 1 α ( 1 − ρ ) 2 ∣ ∣…...

[C语言]大小端及整形输出问题
假设在一个32位little endian 的机器上运行下面的程序,结果是多少 ? 1.1先看以下三个程序 #include <stdio.h> int main() {long long a 1, b 2, c 3;printf("%lld %lld %lld\n", a, b, c); // 1 2 3printf("%d %d %d %d %d %d\n&quo…...

C# 命令行参数解析库示例
写在前面 在日常开发中,我们经常会用到命令行参数,比如cmd下的各种指令;还有C#的控制台类型的项目,在默认入口Main函数中,那个args参数,就是有系统传入到程序进程的命令行参数;在传入的参数相对…...

2020 年网络安全应急响应分析报告
2020 年全年奇安信集团安服团队共参与和处置了全国范围内 660起网络安全应急响应事件。2020 年全年应急响应处置事件行业 TOP3 分别为:政府部门行业(146 起)医疗卫生行业(90 起)以及事业单位(61 起,事件处置数分别占应急处置所有行业的 22.1%、13.6%、9.2%。2020 年…...

Git----学习Git第一步基于 Windows 10 系统和 CentOS7 系统安装 Git
查看原文 文章目录 基于 Windows 10 系统安装 Git 客户端基于 CentOS7 系统安装部署 Git 基于 Windows 10 系统安装 Git 客户端 (1)打开 git官网 ,点击【windows】 (2)根据自己的电脑选择安装,目前一般w…...

爬虫 scrapy ——scrapy shell调试及下载当当网数据(十一)
目录 一、scrapy shell 1.什么是scrapy shell? 2.安装 ipython 3.使用scrapy shell 二、当当网案例 1.在items.py中定义数据结构 2.在dang.py中解析数据 3.使用pipeline保存 4.多条管道的使用 5.多页下载 参考 一、scrapy shell 1.什么是scrapy shell&am…...

Linux驱动(中断、异步通知):红外对射,并在Qt StatusBus使用指示灯进行显示
本文工作: 1、Linux驱动与应用程序编写:使用了设备树、中断、异步通知知识点,实现了红外对射状态的异步信息提醒。 2、QT程序编写:自定义了一个“文本指示灯”类,并放置在QMainWidget的StatusBus中。 3、C与C混合编程与…...

echarts地图的常见用法:基本使用、区域颜色分级、水波动画、区域轮播、给地图添加背景图片和图标、3d地图、飞线图
前言 最近几天用echarts做中国地图,就把以前写的demo:在vue中实现中国地图 拿来用,结果到项目里直接报错了,后来发现是因为版本的问题,没办法只能从头进行踩坑了。以下内容基于vue3 和 echarts 5.32 基本使用 获取地…...

进程间通讯-管道
介绍 管道(Pipe)是操作系统提供的一种进程间通信(IPC,Inter-Process Communication)机制,它允许一个进程的输出直接作为另一个进程的输入。管道主要分为以下两种类型: 无名管道(Unn…...

项目总结-自主HTTP实现
终于是写完了,花费了2周时间,一点一点看,还没有扩展,但是基本功能是已经实现了。利用的是Tcp为网络链接,在其上面又写了http的壳。没有使用epoll,多路转接难度比较高,以后有机会再写,…...

Java语言+二维数组+非递归实现五子棋游戏
以前做过一个C语言版五子棋:C语言+二维数组+非递归实现五子棋游戏 现在做一个Java语言版五子棋,规则如下: 1、白子为O; 2、黑子为; 3、白子先手;…...

WordCloud—— 词云
【说明】文章内容来自《机器学习入门——基于sklearn》,用于学习记录。若有争议联系删除。 wordcloud 是python的第三方库,称为词云,也成文字云,可以根据文本中的词频以直观和艺术化的形式展示文本中词语的重要性。 依赖于pillow …...

linux网络----UDP编程
一、函数接口: 1.socket:创建一个用来网络通信的终端节点; 参数: type:套接字类型 SOCK_STREAM 流式套接字 TCP SOCK_DGRAM 数据报套接字 UDP SOCK_RAM 原始套接字 domain: 协议族 AF_INET protocal: 默认为0 2.s…...

[AI工具推荐]AiRestful智能API代码生成
智能API代码示例生成工具AiRestful 一、产品介绍二、如何使用1、第一步(必须):2、第二步(可选):3、第三步(智能生成): 三、如何集成到您的网站(应用)1、开始接入2、接入案例 四、注意点 一、产品介绍 AiRestful是一款基于智能AI的,帮助小白快速生成任意编程语言的API接口调用示…...

Elasticsearch 8.10.0同义词API用法详解,支持同义词热更新
Elasticsearch 的同义词功能非常强大,如果使用得当,可以显着提高搜索引擎的效果。使用同义词功能时的一个常见问题是更新同义词集。 同义词在搜索引擎领域用途 同义词在搜索引擎领域的用途可概括如下: 增强搜索的准确性——当用户输入一个关键词时,可能与他们实际意图相关…...

深度学习之模型权重
在深度学习中,模型的权重(weights)是指神经网络中的参数,这些参数用于调整和学习模型的行为,以便能够对输入数据进行有效的映射和提取有用的特征。深度学习模型通常由许多神经元和连接组成,而权重就是连接这…...

纯前端使用XLSX导出excel表格
1 单个sheet page.js(页面中的导出方法) import { exportExcel } from ../../../utils/exportExcel.js; leadOut() {const arr [{ id: 1, name: 张三, age: 14, sex: 男 },{ id: 2, name: 李四, age: 15, sex: 女 },{ id: 3, name: 王五, age: 16, sex: 男 },];const allR…...

将mjpg格式数转化成opencv Mat格式
该博客可以解决如下两个问题: 1、将mjpg格式数据转化成opencv Mat格式 2、v4l2_buffer 格式获取的mjpg格式数据转换成Mat格式。 要将 MJPEG 格式的数据转换为 OpenCV 的 Mat 格式,您可以使用 imdecode 函数。imdecode 函数可以将图像数据解码为 Mat 对象…...