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环境中的资源

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

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

相关文章

nodejs在pdf中绘制表格

需求 之前我已经了解过如何在pdf模板中填写字段了 nodejs根据pdf模板填入中文数据并生成新的pdf文件https://blog.csdn.net/ArmadaDK/article/details/132456324 但是当我具体使用的时候&#xff0c;我发现我的模板里面有表格&#xff0c;表格的长度是不固定的&#xff0c;所…

Bluespec SytemVerilog 握手协议接口转换

01、引言 由于接口控制信号上的差异&#xff0c;要实现Bluespec SystemVerilog(BSV)生成的代码和外部Verilog代码之间的正确交互是一件比较麻烦同时容易出错的事情。在BSV中, 模块之间的交互都是基于Action或ActionValue这两类method完成。下图展示了使用BSV设计的某一模块的接…

【JavaEE】HTML

JavaWeb HTML 超文本标记语言 超文本&#xff1a;文本、声音、图片、视频、表格、连接标记&#xff1a;有许许多多的标签组成 vscode开发工具搭建 因为我使用的IDEA是社区版&#xff0c;代码高亮补全缩进都有些问题&#xff0c;使用vscode是最好的选择~ 安装 Visual Stu…

聊聊并发编程——并发容器和阻塞队列

目录 一.ConcurrentHashMap 1.为什么要使用ConcurrentHashMap&#xff1f; 2.ConcurrentHashMap的类图 3.ConcurrentHashMap的结构图 二.阻塞队列 Java中的7个阻塞队列 ArrayBlockingQueue&#xff1a;一个由数组结构组成的有界阻塞队列。 LinkedBlockingQueue&#xf…

FPGA 图像缩放 千兆网 UDP 网络视频传输,基于RTL8211 PHY实现,提供工程和QT上位机源码加技术支持

目录 1、前言版本更新说明免责声明 2、相关方案推荐UDP视频传输--无缩放FPGA图像缩放方案我这里已有的以太网方案 3、设计思路框架视频源选择ADV7611 解码芯片配置及采集动态彩条跨时钟FIFO图像缩放模块详解设计框图代码框图2种插值算法的整合与选择 UDP协议栈UDP视频数据组包U…

Flink中的状态一致性

1.概念 一致性其实就是结果的正确性。对于分布式系统而言&#xff0c;从不同节点读取时总能得到相同的值&#xff1b;而对于事务而言&#xff0c;是要求提交更新操作后&#xff0c;能够读取到新的数据。 有状态的流处理&#xff0c;内部每个算子任务都可以有自己的状态。对于流…

Source Insight 工具栏图标功能介绍

这篇文章并不介绍 Source Insight 的具体使用方法&#xff0c;这类教程网上有很多&#xff0c;这里只分析 Souce Insight 工具栏图标的功能。 文章目录 Source Insight 简介Souce Insight 工具栏文件操作新建&#xff08;CtrlN&#xff09;打开&#xff08;CtrlO&#xff09;保…

Java 实现遍历一个文件夹,文件夹有100万数据,获取到修改时间在2天之内的数据

目录 1 需求2 实现1&#xff08;第一种方法&#xff09;2 实现2 &#xff08;推荐使用这个&#xff0c;快&#xff09;3 实现3&#xff08;推荐&#xff09; 1 需求 现在有一个文件夹&#xff0c;里面会一直存数据&#xff0c;动态的存数据&#xff0c;之后可能会达到100万&am…

【PyTorch实战演练】使用Cifar10数据集训练LeNet5网络并实现图像分类(附代码)

文章目录 0. 前言1. Cifar10数据集1.1 Cifar10数据集下载1.2 Cifar10数据集解析 2. LeNet5网络2.1 LeNet5的网络结构2.2 基于PyTorch的LeNet5网络编码 3. LeNet5网络训练及输出验证3.1 LeNet5网络训练3.2 LeNet5网络验证 4. 完整代码4.1 训练代码4.1 验证代码 0. 前言 按照国际…

紫光同创FPGA图像视频采集系统,基于OV7725实现,提供工程源码和技术支持

目录 1、前言免责声明 2、设计思路框架视频源选择OV7725摄像头配置及采集动态彩条HDMA图像缓存输入输出视频HDMA缓冲FIFOHDMA控制模块HDMI输出 3、PDS工程详解4、上板调试验证并演示准备工作静态演示动态演示 5、福利&#xff1a;工程源码获取 紫光同创FPGA图像视频采集系统&am…

