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

【JavaEE进阶】拦截器与统一功能处理

文章目录

  • 一. 用户登录权限效验
    • 1. 最初用户登录验证
    • 2. Spring AOP 用户统一登录的验证
    • 3. Spring拦截器
      • 3.1 自定义拦截器
      • 3.2 将自定义拦截器设置到当前的项目中
    • 4. 拦截器实现的原理
  • 二. 统一的异常处理
    • 1. 统一的异常处理优点
    • 2. 统一的异常处理实现
  • 三. 统一数据返回格式
    • 1. 统一数据返回格式的优点
    • 2. 统一数据返回格式的实现
    • 3. 统一移除处理在遇到String返回时报错问题
  • 小结

AOP思想的体现主要分为两个方面:

  1. Spring AOP用于分离功能性需求和非功能性需求,使得开发人员可以集中处理某一个关注点,减少对业务代码的侵入,增强代码的可读性和可维护性.
  2. SpringBoot的统一功能处理模块.

一. 用户登录权限效验

1. 最初用户登录验证

我们最初对用户登录验证的实现是这样的:

package com.example.demo.controller;import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;@RestController
@RequestMapping("/user")
public class UserController {//执行的方法1@RequestMapping("/m1")public Object method1(HttpServletRequest request){//有 session 就创建,没有 session 就不会创建HttpSession session = request.getSession(false);if(session != null && session.getAttribute("userinfo") != null){//说明已经登录,执行业务处理return true;}else {//未登录return false;}}//执行的方法2@RequestMapping("/m1")public Object method2(HttpServletRequest request){//有 session 就创建,没有 session 就不会创建HttpSession session = request.getSession(false);if(session != null && session.getAttribute("userinfo") != null){//说明已经登录,执行业务处理return true;}else {//未登录return false;}}//其他需要执行的方法...
}

从上述代码可以看出,每个方法的执行都有用户登录验证权限,它的缺点如下:

  1. 每个方法中都单独写用户登录验证的方法,即使封装成公共方法,也是一样要传参调用和在方法中进行判断.
  2. 添加控制器越多,调用用户登录验证的方法就越多,这样就增加了后期的修改成本和维护成本.
  3. 这些用户登录验证的方法和下面要执行的业务代码没有什么关系,但是在每个方法中都实现了一遍.

所以接下来我们提供一个公共的AOP方法来进行统一的用户登录权限验证.

2. Spring AOP 用户统一登录的验证

使用SpringAOP的具体实现代码如下:

package com.example.demo.common;import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;@Aspect
@Component
public class UserAspect {// 定义切点⽅法 controller 包下、⼦孙包下所有类的所有⽅法@Pointcut("execution(* com.example.demo.controller..*.*(..))")public void pointcut(){ }// 前置⽅法@Before("pointcut()")public void doBefore(){}// 环绕⽅法@Around("pointcut()")public Object doAround(ProceedingJoinPoint joinPoint){Object obj = null;System.out.println("Around 方法开始执行");try {// 执⾏拦截⽅法obj = joinPoint.proceed();} catch (Throwable throwable) {throwable.printStackTrace();}System.out.println("Around 方法结束执行");return obj;}
}

如果要在以上 Spring AOP的切面中实现用户登录权限效验的功能,有以下两个问题:

  1. 没办法获取到HttpSession对象。
  2. 我们要对一部分方法进行拦截,而另一部分方法不拦截,如注册方法和登录方法是不拦截的,这样的话排除方法的规则很难定义,甚至没办法定义。

那么我们应该如何解决呢?

3. Spring拦截器

针对以上问题,Spring中提供了具体的实现拦截器:HandlerInterceptor.拦截器的实现分为两个部分:

  1. 创建自定义拦截器,实现HandlerInterceptor接口的preHandle(执行具体方法之前的预处理)方法.
  2. 将自定义拦截器加入WebMvcConfigureraddInterceptors方法中.

具体实现如下:

3.1 自定义拦截器

实现一个UserInterceptor用户拦截器类,在该类中实现HandlerInterceptor接口,再重写preHandle方法
在这里插入图片描述

