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

Springboot中使用拦截器、过滤器、监听器

一、Servlet、Filter(过滤器)、 Listener(监听器)、Interceptor(拦截器)

Javaweb三大组件:servlet、Filter(过滤器)、 Listener(监听器)

SpringBoot特有组件:Interceptor(拦截器)

过滤器、拦截器、监听器、AOP(后续文章介绍)、全局异常处理器(后续文章介绍)是搭建系统框架时,经常用到的部分,全局异常处理器的作用很明显,就是处理接口执行过程中的异常,而过滤器、拦截器和AOP的作用就很丰富了,日志记录、性能监控、安全认证等等可以向上抽取的功能组件,均可以用他们来实现。

传统基于Servlet容器的程序中,我们可以使用过滤器和监听器,在Java 框架中还可以使用拦截器,而面向切面编程AOP更是作为Spring框架中的核心思想被大家所关注

Filter和Listener:依赖Servlet容器,基于函数回调实现。可以拦截所有请求,覆盖范围更广,但无法获取ioc容器中的bean。

Interceptor和aop:依赖spring框架,基于java反射和动态代理实现。只能拦截controller的请求,可以获取ioc容器中的bean,这点很重要,在拦截器里注入一个service,可以调用业务逻辑。。 

从 Filter -> Interceptor -> aop ,拦截的功能越来越细致、强大,尤其是Interceptor和aop可以更好的结合spring框架的上下文进行开发。但是拦截顺序也是越来越靠后,请求是先进入Servlet容器的,越早的过滤和拦截对系统性能的消耗越少。具体选用哪种方法,就需要开发人员根据实际业务情况综合考虑了。


二、过滤器

1、过滤器作用

Filter过滤器是Servlet容器层面的,在实现上基于函数回调,可以对几乎所有请求进行过滤

过滤器是对数据进行过滤,预处理过程,当我们访问网站时,有时候会发布一些敏感信息,发完以后有的会用*替代,还有就是登陆权限控制等,一个资源,没有经过授权,肯定是不能让用户随便访问的,这个时候,也可以用到过滤器,主要是对用户的一些请求进行一些预处理,并在服务器响应后再进行预处理,返回给用户。

过滤器的功能还有很多,例如实现URL级别的权限控制、压缩响应信息、编码格式等等。对web服务器管理所有的web资源,例如jsp,静态图片 过滤敏感词汇,某些信息用*隐藏。
使用方式有以下三种

2、过滤器执行流程

3、过滤器拦截路径

4、过滤链

一个javaweb系统中,可以配置多个过滤器、这多个过滤器就形成了一个过滤链,当然可以控制每个过滤器顺序,见过滤器三种实现方式

5、过滤器三种实现方式

第一种方式:利用Servlet3.0的WebFilter注解配置

@WebFilter是Servlet3.0新增加的注解,在servlet3.0之前,我们需要在web.xml文件中进行过滤器的配置,而现在可以通过此注解进行配置,当项目启动时,会自动扫描自动注册

通过 @WebFilter 注解来标记一个过滤器,这种方式相信大家很容易想到。这是将 Servlet 中的那一套东西直接拿到 Spring Boot 上用。

具体做法就是通过 @WebFilter 注解来标记一个 Filter,如下:

//一个是filter的名字,一个是url为什么时用此过滤器,其他的看源码,Filter,必须要有名字,所有的过滤器执行顺序是根据Filter的名字字母顺序来执行的
@WebFilter(filterName = "filter1",urlPatterns = {"/hello/*"})
public class TimeFilter implements Filter {@Overridepublic void init(FilterConfig filterConfig) throws ServletException {System.out.println("=======初始化过滤器=========");}@Overridepublic void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain)throws IOException, ServletException {long start = System.currentTimeMillis();filterChain.doFilter(request, response);System.out.println("filter 耗时:" + (System.currentTimeMillis() - start));}@Overridepublic void destroy() {System.out.println("=======销毁过滤器=========");}}

这个注解要生效,还需要我们在项目启动类上配置 @ServletComponentScan 注解,

@ServletComponentScan 注解虽然名字带了 Servlet,但是实际上它不仅仅可以扫描项目中的 Servlet 容器,也可以扫描 Filter 和 Listener。