mysql面试题7:MySQL事务原理是什么?MySQL事务的隔离级别有哪些?

该文章专注于面试,面试只要回答关键点即可,不需要对框架有非常深入的回答,如果你想应付面试,是足够了,抓住关键点 面试官:MySQL事务原理是什么? MySQL事务的原理是基于ACID(原子性、一致性、隔离性、持久性)特性来实现的,具体原理如下: Atomicity(原子性):事务…

给奶牛做直播之三

​一、前言 上一篇给牛奶做直播之二 主要讲用RTMP搭建点播服务器&#xff0c;整了半天直播还没上场&#xff0c;今天不讲太多理论的玩意&#xff0c;奶牛今天放假了也不出场&#xff0c;就由本人亲自上场来个直播首秀&#xff0c;见下图&#xff0c;如果有兴趣的话&#xff0…

YOLOV8-DET转ONNX和RKNN

目录 1. 前言 2.环境配置 (1) RK3588开发板Python环境 (2) PC转onnx和rknn的环境 3.PT模型转onnx 4. ONNX模型转RKNN 6.测试结果 1. 前言 yolov8就不介绍了&#xff0c;详细的请见YOLOV8详细对比&#xff0c;本文章注重实际的使用&#xff0c;从拿到yolov8的pt检测模型&…

施耐德电气:勾勒未来工业愿景,赋能中国市场

9月19日&#xff0c;第23届中国国际工业博览会&#xff08;简称“工博会”&#xff09;在上海隆重召开。作为全球能源管理和自动化领域的数字化转型专家&#xff0c;施耐德电气在工博会现场全方位展现了自身对未来工业的全新视野与深刻见解&#xff0c;不仅展示了其贯通企业设计…

字节一面:深拷贝浅拷贝的区别?如何实现一个深拷贝?

前言 最近博主在字节面试中遇到这样一个面试题&#xff0c;这个问题也是前端面试的高频问题&#xff0c;我们经常需要对后端返回的数据进行处理才能渲染到页面上&#xff0c;一般我们会讲数据进行拷贝&#xff0c;在副本对象里进行处理&#xff0c;以免玷污原始数据&#xff0c…

arduino - UNO-R3,mega2560-R3,NUCLEO-H723ZG的arduino引脚定义区别

文章目录 arduino - UNO-R3,mega2560-R3,NUCLEO-H723ZG的引脚定义区别概述笔记NUCLEO-H723ZGmega2560-R3UNO-R3经过比对, 这2个板子(NUCLEO-H723ZG, mega2560-R3)都是和UNO-R3的arduino引脚定义一样的.mega2560-r3和NUCLEO-H723ZG的区别补充arduino uno r3的纯数字IO和模拟IO作…

uniapp iOS离线打包——原生工程配置

uniapp iOS离线打包&#xff0c;如何配置项目工程&#xff1f; 文章目录 uniapp iOS离线打包&#xff0c;如何配置项目工程&#xff1f;工程配置效果图DebugRelease 配置工程配置 Appkey应用图标模块及三方SDK配置未配置模块错误配置模块TIP: App iOS 离线打包 前提&#xff1a…

Linux服务器安装Anaconda 配置远程jupyter lab使用虚拟环境

参考的博客&#xff1a; Linux服务器安装Anaconda 并配置远程jupyter lab anaconda配置远程访问jupyter&#xff0c;并创建虚拟环境 理解和创建&#xff1a;Anaconda、Jupyterlab、虚拟环境、Kernel 下边是正文了。 https://www.anaconda.com/download是官网网址&#xff0c;可…

华为云云耀云服务器L实例评测|云耀云服务器L实例部署Linux管理面板mdserver-web

华为云云耀云服务器L实例评测&#xff5c;云耀云服务器L实例部署Linux管理面板mdserver-webl 一、云耀云服务器L实例介绍1.1 云耀云服务器L实例简介1.2 云耀云服务器L实例特点 二、mdserver-web介绍2.1 mdserver-web简介2.2 mdserver-web特点2.3 主要插件介绍 三、本次实践介绍…

机器学习之单层神经网络的训练:增量规则(Delta Rule)

文章目录 权重的调整单层神经网络使用delta规则的训练过程 神经网络以权值的形式存储信息,根据给定的信息来修改权值的系统方法称为学习规则。由于训练是神经网络系统地存储信息的唯一途径&#xff0c;因此学习规则是神经网络研究中的一个重要组成部分 权重的调整 &#xff08…