package com.example.demo.interceptor;import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;@Component
public class UserInterceptor implements HandlerInterceptor {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {//业务方法//从请求中取session,如果有session,直接获取到,但是没有,这里设置为false,也不会新创建一个session。HttpSession session  = request.getSession(false);//这里添加false表示不会新创建session。方法中默认的是true。if(session!=null && session.getAttribute("userinfo")!=null){return true;}response.setStatus(401);//返回一个404return false;}
}

getAttribute方法是Object类中的方法,用于获取对象的指定属性值,它接受一个参数,即要获取的属性的名称,并返回该属性的值,如果对象中不存在指定名称的属性,则返回null。该方法可以用于获取对象的任意属性,包括实例变量和静态变量。

3.2 将自定义拦截器设置到当前的项目中

实现一个AppConfig类用来配置,实现WebMvcConfigurer接口,然后重写其中的addInterceptor方法.
在这里插入图片描述

package com.example.demo.config;import com.example.demo.interceptor.UserInterceptor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;@Configuration
public class AppConfig implements WebMvcConfigurer {@Autowiredprivate UserInterceptor userInterceptor;@Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(userInterceptor).addPathPatterns("/**")// 表示拦截所有的请求.excludePathPatterns("/user/reg")//排除不拦截的url.excludePathPatterns("/user/login")//排除不拦截的url;}
}

这里的addInterceptor方法接受一个参数,就是要添加的拦截器对象。可以通过该方法添加一个或多个拦截器。
我们可以写一个UserController1测试类看一下运行结果:

package com.example.demo.controller;import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;@RestController
@RequestMapping("/user")
public class UserController {@RequestMapping("/reg")public String reg(){return "do reg.";}@RequestMapping("/login")public String login(){return "do login.";}@RequestMapping("/test")public String test(){return "do Test.";}
}

由于我们的拦截器中拦截了所有的请求但是除了/user/reg /user/login方法,所以这两个方法可以执行成功.而我们的Test方法则被拦截,返回401状态码.
在这里插入图片描述
当我们想要排除所有的静态文件,静态文件包含图片文件,前端的JS和CSS等文件,这个时候我们不可能将每种格式的文件都手动进行排除,这样工作量也太大了(图片文件存在几十种格式),想要将这些文件排除掉我们可以将这个静态文件放入项目的static目录中,然后针对这个目录中的子目录(图片,css文件,js文件)进行排除。

excludePathPatterns("/image/**")//表示排除image目录下的所有图片

在这里插入图片描述

4. 拦截器实现的原理

没有实现拦截器的时候,用户发送的请求直接被控制层接收到,进而在相应的URL中进行登录校验,这种方式代码的可维护性较低。

但是使用拦截器,用户发送的请求首先会被拦截器接收到,拦截器进行预处理,符合条件才会进一步调用Controller层的方法。
在这里插入图片描述

二. 统一的异常处理

我们之前处理异常的方法就是使用try-catch,或者是将异常抛出去给更上一层处理,这种方式处理异常的方式通常是分散在代码的各个部分中的,当应用程序出现异常时,开发需要在每个可能抛出异常的地方编写相应的异常处理代码,这样做会导致代码冗余,可读性差,并且难以维护。

1. 统一的异常处理优点

而使用统一的异常处理就可以:

  1. 集中处理异常:通过使用统一的异常处理机制,可以集中处理应用程序中的异常。这意味着无论在哪个控制器方法或服务方法中抛出异常,都可以在统一的地方进行处理,从而减少代码冗余。
  2. 统一错误响应:统一的异常处理机制可以确保应用程序返回一致的错误响应给客户端。这样做可以提高用户体验,让客户端能够更容易地理解和处理错误情况。
  3. 异常日志记录:通过统一的异常处理,可以方便地实现异常的日志记录。可以在异常处理器中添加日志记录的逻辑,记录异常的详细信息、发生时间和相关的上下文信息,以便后续的错误分析和故障排查。
  4. 异常转换和封装:统一的异常处理机制还可以进行异常的转换和封装。例如,可以将底层框架或第三方库的异常转换为应用程序定义的自定义异常,以简化异常的处理和管理。
  5. 统一的异常处理策略:通过统一的异常处理,可以定义全局的异常处理策略。可以根据不同的异常类型采取不同的处理方式,例如返回特定的错误码、跳转到指定的错误页面或执行其他自定义逻辑。

2. 统一的异常处理实现

在Spring Boot中,可以使用@RestControllerAdvice注解和@ExceptionHandler注解来实现统一异常处理。这两个注解搭配使用表示的是全局异常处理,可以捕获并处理全局范围内的异常。当控制器中抛出异常时,会根据异常类型匹配对应的@ExceptionHandler方法进行处理。
Exception类是Java中所有异常类的父类。