这是我们在 Spring Boot 中使用过滤器的第一种方式,在实际项目中,这种方式使用较少,因为这种方式有一个很大的弊端就是无法指定 Filter 的优先级,如果存在多个 Filter 时,无法通过 @Order 指定优先级。

@SpringBootApplication
@ServletComponentScan
public class SysoaApplication {public static void main(String[] args) {SpringApplication.run(SysoaApplication.class, args);}}

第二种方式:利用SpringBoot的配置类来添加过滤器

这种方式最简单,直接实现Filter接口,并使用@Component注解标注为组件自动注入bean,

Filter接口有 init、doFilter、destroy 三个方法,但 init、destroy 是有默认方法实现,可以不重写。

@Component
public class TimeFilter implements Filter {@Overridepublic void init(FilterConfig filterConfig) throws ServletException {System.out.println("=======初始化过滤器=========");}@Overridepublic void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain)throws IOException, ServletException {long start = System.currentTimeMillis();filterChain.doFilter(request, response);System.out.println("filter 耗时:" + (System.currentTimeMillis() - start));}@Overridepublic void destroy() {System.out.println("=======销毁过滤器=========");}}

但是缺点是没办法设置过滤的路径,默认是 /* 过滤所有(当然代码中可以加入相关判断)。 

public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {HttpServletRequest request = (HttpServletRequest) servletRequest;HttpServletResponse response = (HttpServletResponse) servletResponse;String requestUri = request.getRequestURI().replaceFirst(contextPath, "");String[] urlList = {"/login","/loginPage","logOut"};for (String uriItem : urlList){if(requestUri.contains(uriItem)){filterChain.doFilter(request,response);return;}}//判断session中是否存在用户,这里还可以做其他业务逻辑 比如ip黑名单等 用户是否被禁,禁止多人在线等if (request.getSession().getAttribute(SystemConstants.USER) == null) {//没有登录跳转到登录页面response.sendRedirect(contextPath+SystemConstants.LOGIN_PAGE_URL);return;}filterChain.doFilter(request, response);}


这种方式看起来很方便,一个注解将 Filter 纳入到 Spring 容器中即可。而且这种方式还有一个优势,就是如果存在多个 Filter,可以通过 @Order 注解指定多个 Filter 的优先级,像下面这样:

@Component
@Order(-1)
public class MyFilter implements Filter {@Overridepublic void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {System.out.println("-----doFilter-----");chain.doFilter(request, response);}
}

第三种方式:Configuration+FilterRegistrationBean

还是将 Filter 封装成一个 Bean,但这个 Bean 是 FilterRegistrationBean,通过 FilterRegistrationBean 我们既可以配置 Filter 的优先级,也可以配置 Filter 的拦截规则。

public class AFilter implements Filter {@Overridepublic void init(FilterConfig filterConfig) throws ServletException {System.out.println("=======初始化过滤器A=========");}@Overridepublic void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain)throws IOException, ServletException {long start = System.currentTimeMillis();filterChain.doFilter(request, response);System.out.println("filter 耗时:" + (System.currentTimeMillis() - start));}@Overridepublic void destroy() {System.out.println("=======销毁过滤器=========");}}

 然后使用SpringBoot提供的FilterRegistrationBean来对Filter进行配置

@Configuration
public class FilterConfig  {/*过滤器注解bean:  FilterRegistrationBean,  注册过滤器, 添加过滤器*/@Beanpublic FilterRegistrationBean<AFilter> createFilterRegistrationBean() {//1.创建FilterRegistrationBean这个对象, 一个过滤器注册器,注册一个过滤器FilterRegistrationBean<AFilter> filterRegistrationBean  = new FilterRegistrationBean<>();//注册一个过滤器filterRegistrationBean.setFilter(new AFilter());//过滤器的配置, 设置拦截的urlfilterRegistrationBean.addUrlPatterns("/*");//给过滤器起名字filterRegistrationBean.setName("AFilter");//设置过滤器的执行顺序filterRegistrationBean.setOrder(1);return filterRegistrationBean;}

当然也可以配置多个并且控制顺序

@Configuration
public class FilterConfig  {@BeanFilterRegistrationBean<AFilter> myFilterFilterRegistrationBean() {FilterRegistrationBean<AFilter> bean = new FilterRegistrationBean<>();bean.setFilter(new AFilter());bean.setOrder(-1);bean.setUrlPatterns(Arrays.asList("/*"));return bean;}@BeanFilterRegistrationBean<BFilter> myFilterFilterRegistrationBean2() {FilterRegistrationBean<BFilter> bean = new FilterRegistrationBean<>();bean.setFilter(new BFilter());bean.setOrder(-2);bean.setUrlPatterns(Arrays.asList("/hello"));return bean;}
}

 

FilterRegistrationBean 扩展

Spring Boot 为了方便大家向 Servlet 容器中注册 Servlet、Filter 以及 Listener,提供了一个 Bean 注册的抽象类 RegistrationBean,如下:

public abstract class RegistrationBean implements ServletContextInitializer, Ordered {private int order = Ordered.LOWEST_PRECEDENCE;private boolean enabled = true;@Overridepublic final void onStartup(ServletContext servletContext) throws ServletException {String description = getDescription();if (!isEnabled()) {logger.info(StringUtils.capitalize(description) + " was not registered (disabled)");return;}register(description, servletContext);}protected abstract String getDescription();protected abstract void register(String description, ServletContext servletContext);public void setEnabled(boolean enabled) {this.enabled = enabled;}public boolean isEnabled() {return this.enabled;}public void setOrder(int order) {this.order = order;}@Overridepublic int getOrder() {return this.order;}}

 

RegistrationBean 实现了 ServletContextInitializer 接口,在 Servlet 启动时,RegistrationBean#onStartup 方法会被调用,进而完成 Filter、Servlet 以及 Listener 的注册。
    enabled 属性可以理解为一个开关,设置为 false 相当于关闭组件注册。

RegistrationBean 有众多的实现类,我们之前使用的 FilterRegistrationBean 只是其中之一:

实现类的作用一目了然:

    ServletListenerRegistrationBean 用来注册监听器。
    ServletRegistrationBean 用来注册 Servlet。
    DispatcherServletRegistrationBean 用来注册 DispatcherServlet。
    FilterRegistrationBean 用来注册过滤器。
    DelegatingFilterProxyRegistrationBean 则用来注册 DelegatingFilterProxy,DelegatingFilterProxy 在 Spring Security、Spring Session、Shiro 等整合时非常有用。
 

6、过滤器实际项目场景使用举例

使用filter实现登录校验

三、监听器

Listener监听器也是Servlet层面的,可以用于监听Web应用中某些对象、信息的创建、销毁和修改等动作发生,然后做出相应的响应处理。可以在这些事件发生前和发生后进行处理。

用途:

1、用于统计在线人数和在线用户,

2、系统启动时加载初始化信息,

3、统计网站访问量,

4、记录用户访问路径

根据监听对象,将监听器分为3类:

第一类:ServletContext:对应application,实现接口ServletContextListener。在整个Web服务中只有一个,在Web服务关闭时销毁。可用于做数据缓存,例如结合redis,在Web服务创建时从数据库拉取数据到缓存服务器。

第二类:HttpSession:对应session会话,实现接口HttpSessionListener。在会话起始时创建,一端关闭会话后销毁。可用作获取在线用户数量。

第三类:ServletRequest:对应request,实现接口ServletRequestListener。request对象是客户发送请求时创建的,用于封装请求数据,请求处理完毕后销毁。可用作封装用户信息。

在写Listener的类时,有两种方式。

第一种是只加@Component;

第二种是 @WebListener 和 @ServletComponentScan 配合使用。

不过实现接口则根据监听对象区分,如:ServletContextListener、HttpSessionListener和ServletRequestListener。

 
import javax.servlet.annotation.WebListener;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;@WebListener()
public class MyListener implements HttpSessionListener{public static int online = 0;@Overridepublic void sessionCreated(HttpSessionEvent se) {System.out.println("创建session,在线用户数:" + (++online));}@Overridepublic void sessionDestroyed(HttpSessionEvent se) {System.out.println("销毁session,在线用户数:" + (--online));online--;}
}

启动类

 
@SpringBootApplication
@ServletComponentScan("com.demo.listener") //需要扫描包
public class SpringBoot1Application {public static void main(String[] args) {SpringApplication.run(SpringBoot1Application.class, args);}}

 

这里我们再补充一下常用的监听器接口:

1.ServletContextListener -- 监听servletContext对象的创建以及销毁