  • @RestControllerAdvice注解用在一个类上,表示该类是一个全局的控制器增强器,可以对所有的控制器进行统一的处理。这个注解提供了一种集中管理和统一处理全局范围内操作的方式,在引用程序中起到了很好的代码复用和统一管理的作用。
  • @ExceptionHandler注解,用于定义一个方法,**该方法用于处理控制器中发生的异常。**当控制器中的方法抛出异常时,@ExceptionHandler注解标记的方法将被调用来处理该异常。这样可以集中处理控制器中的异常。
  1. 创建一个异常处理类
    在这里插入图片描述
  2. 创建异常检测的类和处理业务方法:
package com.example.demo;import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;import java.util.HashMap;@ControllerAdvice
@ResponseBody
public class MyExpectionAdvice {@ExceptionHandler(NullPointerException.class)public HashMap<String,Object> doNullPointerExpection(NullPointerException e){HashMap<String,Object> result = new HashMap<>();result.put("code",-1);result.put("msg","空指针"+e.getMessage());result.put("data",null);return result;}
}

写个UserController测试一下:

package com.example.demo.controller;import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;@RestController
@RequestMapping("/user")
public class UserController {@RequestMapping("/login")public int login() {//空指针异常Object obj = null;System.out.println(obj.hashCode());return 1;}
}

在这里插入图片描述
此时我们就可以告诉前端异常的类型.上述代码我们处理了空指针异常,通常情况下,我们无法预测代码会抛出什么异常.所以我们可以使用所有异常的父类Expection来处理:

    //默认的异常处理@ExceptionHandler(Exception.class)public HashMap<String, Object> doException(Exception e) {HashMap<String, Object> result = new HashMap<>();result.put("code", -300);result.put("msg", "Exception:" + e.getMessage());result.put("data", null);return result;}

那么上述doException方法也可以处理空指针异常,当上述两个处理异常的方式同时存在时,首先采用的是doNullPointerExpection:(有子类先开始处理子类,再处理父类)
在这里插入图片描述

三. 统一数据返回格式

1. 统一数据返回格式的优点

  • 方便前端程序员更好的接收和解析后端数据接口返回的数据。
  • 降低前端程序员和后端程序员的沟通成本,按照某个个格式实现就行了,因为所有返回接口都是这样返回的
  • 有利于项目统一数据的维护和修改
  • 有利于后端技术部门的统一规范的标准指定,不会出现稀奇古怪的返回内容。

总结起来,统一数据返回格式可以提高接口的规范性、可读性和可维护性,方便异常处理,支持扩展和版本控制,并增强系统的兼容性。这些优点都有助于提高开发效率、减少错误和提升用户体验。

2. 统一数据返回格式的实现

统一的数据返回格式可以使用@ControllerAdvice+ResponseBodyAdvice的方式实现,实现步骤如下:
实现ResponseBodyAdvice接口.并重写其中的方法supports beforeBodyWrite方法:
值得注意的是在此类中不需要加入@ResponseBody注解,这是因为在该类中只是对返回值进行转换.

package com.example.demo.controller;import org.springframework.core.MethodParameter;
import org.springframework.http.MediaType;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;import java.util.HashMap;@ControllerAdvice
public class ResponseAdvice implements ResponseBodyAdvice {//是否执行 beforeBodyWrite 方法,true=执行,重写返回结果@Overridepublic boolean supports(MethodParameter returnType, Class converterType) {return true;}//返回数据之前进行数据重写//@param body :原始返回值@Overridepublic Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType, Class selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) {// HashMap<String,Object>  ->  code,msg,dataif (body instanceof HashMap) {return body;}// 重写返回结果,让其返回一个统一的数据格式HashMap<String, Object> result = new HashMap<>();result.put("code", 200);result.put("data", body);result.put("msg", "");return result;}
}

写个测试方法测试一下:

    @RequestMapping("/test")public int test(){return 666;}

在这里插入图片描述
可以看到,上述结果返回的是我们指定的数据格式.

3. 统一移除处理在遇到String返回时报错问题

但是上述返回值有一个问题,即如果返回的类型是String类型时会报错:
测试方法:

    @RequestMapping("/test1")public String test1(){return "dotest1";}

运行结果:
在这里插入图片描述

要注意其返回的流程:

  1. 方法返回的是String
  2. 统一数据返回之前处理-> String Convert HashMap
  3. 将 HashMap 转换成 application/json 字符串给前端(接口)

显然,Exception:java.util.HashMap cannot be cast to java.lang.String是第三步出现了问题.第三步在执行的时候会判断Body的类型,如果是String类型,那么执行StringHttpMessageConverter进行类型转换;如果不是String类型,那么执行HttpMessageConverter进行类型转换.问题就出在了将HashMap 转换成 application/json 字符串给前端(接口).针对以上问题,有两种解决方式:

  1. StringHttpMessageConverter去掉:
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;import java.util.List;@Configuration
public class MyConfig implements WebMvcConfigurer {//移除 StringHttpMessageConverter@Overridepublic void configureMessageConverters(List<HttpMessageConverter<?>> converters) {converters.removeIf(converter -> converter instanceof StringHttpMessageConverter);}
}
  1. 在统一数据重写时,单独处理String 类型,让其返回一个String 字符串,而非 HashMap
 @Overridepublic Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType, Class selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) {// HashMap<String,Object>  ->  code,msg,dataif (body instanceof HashMap) {return body;}// 重写返回结果,让其返回一个统一的数据格式HashMap<String, Object> result = new HashMap<>();result.put("code", 200);result.put("data", body);result.put("msg", "");if(body instanceof String){// 返回一个 将对象转换成 JSON String 字符串try {return objectMapper.writeValueAsString(result);} catch (JsonProcessingException e) {e.printStackTrace();}}return result;}

注意在上述代码中使用import com.fasterxml.jackson.databind.ObjectMapper包下的objectMapper方法需要引入Maven-jackson依赖:

<dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-databind</artifactId>
</dependency>

在这里插入图片描述

小结

自定义拦截器的实现:使用HandlerInterceptor接口+WebMvcConfigurer接口实现。
统一异常的处理:使用@RestControllerAdvice注解+@ExceptionHandler注解实现。
统一数据返回格式:使用@ControllerAdvice注解+ResponseBodyAdvice接口实现。

相关文章:

【JavaEE进阶】拦截器与统一功能处理

文章目录 一. 用户登录权限效验1. 最初用户登录验证2. Spring AOP 用户统一登录的验证3. Spring拦截器3.1 自定义拦截器3.2 将自定义拦截器设置到当前的项目中 4. 拦截器实现的原理 二. 统一的异常处理1. 统一的异常处理优点2. 统一的异常处理实现 三. 统一数据返回格式1. 统一…...

2023年智慧政务一网通办云平台顶层设计与建设方案PPT

导读&#xff1a;原文《2023年智慧政务一网通办云平台顶层设计与建设方案PPT》&#xff08;获取来源见文尾&#xff09;&#xff0c;本文精选其中精华及架构部分&#xff0c;逻辑清晰、内容完整&#xff0c;为快速形成售前方案提供参考。 部分内容&#xff1a; 喜欢文章&#…...

安防监控/视频汇聚平台EasyCVR调用rtsp地址返回的IP不正确是什么原因?

安防监控/云存储/磁盘阵列存储/视频汇聚平台EasyCVR可拓展性强、视频能力灵活、部署轻快&#xff0c;可支持的主流标准协议有GB28181、RTSP/Onvif、RTMP等&#xff0c;以及厂家私有协议与SDK接入&#xff0c;包括海康Ehome、海大宇等设备的SDK等&#xff0c;能对外分发RTSP、RT…...

媒体服务器与视频服务器有什么区别

媒体服务器与视频服务器有什么区别 流媒体服务器用在远程教育&#xff0c;视频点播、网络电台、网络视频等方面。 直播过程中就需要使用流媒体服务器&#xff0c;一个完整的直播过程&#xff0c;包括采集、处理、编码、封包、推流、传输、转码、分发、解码、播放等过程&#xf…...

菜鸟教程《Python 3 教程》笔记(11):循环语句

菜鸟教程《Python 3 教程》笔记&#xff08;11&#xff09; 11 循环语句11.1 while 循环11.1.1 while 循环使用 else 语句 11.2 for 语句11.2.1 for...else 11.3 break 和 continue 语句及循环中的 else 子句 11 循环语句 出处&#xff1a; 菜鸟教程 - Python3 循环语句 11.1…...

【DevOps视频笔记】8. Jenkins 配置

一、Jenkins 入门配置 1. 工具 / 插件 介绍 二、插件和工具配置 1. 配置 JDK 和 Maven Stage 1&#xff1a;将服务器中 JDK 和 Maven 映射到 jenkins 容器中 Stage 2&#xff1a;jenkins 全局配置中 -- 指定JAVA_HOME目录 Stage 3&#xff1a;jenkins 全局配置中 -- 指定…...

C# 在Color[] colorTable中快速找到Color的索引位置

C# 在Color[] colorTable中快速找到Color的索引位置 第一种方法&#xff1a; 如果您需要在Color[] colorTable中快速查找特定Color的索引位置&#xff0c;可以使用C#的Array.FindIndex方法。这个方法接受一个回调函数作为参数&#xff0c;该函数定义了如何判断数组元素是否与…...

go学习笔记 炒土豆丝

今天的主菜是土豆&#xff0c;就来个土豆丝吧。我的大致流程如下&#xff1a; 1.挑选白瓤土豆&#xff0c;洗它 2.土豆去皮 3.土豆切片&#xff0c;切丝&#xff0c;丝要粗细均匀 4.清洗几遍土豆丝&#xff0c;去除上面的淀粉&#xff0c;在清水中泡一小会 5.起锅&#xff0c;放…...

FPGA VR摄像机-拍摄和拼接立体 360 度视频

本文介绍的是 FPGA VR 相机的第二个版本&#xff0c;第一个版本是下面这样&#xff1a; 第一版地址&#xff1a; ❝ https://hackaday.io/project/26974-vr-camera-fpga-stereoscopic-3d-360-camera ❞ 本文主要介绍第二版本&#xff0c;第二版本的 VR 摄像机&#xff0c;能够以…...

vue集成mars3d后,basemaps加不上去

首先&#xff1a; <template> <div id"centerDiv" class"mapcontainer"> <mars-map :url"configUrl" οnlοad"onMapload" /> </div> </template> <script> import MarsMap from ../component…...

油管视频直接生成PPT的AI工具!剖析c.ai和Pi的用户需求;独立创业者的操作指南;广告大佬的三个AI绘画实战 | ShowMeAI日报

&#x1f440;日报&周刊合集 | &#x1f3a1;生产力工具与行业应用大全 | &#x1f9e1; 点赞关注评论拜托啦&#xff01; &#x1f916; 2023 CCF BDCI 数字安全公开赛&#xff0c;大模型安全竞赛等你「码」力全开 网站&#xff1a;https://www.datafountain.cn/special/B…...

WebSocket- 前端篇

官网代码 // 为了浏览器兼容websocketconst WebSocket window.WebSocket || window.MozWebSocket// 创建连接 this.socket new WebSocket(ws://xxx)// 连接成功this.socket.onopen (res)>{console.log(websocket 连接成功)this.socket.send(入参字段) // 传递的参数字段}…...

如何在 Python 中将图像转换为 PDF

一、说明 如何使得图像转化成pdf文件&#xff0c; 想要将一个或多个图像转换为 PDF 文档&#xff1f;看看img2pdf和PyPDF2软件包就是您的最佳选择。 二、需要哪些程序包&#xff1f; 首先&#xff0c;您只需要一个 Python 环境&#xff0c;最好是 3.10 或更高版本。本教程中的代…...

使用python编写脚本测试目标主机的TCP端口连通性

使用Python的Socket模块的connect()函数来尝试连接目标主机的特定端口。如果连接成功&#xff0c;则说明该端口是打开的&#xff1b;否则&#xff0c;该端口是关闭的。 下面是一个示例脚本&#xff0c;可以检测目标IP的22端口是否开启&#xff1a; import socket def check_po…...

华为云云服务器评测|基于华为云云耀云服务器L实例开展性能评测,例如 MySQL、Clickhouse、Elasticsearch等等

在当今云计算时代&#xff0c;越来越多的企业和个人开始选择将应用部署在云服务器上&#xff0c;以便更好地满足高性能、可靠性和可扩展性等需求。而华为云云耀云服务器L实例不仅提供了高性能和可靠性的计算和存储资源&#xff0c;而且具有灵活和高效的成本控制&#xff0c;深受…...

Git分布式版本控制系统与github

第四阶段提升 时 间&#xff1a;2023年8月29日 参加人&#xff1a;全班人员 内 容&#xff1a; Git分布式版本控制系统与github 目录 一、案例概述 二、版本控制系统 &#xff08;一&#xff09; 本地版本控制 &#xff08;二&#xff09;集中化的版本控制系统 &…...

基于Java+SpringBoot+Vue前后端分离中国陕西民俗网设计和实现

博主介绍&#xff1a;✌全网粉丝30W,csdn特邀作者、博客专家、CSDN新星计划导师、Java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专…...

CSS3D+动画

CSS3D 1.css3D 给父元素设置 perspective:景深:近大远小的效果900-1200px这个范围内 transform-style:是否设置3D环境 flat 2D环境 默认值 perserve-3D环境 3D功能函数 1.位移: translateZ()translate3D(x,y,z) <!DOCTYPE html> <html lang"en"><h…...

list对象中如何根据对象中某个属性去重使用Java8流实现

list对象中如何根据对象中某个属性去重使用Java8流实现? 在 Java 8 的流操作中&#xff0c;可以使用 distinct 方法来对一个对象流进行去重&#xff0c;但是默认情况下它会使用对象的 equals() 方法来判断重复。如果你希望根据对象的某个属性进行去重&#xff0c;则可以使用 …...

2023 在Windows上的安装Faiss-GPU(使用anaconda)

该方法安装完 faiss-gpu 之后&#xff0c;不仅会装这个库&#xff0c;还会装很多依赖库。为了防止自己本地一些同名库的版本被修改&#xff0c;建议新建一个虚拟环境来安装。如果本地库版本修改对自己没影响&#xff0c;也可以忽略。 你好&#xff0c;我是悦创。 登录网站&…...

HTML及CSS入门及精通

前言 HTML&#xff08;超文本标记语言&#xff09;和CSS&#xff08;层叠样式表&#xff09;是构建网页的两个基本技术。HTML用于定义网页的结构和内容&#xff0c;而CSS用于控制网页的样式和布局。本教程将介绍HTML和CSS的入门知识&#xff0c;并逐步引导您掌握更高级的技巧和…...

frp实现二级代理

kali是攻击机 &#xff08;192.168.0.106&#xff09; windows server2012是边界服务器&#xff0c;拥有两个网卡&#xff0c;作为一级代理&#xff0c; &#xff08;192.168.0.108&#xff0c;10.10.10.136&#xff09; ad01是内网机器&#xff0c;不出网 &#xff08;10.10.1…...

Vue组件设置背景色

vh&#xff1a;浏览器视区高度百分值 wh&#xff1a;浏览器视区宽度百分值 min-height&#xff1a;最小高度&#xff0c;其他时候自适应 给组件根标签设置&#xff1a;min-height&#xff1a;100vh&#xff0c;就可以正常添加背景色&#xff0c;而且背景色随内容展开而自适…...

Java+Github+Jenkins部署

Java项目—Jenkins部署笔记 一&#xff0c;准备 一台服务器操作系统&#xff0c;示例为ubuntu 22.0.4 可运行lsb_release -a查看 二&#xff0c;安装 docker 更新软件包列表&#xff1a; sudo apt update安装必要的软件包&#xff0c;以便使用HTTPS通过APT下载软件包&#x…...

vue使用命令npm install 报错 cb() never called!

一.错误说明,npm本身下载就慢&#xff0c;有可能是网络的问题。 二.解决方案,把npm设置成淘宝镜像后,再重新npm install npm config set registry https://registry.npm.taobao.org 三.还是不行&#xff0c;还会出现同样的问题&#xff0c;那接下来先清理一下npm缓存 npm cache…...

什么是LatexEasy及其在数学排版中的作用

LatexEasy是一种强大的排版系统&#xff0c;特别擅长处理数学公式和科技文档。它基于 TeX&#xff0c;是由计算机科学家 Donald Knuth 开发的。LaTeX 可以让你专注于内容&#xff0c;而不必过多关心排版细节&#xff0c;特别适用于数学家、工程师和科学研究者。 什么是 LaTeX&…...

axios 和fetch的取舍,以及比较

废话不多说&#xff0c;直接直捣黄龙&#xff1a; 区别 相同点 都是一种基于promise的异步解决方案。都可以解决回调地狱问题 不同点 axios是一个封装好的库&#xff0c;需要npm进行安装&#xff0c;fetch是es6新增的api 语法&#xff1a; fetch(url, { method: GET, // o…...

K-Means(K-均值)聚类算法理论和实战

目录 K-Means 算法 K-Means 术语 K 值如何确定 K-Means 场景 美国总统大选摇争取摆选民 电商平台用户分层 给亚洲球队做聚类 ​编辑 其他场景 K-Means 工作流程 K-Means 开发流程 K-Means的底层代码实现 K-Means 的评价标准 K-Means 算法 对于 n 个样本点来说&am…...

Python-pyqt不同窗口数据传输【使用静态函数】

文章目录 前言程序1&#xff1a;caogao1.py输入数据界面程序2&#xff1a;caogao2.py接收数据界面 程序3 &#xff1a;将输入数据界面和接收数据界面组合成一个总界面讲解 总结 前言 在编写pyqt 页面时有时候需要不同页面进行数据传输。本文讲解静态函数方法。直接看示例。 程…...

百度垂类离线计算系统发展历程

作者 | 弘远君 导读 本文以百度垂类离线计算系统的演进方向为主线&#xff0c;详细描述搜索垂类离线计算系统发展过程中遇到的问题&#xff0c;以及对应的解决方案。架构演进过程中一直奉行“没有最好的架构&#xff0c;只有最合适的架构”的宗旨&#xff0c;面对不同阶段遇到的…...

ubuntu 安装 指定版本:nodejs

通过 PPA 安装指定或最新版本的 nodejs 那么就需要使用 nodesource 来安装指定版本的 nodejs 了。其需要下载一个脚本&#xff0c;运行此脚本会在 ubuntu 里添加一个 nodejs 源&#xff0c;然后用 apt 就可以下载指定的 nodejs 了。 PPA 的全称为 personal package archive 。要…...

16.CSS菜单悬停特效

效果 源码 <!DOCTYPE html> <html> <head> <title>Creative Menu Item Hover Effects</title> <link rel="stylesheet" type="text/css" href="style.css"> </head> <body><section><…...

恒运资本:市盈率怎么算?

市盈率&#xff08;P/E ratio&#xff09;是判别一家公司股票价格合理性的一个重要目标&#xff0c;也是投资者评估公司股票投资价值的重要参阅目标。市盈率越高&#xff0c;表明相对于公司的收益来说&#xff0c;该公司的股票定价越高。市盈率越低&#xff0c;则表明该股票被低…...

Docker运维中常见错误以及解决方法汇总1

1.报错如下: Another app is currently holding the yum lock; waiting for it to exit... 另一个应用程序是:PackageKit 原因:另一个APP正在锁定yum,等待其退出! 解决:执行指令 rm -f /var/run/yum.pid 2.CentOS7设置静态的IP且可以上网...

Maven - 使用maven-release-plugin规范化版本发布

文章目录 Maven Release plugin – IntroductionMaven Release plugin – Plugin DocumentationMaven Release plugin – Usage实战案例 Maven Release plugin – Introduction Maven Release Plugin&#xff08;Maven 发布插件&#xff09;是一个用于帮助在Maven项目中执行版…...

2023.8.29 关于性能测试

目录 什么是性能测试&#xff1f; 性能测试常见术语及其性能测试衡量指标 并发 用户数 响应时间 事务 点击率 吞吐量 思考时间 资源利用率 性能测试分类 基准性能测试 负载性能测试 压力性能测试 可靠性性能测试 性能测试执行流程 什么是性能测试&#xff1f; 性…...

基于MATLAB的径向基函数插值(RBF插值)(一维、二维、三维)

基于MATLAB的径向基函数插值&#xff08;RBF插值&#xff09;&#xff08;一维、二维、三维&#xff09; 0 前言1 RBF思路2 1维RBF函数2.1 参数说明2.1.1 核函数选择2.1.2 作用半径2.1.3 多项式拟合2.1.4 误差项&#xff08;光滑项&#xff09; 3 2维RBF函数4 3维RBF函数 惯例声…...

flume拦截器

flume拦截器代码 1.依赖 <?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.apach…...

vue、elementui控制前一级选择后,后一级才会有数据

<el-form-item label"废物类型&#xff1a;"><el-select clearable v-model"queryForm.hswCateType" placeholder"请选择" change"industryCategoryChange" focus"industryCategoryFocus"><el-option v-for&…...

亲测influxdb安装为window后台服务

InfluxDB 安装 64bit&#xff1a;https://dl.influxdata.com/influxdb/releases/influxdb-1.7.4_windows_amd64.zip 解压安装包 修改配置文件 [meta]# Where the metadata/raft database is storeddir "D:/influxdb/meta"...[data]# The directory where the TSM…...

【LeetCode - 每日一题】823. 带因子的二叉树 (2023.08.29)

823. 带因子的二叉树 题意 元素都大于1&#xff0c;元素不重复。计数满足要求的二叉树&#xff08;每个非叶结点的值应等于它的两个子结点的值的乘积&#xff09;的数量。元素可以重复使用。 代码 自上而下动态规划。 所有元素大于1&#xff0c;所以不会有 自己自己自己 的…...

flutter 上传图片并裁剪

1.首先在pubspec.yaml文件中新增依赖pub.dev image_picker: ^0.8.75 image_cropper: ^4.0.1 2.在Android的AndroidManifest.xml文件里面添加权限 <activityandroid:name"com.yalantis.ucrop.UCropActivity"android:screenOrientation"portrait"andro…...

一台服务器上部署 Redis 伪集群

哈喽大家好&#xff0c;我是咸鱼 今天这篇文章介绍如何在一台服务器&#xff08;以 CentOS 7.9 为例&#xff09;上通过 redis-trib.rb 工具搭建 Redis cluster &#xff08;三主三从&#xff09; redis-trib.rb 是一个基于 Ruby 编写的脚本&#xff0c;其功能涵盖了创建、管…...

ealtek高清晰音频管理器(realtek高清晰音频管理器怎么设置win10)

本文为大家介绍realtek高清晰音频管理器(realtek高清晰音频管理器怎么设置win10)&#xff0c;下面和小编一起看看详细内容吧。 我们都使用电脑来听音乐、看电影或者进行其他操作&#xff0c;但是如果我们觉得电脑产生的音效不够立体&#xff0c;我们就会想要去Realtek来设置音…...

微信小程序 scroll-view 组件的 bindscroll 不触发不生效

使用微信小程序基础组件中的scroll-view&#xff0c;但是滑动的时候 bindscroll 一直不生效。 <view class"container log-list"><scroll-view scroll-y style"height:100%;white-space:nowrap;" scroll-into-view"{{toView}}" enable…...

datax 删除分区数据,再写入MySQL脚本

#! /bin/bashDATAX_HOME/opt/module/datax#1、判断参数是否传入 if [ $# -lt 1 ] thenecho "必须传入all/表名..."exit fi #2、判断日期是否传入 [ "$2" ] && datestr$2 || datestr$(date -d -1 day %F)#DataX导出路径不允许存在空文件&#xff0c…...

hyperf 十四 国际化

一 安装 composer require hyperf/translation:v2.2.33 二 配置 1、设置语言文件 文件结构&#xff1a; /storage/languages/en/messages.php /storage/languages/zh_CH/messages.php // storage/languages/en/messages.php return [welcome > Welcome to our applicat…...

C语言_初识C语言指针

文章目录 前言一、指针 ... 一个内存单元多大比较合适&#xff1f;二、地址或者编号如何产生&#xff1f;三、指针变量的大小 前言 内存是电脑上特别重要的存储器&#xff0c;计算机中程序的运行都是在内存中进行的。 所以为了有效的使用内存&#xff0c;就把内存划分成一个个…...

EMQX启用双向SSL/TLS安全连接以及java连接

作为基于现代密码学公钥算法的安全协议&#xff0c;TLS/SSL 能在计算机通讯网络上保证传输安全&#xff0c;EMQX 内置对 TLS/SSL 的支持&#xff0c;包括支持单/双向认证、X.509 证书、负载均衡 SSL 等多种安全认证。你可以为 EMQX 支持的所有协议启用 SSL/TLS&#xff0c;也可…...

4399面试总结C/C++游戏开发

主要流程 首先询问了C/C知识点 然后询问操作系统&#xff0c;计算机组成&#xff0c;数据结构&#xff0c;计算机网络哪两门熟悉 涉及的相关问题 多态的概念 tcp,udp&#xff1f; tcp,udp区别 tcp可靠&#xff0c;udp不可靠 tcp这个链接的过程? 一个TCP连接必须要经过三次“…...