    1.1    contextInitialized(ServletContextEvent arg0)   -- 创建时执行

    1.2    contextDestroyed(ServletContextEvent arg0)  -- 销毁时执行

2.HttpSessionListener  -- 监听session对象的创建以及销毁

    2.2   sessionCreated(HttpSessionEvent se)   -- 创建时执行

    2.2   sessionDestroyed(HttpSessionEvent se) -- 销毁时执行

3.ServletRequestListener -- 监听request对象的创建以及销毁

    3.1    requestInitialized(ServletRequestEvent sre) -- 创建时执行

    3.2    requestDestroyed(ServletRequestEvent sre) -- 销毁时执行

4.ServletContextAttributeListener  -- 监听servletContext对象中属性的改变

    4.1    attributeAdded(ServletContextAttributeEvent event) -- 添加属性时执行

    4.2    attributeReplaced(ServletContextAttributeEvent event) -- 修改属性时执行

    4.3    attributeRemoved(ServletContextAttributeEvent event) -- 删除属性时执行

5.HttpSessionAttributeListener  --监听session对象中属性的改变

    5.1    attributeAdded(HttpSessionBindingEvent event) -- 添加属性时执行

    5.2    attributeReplaced(HttpSessionBindingEvent event) -- 修改属性时执行

    5.3    attributeRemoved(HttpSessionBindingEvent event) -- 删除属性时执行

6.ServletRequestAttributeListener  --监听request对象中属性的改变

    6.1    attributeAdded(ServletRequestAttributeEvent srae) -- 添加属性时执行

    6.2    attributeReplaced(ServletRequestAttributeEvent srae) -- 修改属性时执行

    6.3    attributeRemoved(ServletRequestAttributeEvent srae) -- 删除属性时执行

 

四、拦截器

1、拦截器作用

过滤器是拦截所有请求,而拦截器是拦截在进入到前端控制器之后的请求,

Interceptor和Filter、Listener有本质上的不同,Filter、Listener都是依赖于Servlet容器,而Interceptor则是依赖于Spring框架,是aop的一种表现,当某个方法或字段被访问时进行拦截,在之前 和 在之后 加入某些操作

用途:权限验证,判断用户是否登录,或者再做某一操作时要确定满足某一定的条件,基于Java的动态代理实现的。

2、拦截器执行流程

3、拦截器拦截路径

 拦截器可以根据需求配置不同的拦截路径

 

4、拦截器的使用

首先通过实现 HandlerInterceptor接口声明拦截器的类,实现preHandle、postHandle和afterCompletion方法。然后通过配置类WebMvcConfigurer接口,实现addInterceptors方法配置拦截器

 
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;@Component
public class InterceptorTest  implements HandlerInterceptor {/*** 在请求处理之前进行调用(Controller方法调用之前)* 预处理回调方法,实现处理器的预处理* 返回值:true表示继续流程;false表示流程中断,不会继续调用其他的拦截器或处理器*/@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)throws Exception {System.out.println("开始拦截.........");String name = MyCookie.getCookieByKey(request,response,"name");String password = MyCookie.getCookieByKey(request,response,"password");//如果session中没有user,表示没登陆if (password == null|| name == null){//这个方法返回false表示忽略当前请求,如果一个用户调用了需要登陆才能使用的接口,如果他没有登陆这里会直接忽略掉//当然你可以利用response给用户返回一些提示信息,告诉他没登陆request.getRequestDispatcher("/interceptor/to_login").forward(request, response);return false;}else {return true;//放行}}/*** 请求处理之后进行调用,但是在视图被渲染之前(Controller方法调用之后)* 后处理回调方法,实现处理器(controller)的后处理,但在渲染视图之前* 此时我们可以通过modelAndView对模型数据进行处理或对视图进行处理*/@Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,ModelAndView modelAndView) throws Exception {// TODO Auto-generated method stubSystem.out.println("return前");}/*** 在整个请求结束之后被调用,也就是在DispatcherServlet 渲染了对应的视图之后执行(主要是用于进行资源清理工作)* 整个请求处理完毕回调方法,即在视图渲染完毕时回调,* 如性能监控中我们可以在此记录结束时间并输出消耗时间,* 还可以进行一些资源清理,类似于try-catch-finally中的finally,* 但仅调用处理器执行链中*/@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)throws Exception {// TODO Auto-generated method stubSystem.out.println("操作完之后,可以用于资源清理");}
}

然后将这个组件加入到boot中,在boot1版本中 通过继承WebmvcConfigureAdapter实现一个web配置,例如我们配置上面的拦截器

@Configuration //声明这是一个配置
public class LoginInterceptorConfig extends WebMvcConfigurerAdapter {
@Resource
private LoginInterceptor loginInterceptor;@Override
public void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(loginInterceptor).addPathPatterns("/admin/**").excludePathPatterns("/admin").excludePathPatterns("/admin/login");
}}

 或者直接使用匿名类的方式

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;/*** 自定义一个登陆拦截器*/
@Configuration //声明这是一个配置
public class LoginInterceptor extends WebMvcConfigurerAdapter {/*用来添加拦截器的方法InterceptorRegistry registry拦截器注册*/@Overridepublic void addInterceptors(InterceptorRegistry registry) {//使用匿名内部类创建要给拦截器HandlerInterceptor loginInterceptor = new HandlerInterceptor() {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object o) throws Exception {//判断session中是否存在用户if (request.getSession().getAttribute("user") == null) {response.sendRedirect("/admin");return false;}return true;}@Overridepublic void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {}@Overridepublic void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {}};registry.addInterceptor(loginInterceptor).addPathPatterns("/admin/**").excludePathPatterns("/admin").excludePathPatterns("/admin/login");}
}

 对于Sprinboot2版本,第一步还是定义一个拦截器组件。

第二不再是通过继承WebmvcConfigureAdapter实现一个web配置,而是实现接口WebMvcConfigurer增加一个配置

@Configuration
public class WebConfig implements WebMvcConfigurer {//引入我们的拦截器组件@Resourceprivate LoginInterceptor loginInterceptor;
//实现拦截器配置方法@Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(loginInterceptor).addPathPatterns("/admin/**").excludePathPatterns("/admin").excludePathPatterns("/admin/login");}
}

踩坑5--springboot2.xl登陆拦截器中排除静态资源的几种情况整理 - 百度文库 (baidu.com) 

5、拦截器使用场景举例

Filter与Interceptor区别

1.接口范围不同:过滤器需要实现Filter接口,而拦截器需要实现HandlerInterceptor接口。

2.拦截范围不同:过滤器Filter会拦截所有的资源,而Interceptor只会拦截Spring环境中的资源

相关文章:

Springboot中使用拦截器、过滤器、监听器

一、Servlet、Filter&#xff08;过滤器&#xff09;、 Listener&#xff08;监听器&#xff09;、Interceptor&#xff08;拦截器&#xff09; Javaweb三大组件&#xff1a;servlet、Filter&#xff08;过滤器&#xff09;、 Listener&#xff08;监听器&#xff09; Spring…...

代码随想录二刷day45

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、力扣70. 爬楼梯二、力扣322. 零钱兑换三、力扣279. 完全平方数 前言 一、力扣70. 爬楼梯 class Solution {public int climbStairs(int n) {int[] dp new…...

泊车功能专题介绍 ———— AVP系统基础数据交互内容

文章目录 系统架构系统功能描述云端子系统车辆子系统场端子系统用户APP 工作流程基础数据交互内容AVP 系统基础数据交互服务车/用户 - 云基础数据交互内容车位查询工作流程技术要求数据交互要求 车位预约工作流程技术要求数据交互要求 取消预约工作流程技术要求数据交互要求 泊…...

蓝桥杯每日一题2023.10.6

题目描述 门牌制作 - 蓝桥云课 (lanqiao.cn) 题目分析 #include<bits/stdc.h> using namespace std; int ans; int main() {for(int i 1; i < 2020; i ){int x i;while(x){int a x % 10;if(a 2)ans ;x / 10;}}cout << ans;return 0; } 题目描述 既约分数…...

7、【Qlib】【主要组件】Data Layer:数据框架与使用

7、【主要组件】Data Layer&#xff1a;数据框架与使用 简介数据准备Qlib 格式数据Qlib 格式数据集自动更新日频率数据将 CSV 格式转换为 Qlib 格式股票池&#xff08;市场&#xff09;多股票模式 数据API数据检索特征过滤器 数据加载器QlibDataLoaderStaticDataLoaderInterfac…...

Kubernetes安装部署 1

本文主要描述kubernetes的安装部署&#xff0c;kubernetes的安装部署主要包括三个关键组件&#xff0c;其中&#xff0c;包括kubeadm、kubelet、kubectl&#xff0c;这三个组件的功能描述如下所示&#xff1a; Kubeadm 用于启动与管理kubernetes集群 Kubelet 运行在所有集群的…...

在VS Code中优雅地编辑csv文件

文章目录 Rainbow csv转表格CSV to Tablecsv2tableCSV to Markdown Table Edit csv 下面这些插件对csv/tsv/psv都有着不错的支持&#xff0c;这几种格式的主要区别是分隔符不同。 功能入口/使用方法Rainbow csv按列赋色右键菜单CSV to Table转为ASCII表格指令CSV to Markdown …...

LCR 128.库存管理 I

​题目来源&#xff1a; leetcode题目&#xff0c;网址&#xff1a;LCR 128. 库存管理 I - 力扣&#xff08;LeetCode&#xff09; 解题思路&#xff1a; 数组可以分割成两段的升序连续子数组&#xff0c;找到两个子数组的开始元素并返回较小者即可。 解题代码&#xff1a; …...

eigen::Affine3d 转换

平移eigen::vector3d和四元数Eigen::Quaterniond 转 eigen::Affine3d Eigen::Vector3d t Eigen::Vector3d::Zero(); Eigen::Quaterniond q Eigen::Quaterniond ::Identity();Eigen::Affine3d affine3d t * q.toRotationMatrix(); Eigen::Matrix4d 转 eigen::Affine3d Eige…...

【Python从入门到进阶】38、selenium关于Chrome handless的基本使用

接上篇《37、selenium关于phantomjs的基本使用》 上一篇我们介绍了有关phantomjs的相关知识&#xff0c;但由于selenium已经放弃PhantomJS&#xff0c;本篇我们来学习Chrome的无头版浏览器Chrome Handless的使用。 一、Chrome Headless简介 Chrome Headless是一个无界面的浏览…...

给Python项目创建一个虚拟环境(enev)

给Python项目创建一个虚拟环境&#xff08;enev&#xff09; 为您的Python项目创建一个虚拟环境是一种良好的实践&#xff0c;可以隔离项目的依赖项&#xff0c;以确保它们不会干扰全局Python环境或其他项目。您可以使用venv模块来创建虚拟环境。以下是在Linux上创建虚拟环境的…...

【RK3588】YOLO V5在瑞芯微板子上部署问题记录汇总

YOLO V5训练模型部署到瑞芯微的板子上面&#xff0c;官方是有给出案例和转过详情的。并且也提供了Python版本的推理代码&#xff0c;以及C语言的代码。 但是&#xff0c;对于转换过程中的细节&#xff0c;哪些需要改&#xff1f;怎么改&#xff1f;如何改&#xff0c;和为什么…...

别人做的百度百科词条信息不全,如何更正自己的百度百科词条

很多人自己的百度百科词条是别人上传上去的&#xff0c;自己压根不知道&#xff0c;而且里面的信息内容要么不全&#xff0c;要么是有错漏的&#xff0c;但自己想要更正自己的百度百科词条又不知道如何更正&#xff0c;下面洛希爱做百科网和大家介绍一些百科经验知识。 首先百…...

[论文精读]U-Net: Convolutional Networks for BiomedicalImage Segmentation

论文原文&#xff1a;U-Net: Convolutional Networks for Biomedical Image Segmentation (arxiv.org) 英文是纯手打的&#xff01;论文原文的summarizing and paraphrasing。可能会出现难以避免的拼写错误和语法错误&#xff0c;若有发现欢迎评论指正&#xff01;文章偏向于笔…...

Godot Identifier “File“ not declared in the current scope.

解决方案&#xff1a; f FileAccess.open(savedir, FileAccess.READ)...

Java ORM Bee,多表关联更新

Bee V2.1.8 增加支持多表的update, insert, delete; 使用FK注解进行关联. 如果子实体没有用上FK声明的字段(即FK的字段没有值),则不执行,防止更新到多余记录 外键有一个没有设置时&#xff0c;跳过。 更多实例,请查看样例工程:https://gitee.com/automvc/bee-exam 或:h…...

Java 读取excel文件

导入&#xff1a; 先导入依赖&#xff1a; <!-- 文件上传 --> <dependency><groupId>org.apache.httpcomponents</groupId><artifactId>httpmime</artifactId><version>4.5.7</version> </dependency> <!-- JSON -…...

PageRank(上):数据分析 | 数据挖掘 | 十大算法之一

⭐️⭐️⭐️⭐️⭐️欢迎来到我的博客⭐️⭐️⭐️⭐️⭐️ 🐴作者:秋无之地 🐴简介:CSDN爬虫、后端、大数据领域创作者。目前从事python爬虫、后端和大数据等相关工作,主要擅长领域有:爬虫、后端、大数据开发、数据分析等。 🐴欢迎小伙伴们点赞👍🏻、收藏⭐️、…...

吃鸡达人专享!提高战斗力,分享干货,查询装备皮肤,保护账号安全!

大家好&#xff01;作为专业吃鸡行家&#xff0c;我将为您带来一些热门话题和实用内容&#xff0c;帮助您提升游戏战斗力&#xff0c;分享顶级游戏作战干货&#xff0c;并提供便捷的作图工具和查询服务。让我们一起享受吃鸡的乐趣&#xff01; 首先&#xff0c;我要推荐一款绝地…...

力扣第101题 c++ 递归 迭代 双方法 +注释 ~

题目 101. 对称二叉树 简单 给你一个二叉树的根节点 root &#xff0c; 检查它是否轴对称。 示例 1&#xff1a; 输入&#xff1a;root [1,2,2,3,4,4,3] 输出&#xff1a;true示例 2&#xff1a; 输入&#xff1a;root [1,2,2,null,3,null,3] 输出&#xff1a;false提示&a…...

Go:实现SMTP邮件发送订阅功能(包含163邮箱、163企业邮箱、谷歌gmail邮箱)

需求很简单&#xff0c;就是用户输入自己的邮箱后&#xff0c;使用官方邮箱给用户发送替邮件模版 目录 前置邮件模版邮箱开启SMTP服务163邮箱163企业邮箱谷歌gmail邮箱腾讯企业邮箱-失败其他邮箱-未操作 邮件发送核心代码config.yaml配置读取邮件相关配置发送邮件 附录 前置 邮…...

Scala第十六章节

Scala第十六章节 scala总目录 文档资料下载 章节目标 掌握泛型方法, 类, 特质的用法了解泛型上下界相关内容了解协变, 逆变, 非变的用法掌握列表去重排序案例 1. 泛型 泛型的意思是泛指某种具体的数据类型, 在Scala中, 泛型用[数据类型]表示. 在实际开发中, 泛型一般是结合…...

C语言 实现 链 显示 效果 查找 修改 删除

显示所有信息 2023年10月1日的描述:今天放假 2023年10月2日的描述:今天有体育 2023年10月3日的描述:今天有数学 2023年10月4日的描述:今天有语文 2023年10月5日的描述:今天有政治 2023年10月6日的描述:今天交学费 2023年10月7日的描述:今天周末 2023年10月8日的描述:今天给家里…...

CSS基础语法第一天

目录 一、CSS 简介 1.1 CSS简介 1.2 CSS语法 ​1.3 CSS 语法规范 1.4 CSS 代码风格 1.4.1 样式格式书写 1.4.2 样式大小写 ​1.4.3 空格规范 二、CSS 基础选择器 2.1选择器分类 2.2标签选择器 2.3 类选择器 2.4 id选择器 2.5 通配符选择器 三、盒子尺寸和背景色 …...

Leetcode 1492.n的第k个因子

给你两个正整数 n 和 k 。 如果正整数 i 满足 n % i 0 &#xff0c;那么我们就说正整数 i 是整数 n 的因子。 考虑整数 n 的所有因子&#xff0c;将它们 升序排列 。请你返回第 k 个因子。如果 n 的因子数少于 k &#xff0c;请你返回 -1 。 示例 1&#xff1a; 输入&#…...

十一工具箱流量主小程序源码

无授权&#xff0c;去过滤机制版本 看到网上发布的都是要授权的 朋友叫我把他去授权&#xff0c;能用就行 就把过滤去了 这样就不用授权 可以免费使用 白嫖党专属 一切接口可用&#xff0c;无需担心不能用 授权者不关站一直可以用 源码下载&#xff1a;https://download.csdn.…...

10.5汇编语言整理

【汇编语言相关语法】 1.汇编语言的组成部分 1.伪操作&#xff1a;不参与程序的执行&#xff0c;但是用于告诉编译器程序该怎么编译 .text .global .end .if .else .endif .data 2.汇编指令 编译器将一条汇编指令编译成一条机器码&#xff0c;在内存里一条指令占4字节内存&…...

Connect to 127.0.0.1:1080 [/127.0.0.1] failed: Connection refused: connect

报错信息 A problem occurred configuring root project CourseSelection. > Could not resolve all artifacts for configuration :classpath.> Could not resolve com.android.tools.build:gradle:3.6.1.Required by:project :> Could not resolve com.android.tool…...

驱动器类产品的接口EMC拓扑方案

驱动器类产品的接口EMC拓扑方案 1. 概述 本文以高压伺服驱动器和变频器类产品为例&#xff0c;对常用端口滤波拓扑方案进行总结&#xff0c;后续根据不同的应用场景可进行适当删减&#xff0c;希望对大家有帮助。 2. 驱动器验证等级 本文推荐拓扑的实验结果&#xff0c;满足…...

2023最新ICP备案查询系统源码 附教程 Thinkphp框架

2023最新ICP备案查询系统源码 附教程 thinkphp框架 本系统支持网址备案&#xff0c;小程序备案&#xff0c;APP备案查询&#xff0c;快应用备案查询 优势&#xff1a; 响应速度快&#xff0c;没有延迟&#xff0c;没有缓存&#xff0c;数据与官方同步 源码下载&#xff1a;ht…...

视频拍摄要求/seo课程培训入门

1.Mean Average Precision (MAP) AP∑nij1P(j).yi,j∑nij1yi,j 其中&#xff0c; yi,j:排序中第j个元素对于查询i是否是相关的&#xff1b;相关为1&#xff0c;不相关为0。 P(j)∑k:πi(k)≤πi(j)y(i,k)πi(j) 其中&#xff0c; πi(j) 为j的排序位置。 例如&#xff0c; r…...

高端装饰公司网站设计/北京百度网站排名优化

首先要声明一下这是从http://www.cnblogs.com/yufeihlf/p/5949984.html拷贝的。 在这里只是自己的一个笔记&#xff0c;方便日后添加、修改内容。 Robot Framework 安装流程 http://www.cnblogs.com/kill0001000/p/7666217.html 总结下Robot Framework最基本的用法&#xff0c;…...

学历提升文案/seo排名优化是什么意思

我个人很讨厌在Dock上放置程序的快捷方式。因为当Dock上的图标超过7个之后就很难一眼看全──Dock上过多的图标不仅起不到“快捷”的作用&#xff0c;反倒碍事。所以&#xff0c;基本上都是用Spotlight呼出程序&#xff08;我选择这种方式的原因在于它可以让我的手不用开键盘就…...

企业门户网站建设流程/一份完整的品牌策划方案

实验报告&#xff1a;二叉树创建与遍历 一、问题描述 二叉树是一种实用范围很广的非线性结构&#xff0c;一棵非空二叉树有也只有一个根结点&#xff0c;每个结点最多有两个子树&#xff0c;我们称为左子树与右子树&#xff0c;当一个结点的左、右子树都是空的时&#xff0c;沃…...

网站ip地址 a记录/营销推广方案

2023/4/12 09:37:43 网络安全测试 2023/4/12 09:38:19 网络安全测试是指通过模拟攻击&#xff0c;对计算机系统、网络、应用程序等进行安全评估&#xff0c;发现其中存在的漏洞和安全风险&#xff0c;并提供修复建议的过程。网络安全测试可以帮助企业和组织发现和解决网络安…...

java网站开发视频转码/宁波网站推广方式怎么样

这 10 个 SOA 设计模式是如此之重要&#xff0c;其应用是如此之广泛&#xff0c;以至于它们都有些显而易见了。 1. 服务无关 服务无关实现对多种业务通用的逻辑。将服务无关的逻辑分离成离散的服务以方便服务的重用和整合。 原则&#xff1a;复用&#xff0c;服务整合 2. …...