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

Spring MVC 中的拦截器的使用“拦截器基本配置” 和 “拦截器高级配置”

1. Spring MVC 中的拦截器的使用“拦截器基本配置” 和 “拦截器高级配置”

文章目录

  • 1. Spring MVC 中的拦截器的使用“拦截器基本配置” 和 “拦截器高级配置”
  • 2. 拦截器
  • 3. Spring MVC 中的拦截器的创建和基本配置
    • 3.1 定义拦截
    • 3.2 拦截器基本配置
    • 3.3 拦截器的高级配置
  • 4. Spring MVC中多个拦截器的执行顺序
    • 4.1 如果所有拦截器 preHandle( ) 方法 都返回 true时,多个拦截器的的执行顺序
    • 4.2 如果其中一个拦截器 preHandle ( ) 方法,返回 false,多个拦截器的的执行顺序
  • 5. 补充:源码分析
    • 5.1 方法执行顺序的源码分析
    • 5.2 拦截与放行的源码分析
    • 5.3 DispatcherServlet 和 HandlerExecutionChain 的部分源码:
  • 6. 总结:
  • 7. 最后:


2. 拦截器

拦截器(Interceptor) 类似于过滤器(Filter)

Spring MVC 的拦截器作用是在请求到达控制器之前或之后进行拦截,可以对请求和响应进行一些特定的处理。

拦截器可以用于很多场景下:

  1. 登录验证:对于需要登录才能访问的地址,使用拦截器可以判断用户是否已登录,如果未登录,则跳转到登录页面。
  2. 权限校验:根据用户权限对部分网址进行访问控制,拒绝未经授权的用户访问。
  3. 请求日志:记录请求信息,例如:请求地址,请求参数,请求时间等,用于排查问题和性能优化。
  4. 更改响应:可以对响应的内容进行修改,例如:添加头信息,调整响应内容格式等。

拦截器和过滤器的区别在于它们的作用层面不同:

  • 过滤器更注重在请求和响应的流程中进行处理,可以修改请求和响应的内容,例如:设置编码和字符集,请求头,状态码等。
  • 拦截器则更加侧重于对控制器进行前置或后置处理,在请求到达控制器之前或之后进行特定的操作,例如:打印日志,权限验证等。

Filter、Servlet、Interceptor、Controller的执行顺序:

在这里插入图片描述

3. Spring MVC 中的拦截器的创建和基本配置

3.1 定义拦截

实现org.springframework.web.servlet.HandlerInterceptor 接口,共有三个方法可以进行选择性的实现:

在这里插入图片描述

  • preHandle( ):处理器方法调用之前执行。只有该方法有返回值,返回值是布尔类型,true 表示放行,false 表示拦截
  • postHandle( ):处理器方法调用之后执行。
  • afterCompletion( ):渲染完成后执行。

3.2 拦截器基本配置

第一步:编写拦截器,该拦截器要实现org.springframework.web.servlet.HandlerInterceptor 接口

在这里插入图片描述

package com.rainbowsea.springmvc.interceptors;import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;public class Interceptor1 implements HandlerInterceptor {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {System.out.println("Interceptor1's preHandle!");return true;}@Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {System.out.println("Interceptor1's postHandle!");}@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {System.out.println("Interceptor1's afterCompletion!");}
}

在 Spring MVC 中拦截器的基本配置有两种方式:

  • 第一种方式是:通过 xml 进行配置
  • 第二种方式是:通过 @Component 注解 + xml 文件进行配置

第一种方式:通过 xml 进行配置

需要注意的是:这个基本配置,默认情况下是拦截所有请求的。

在 springmvc.xml 文件中进行如下配置:

<mvc:interceptors><bean class="com.powernode.springmvc.interceptors.Interceptor1"/>
</mvc:interceptors>

在这里插入图片描述

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:context="http://www.springframework.org/schema/context"xmlns:mvc="http://www.springframework.org/schema/mvc"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache.xsd http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd"><!--    组件扫描--><context:component-scanbase-package="com.rainbowsea.springmvc.controller,com.rainbowsea.springmvc.interceptors"></context:component-scan><!--    视图解析器--><bean id="thymeleafViewResolver" class="org.thymeleaf.spring6.view.ThymeleafViewResolver"><!--作用于视图渲染的过程中,可以设置视图渲染后输出时采用的编码字符集--><property name="characterEncoding" value="UTF-8"/><!--如果配置多个视图解析器,它来决定优先使用哪个视图解析器,它的值越小优先级越高--><property name="order" value="1"/><!--当 ThymeleafViewResolver 渲染模板时,会使用该模板引擎来解析、编译和渲染模板--><property name="templateEngine"><bean class="org.thymeleaf.spring6.SpringTemplateEngine"><!--用于指定 Thymeleaf 模板引擎使用的模板解析器。模板解析器负责根据模板位置、模板资源名称、文件编码等信息,加载模板并对其进行解析--><property name="templateResolver"><bean class="org.thymeleaf.spring6.templateresolver.SpringResourceTemplateResolver"><!--设置模板文件的位置(前缀)--><property name="prefix" value="/WEB-INF/templates/"/><!--设置模板文件后缀(后缀),Thymeleaf文件扩展名不一定是html,也可以是其他,例如txt,大部分都是html--><property name="suffix" value=".html"/><!--设置模板类型,例如:HTML,TEXT,JAVASCRIPT,CSS等--><property name="templateMode" value="HTML"/><!--用于模板文件在读取和解析过程中采用的编码字符集--><property name="characterEncoding" value="UTF-8"/></bean></property></bean></property></bean><!--    配置拦截器--><mvc:interceptors><!--        基本配置,第一种方式注意:基本配置,默认情况下是拦截所有请求的--><bean class="com.rainbowsea.springmvc.interceptors.Interceptor1"></bean></mvc:interceptors>
</beans>

编写对应的 Controller 控制器进行测试:

在这里插入图片描述

package com.rainbowsea.springmvc.controller;import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;@Controller  // 交给 Spring IOC 容器管理
public class IndexController {@RequestMapping("/index")public String toIndex() {System.out.println("IndexController#toIndex()  ---> 处理器方法执行了");return "index";}@RequestMapping("ok")public String toOK() {System.out.println("IndexController#OK() ---> 处理器方法执行了");return "ok";}
}

运行测试:

在这里插入图片描述

在这里插入图片描述

第二种方式是:通过 @Component 注解 + xml 文件进行配置

注意:同样的,对于这种基本配置来说,拦截器是拦截所有请求的。

第二种方式的前提:

  1. 前提1:包扫描,在 spring mvc 中配置组件扫描

在这里插入图片描述

  1. 前提2:使用 @Component 注解进行对 编写的拦截器类进行标注即可。
    在这里插入图片描述
  1. 两个前提都搞定了,就可以在 spring mvc.xml 文件中进行配置了。
  2. 在这里插入图片描述
<mvc:interceptors><ref bean="interceptor1"/>
</mvc:interceptors>

运行测试:

在这里插入图片描述

3.3 拦截器的高级配置

采用以上基本配置方式,拦截器是拦截所有请求路径的。如果要针对某些路径进行拦截,某些路径不拦截,某些路径拦截,可以采用高级配置:在 spring mvc.xml 文件当中进行配置

在这里插入图片描述

以上的配置表示,除 /ok 请求路径之外,剩下的路径全部拦截。

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:context="http://www.springframework.org/schema/context"xmlns:mvc="http://www.springframework.org/schema/mvc"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache.xsd http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd"><!--    组件扫描--><context:component-scanbase-package="com.rainbowsea.springmvc.controller,com.rainbowsea.springmvc.interceptors"></context:component-scan><!--    视图解析器--><bean id="thymeleafViewResolver" class="org.thymeleaf.spring6.view.ThymeleafViewResolver"><!--作用于视图渲染的过程中,可以设置视图渲染后输出时采用的编码字符集--><property name="characterEncoding" value="UTF-8"/><!--如果配置多个视图解析器,它来决定优先使用哪个视图解析器,它的值越小优先级越高--><property name="order" value="1"/><!--当 ThymeleafViewResolver 渲染模板时,会使用该模板引擎来解析、编译和渲染模板--><property name="templateEngine"><bean class="org.thymeleaf.spring6.SpringTemplateEngine"><!--用于指定 Thymeleaf 模板引擎使用的模板解析器。模板解析器负责根据模板位置、模板资源名称、文件编码等信息,加载模板并对其进行解析--><property name="templateResolver"><bean class="org.thymeleaf.spring6.templateresolver.SpringResourceTemplateResolver"><!--设置模板文件的位置(前缀)--><property name="prefix" value="/WEB-INF/templates/"/><!--设置模板文件后缀(后缀),Thymeleaf文件扩展名不一定是html,也可以是其他,例如txt,大部分都是html--><property name="suffix" value=".html"/><!--设置模板类型,例如:HTML,TEXT,JAVASCRIPT,CSS等--><property name="templateMode" value="HTML"/><!--用于模板文件在读取和解析过程中采用的编码字符集--><property name="characterEncoding" value="UTF-8"/></bean></property></bean></property></bean><!--    高级配置:指定一些路径被拦截,一些路径不拦截--><mvc:interceptors><mvc:interceptor><!--            /** 表示拦截所有路径--><mvc:mapping path="/**"/><!--            /ok 请求路径不拦截--><mvc:exclude-mapping path="/ok"/><!--            /index 请求路径拦截--><!--            <mvc:mapping path="/index"/>--><!--            设置对应的那个拦截器--><ref bean="interceptor1"></ref></mvc:interceptor></mvc:interceptors>
</beans>

运行测试:

在这里插入图片描述

4. Spring MVC中多个拦截器的执行顺序

这里我们为了探究,多个拦截器存在的时候的执行顺序,我们创建 3 个 拦截器。如下:

4.1 如果所有拦截器 preHandle( ) 方法 都返回 true时,多个拦截器的的执行顺序

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

配置多个拦截器

在这里插入图片描述

    <mvc:interceptors><!--        配置多个拦截器,这个是基本配置,默认是所有请求都会进行拦截处理--><ref bean="interceptor1"></ref><ref bean="interceptor2"></ref><ref bean="interceptor3"></ref></mvc:interceptors>
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:context="http://www.springframework.org/schema/context"xmlns:mvc="http://www.springframework.org/schema/mvc"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache.xsd http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd"><!--    组件扫描--><context:component-scanbase-package="com.rainbowsea.springmvc.controller,com.rainbowsea.springmvc.interceptors"></context:component-scan><!--    视图解析器--><bean id="thymeleafViewResolver" class="org.thymeleaf.spring6.view.ThymeleafViewResolver"><!--作用于视图渲染的过程中,可以设置视图渲染后输出时采用的编码字符集--><property name="characterEncoding" value="UTF-8"/><!--如果配置多个视图解析器,它来决定优先使用哪个视图解析器,它的值越小优先级越高--><property name="order" value="1"/><!--当 ThymeleafViewResolver 渲染模板时,会使用该模板引擎来解析、编译和渲染模板--><property name="templateEngine"><bean class="org.thymeleaf.spring6.SpringTemplateEngine"><!--用于指定 Thymeleaf 模板引擎使用的模板解析器。模板解析器负责根据模板位置、模板资源名称、文件编码等信息,加载模板并对其进行解析--><property name="templateResolver"><bean class="org.thymeleaf.spring6.templateresolver.SpringResourceTemplateResolver"><!--设置模板文件的位置(前缀)--><property name="prefix" value="/WEB-INF/templates/"/><!--设置模板文件后缀(后缀),Thymeleaf文件扩展名不一定是html,也可以是其他,例如txt,大部分都是html--><property name="suffix" value=".html"/><!--设置模板类型,例如:HTML,TEXT,JAVASCRIPT,CSS等--><property name="templateMode" value="HTML"/><!--用于模板文件在读取和解析过程中采用的编码字符集--><property name="characterEncoding" value="UTF-8"/></bean></property></bean></property></bean><mvc:interceptors><!--        配置多个拦截器,这个是基本配置,默认是所有请求都会进行拦截处理--><ref bean="interceptor1"></ref><ref bean="interceptor2"></ref><ref bean="interceptor3"></ref></mvc:interceptors>
</beans>

如果所有拦截器 preHandle 都返回 true

在这里插入图片描述

按照 springmvc.xml文件中配置的顺序,自上而下调用 preHandle:

在这里插入图片描述

在这里插入图片描述

4.2 如果其中一个拦截器 preHandle ( ) 方法,返回 false,多个拦截器的的执行顺序

Interceptor3 拦截器中的 preHandle()方法返回 false。其他两个拦截器返回 true.

在这里插入图片描述

规则:只要有一个拦截器preHandle返回false,任何postHandle都不执行。但返回false的拦截器的前面的拦截器按照逆序执行afterCompletion

在这里插入图片描述

  1. 只要有一个拦截器preHandle()方法,返回false,则任何拦截器的 postHandle()方法都不执行。但返回 false 的拦截器的前面的拦截器按照逆序执行afterCompletion

  2. 返回 false 拦截器,拦截住了,则其中的 Controllor控制器不执行了,其中的 postHandle

    一个也不会执行。而对应的 afterCompletion()方法,的执行是按照配置拦截器(自上而下)的倒序执行,但其中返回 false 的拦截器中的 afterCompletion()方法不会被执行

  3. 只要有一个拦截器preHandle返回false,任何postHandle都不执行。但返回false的拦截器的前面的拦截器按照逆序执行afterCompletion。只要有一个拦截器preHandle返回false,任何postHandle都不执行。但返回false的拦截器的前面的拦截器按照逆序执行afterCompletion

5. 补充:源码分析

5.1 方法执行顺序的源码分析

public class DispatcherServlet extends FrameworkServlet {protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {// 调用所有拦截器的 preHandle 方法if (!mappedHandler.applyPreHandle(processedRequest, response)) {return;}// 调用处理器方法mv = ha.handle(processedRequest, response, mappedHandler.getHandler());// 调用所有拦截器的 postHandle 方法mappedHandler.applyPostHandle(processedRequest, response, mv);// 处理视图processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);}private void processDispatchResult(HttpServletRequest request, HttpServletResponse response,@Nullable HandlerExecutionChain mappedHandler, @Nullable ModelAndView mv,@Nullable Exception exception) throws Exception {// 渲染页面render(mv, request, response);// 调用所有拦截器的 afterCompletion 方法mappedHandler.triggerAfterCompletion(request, response, null);}
}

5.2 拦截与放行的源码分析

public class DispatcherServlet extends FrameworkServlet {protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {// 调用所有拦截器的 preHandle 方法if (!mappedHandler.applyPreHandle(processedRequest, response)) {// 如果 mappedHandler.applyPreHandle(processedRequest, response) 返回false,以下的return语句就会执行return;}}
}
public class HandlerExecutionChain {boolean applyPreHandle(HttpServletRequest request, HttpServletResponse response) throws Exception {for (int i = 0; i < this.interceptorList.size(); i++) {HandlerInterceptor interceptor = this.interceptorList.get(i);if (!interceptor.preHandle(request, response, this.handler)) {triggerAfterCompletion(request, response, null);// 如果 interceptor.preHandle(request, response, this.handler) 返回 false,以下的 return false;就会执行。return false;}this.interceptorIndex = i;}return true;}
}

5.3 DispatcherServlet 和 HandlerExecutionChain 的部分源码:

public class DispatcherServlet extends FrameworkServlet {protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {// 按照顺序执行所有拦截器的preHandle方法if (!mappedHandler.applyPreHandle(processedRequest, response)) {return;}// 执行处理器方法mv = ha.handle(processedRequest, response, mappedHandler.getHandler());// 按照逆序执行所有拦截器的 postHanle 方法mappedHandler.applyPostHandle(processedRequest, response, mv);// 处理视图processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);}private void processDispatchResult(HttpServletRequest request, HttpServletResponse response,@Nullable HandlerExecutionChain mappedHandler, @Nullable ModelAndView mv,@Nullable Exception exception) throws Exception {// 渲染视图render(mv, request, response);// 按照逆序执行所有拦截器的 afterCompletion 方法mappedHandler.triggerAfterCompletion(request, response, null);}
}
public class HandlerExecutionChain {// 顺序执行 preHandleboolean applyPreHandle(HttpServletRequest request, HttpServletResponse response) throws Exception {for (int i = 0; i < this.interceptorList.size(); i++) {HandlerInterceptor interceptor = this.interceptorList.get(i);if (!interceptor.preHandle(request, response, this.handler)) {// 如果其中一个拦截器preHandle返回false// 将该拦截器前面的拦截器按照逆序执行所有的afterCompletiontriggerAfterCompletion(request, response, null);return false;}this.interceptorIndex = i;}return true;}// 逆序执行 postHanlevoid applyPostHandle(HttpServletRequest request, HttpServletResponse response, @Nullable ModelAndView mv) throws Exception {for (int i = this.interceptorList.size() - 1; i >= 0; i--) {HandlerInterceptor interceptor = this.interceptorList.get(i);interceptor.postHandle(request, response, this.handler, mv);}}// 逆序执行 afterCompletionvoid triggerAfterCompletion(HttpServletRequest request, HttpServletResponse response, @Nullable Exception ex) {for (int i = this.interceptorIndex; i >= 0; i--) {HandlerInterceptor interceptor = this.interceptorList.get(i);try {interceptor.afterCompletion(request, response, this.handler, ex);}catch (Throwable ex2) {logger.error("HandlerInterceptor.afterCompletion threw exception", ex2);}}}
}

6. 总结:

  1. 实现org.springframework.web.servlet.HandlerInterceptor 接口,共有三个方法可以进行选择性的实现:

    • preHandle( ):处理器方法调用之前执行。只有该方法有返回值,返回值是布尔类型,true 表示放行,false 表示拦截
    • postHandle( ):处理器方法调用之后执行。
    • afterCompletion( ):渲染完成后执行。
  2. 在 Spring MVC 中拦截器的基本配置有两种方式:

    • 第一种方式是:通过 xml 进行配置
    • 第二种方式是:通过 @Component 注解 + xml 文件进行配置
    • 对于这种基本配置来说,拦截器是拦截所有请求的。
  3. 拦截器的高级配置:采用以上基本配置方式,拦截器是拦截所有请求路径的。如果要针对某些路径进行拦截,某些路径不拦截,某些路径拦截,可以采用高级配置:在 spring mvc.xml 文件当中进行配置

  4. Spring MVC中多个拦截器的执行顺序:

    1. 如果所有拦截器 preHandle( ) 方法 都返回 true时,多个拦截器的的执行顺序:

      1. 按照 springmvc.xml文件中配置的顺序,自上而下调用 preHandle:

        在这里插入图片描述

  1. 如果其中一个拦截器 preHandle ( ) 方法,返回 false,多个拦截器的的执行顺序

    1. 只要有一个拦截器preHandle()方法,返回false,则任何拦截器的 postHandle()方法都不执行。但返回 false 的拦截器的前面的拦截器按照逆序执行afterCompletion
  2. 拦截器源码分析。

7. 最后:

“在这个最后的篇章中,我要表达我对每一位读者的感激之情。你们的关注和回复是我创作的动力源泉,我从你们身上吸取了无尽的灵感与勇气。我会将你们的鼓励留在心底,继续在其他的领域奋斗。感谢你们,我们总会在某个时刻再次相遇。”

在这里插入图片描述

相关文章:

Spring MVC 中的拦截器的使用“拦截器基本配置” 和 “拦截器高级配置”

1. Spring MVC 中的拦截器的使用“拦截器基本配置” 和 “拦截器高级配置” 文章目录 1. Spring MVC 中的拦截器的使用“拦截器基本配置” 和 “拦截器高级配置”2. 拦截器3. Spring MVC 中的拦截器的创建和基本配置3.1 定义拦截3.2 拦截器基本配置3.3 拦截器的高级配置 4. Spr…...

MyBatis框架学习笔记(四):动态SQL语句、映射关系和缓存

1 动态 SQL 语句-更复杂的查询业务需求 1.1 动态 SQL-官方文档 &#xff08;1&#xff09;文档地址: mybatis – MyBatis 3 | 动态 SQL &#xff08;2&#xff09;为什么需要动态 SQL 动态 SQL 是 MyBatis 的强大特性之一 使用 JDBC 或其它类似的框架&#xff0c;根据不同条…...

【C++PythonJava】字符处理详细解读_字符_ASCLL码_字母数字转换_算法竞赛_开发语言

文章目录 Beginning1&#xff09;ASCLL 码2&#xff09;大小比较2&#xff09;判断数字字符3&#xff09;字符、数字间的相互转换End Beginning 在 C 中&#xff0c;字符和整数有着密不可分的关系。原因就是在计算机中&#xff0c;字符是以一种较 ASCLL 码的整数存储的。自然&…...

人像视频淡入淡出效果的灵敏检验方法

在视频中经常会有淡入淡出的效果&#xff0c;这可能导致人脸检测在实际人已经离开画面之后仍然触发&#xff0c;特别是在使用基于像素强度变化的检测算法时。为了更精确地裁剪视频&#xff0c;你可以尝试以下几种方法&#xff1a; 使用更复杂的人脸检测模型&#xff1a; 有些…...

Unity UGUI Image Maskable

在Unity的UGUI系统中&#xff0c;Maskable属性用于控制UI元素是否受到父级遮罩组件的影响。以下是关于这个属性的详细说明和如何使用&#xff1a; Maskable属性 Maskable属性&#xff1a; 当你在GameObject上添加一个Image组件&#xff08;比如UI面板或按钮&#xff09;时&…...

SpringCloud | 单体商城项目拆分(微服务)

为什么要进行微服务拆分&#xff1f; 在平常的商城项目中&#xff0c;我们一般的项目结构模块都是将各种业务放在同一个项目文件夹&#xff0c;比如像&#xff1a; 用户&#xff0c;购物车&#xff0c;商品&#xff0c;订单&#xff0c;支付等业务都是放在一起&#xff0c;这样…...

uniapp 如何实现路由拦截,路由守卫

uniapp框架的全局文件&#xff1a;page.json全局文件&#xff0c;官网链接 背景&#xff1a; 通过封装 UniApp 的路由方法&#xff0c;并在封装方法中添加自定义逻辑&#xff0c;可以实现类似 Vue Router 的路由守卫功能。 在 UniApp 框架中&#xff0c;不像 Vue Router 直接支…...

人工智能算法工程师(中级)课程13-神经网络的优化与设计之梯度问题及优化与代码详解

大家好&#xff0c;我是微学AI&#xff0c;今天给大家介绍一下人工智能算法工程师(中级)课程13-神经网络的优化与设计之梯度问题及优化与代码详解。 文章目录 一、引言二、梯度问题1. 梯度爆炸梯度爆炸的概念梯度爆炸的原因梯度爆炸的解决方案 2. 梯度消失梯度消失的概念梯度…...

Qt/QML学习-ComboBox

QML学习 ComboBox例程视频讲解代码 main.qml import QtQuick 2.15 import QtQuick.Window 2.15 import QtQuick.Controls 2.15Window {width: 640height: 480visible: truetitle: qsTr("ComboBox")ComboBox {id: comboBox// 列表项数据模型model: ListModel {List…...

微服务实战系列之玩转Docker(一)

前言 话说计算机的“小型化”发展&#xff0c;历经了大型机、中型机直至微型机&#xff0c;贯穿了整个20世纪的下半叶。同样&#xff0c;伴随着计算机的各个发展阶段&#xff0c;如何做到“资源共享、资源节约”&#xff0c;也一直是一代又一代计算机人的不懈追求和历史使命。今…...

Java中常见的语法糖

文章目录 概览泛型增强for循环自动装箱与拆箱字符串拼接枚举类型可变参数内部类try-with-resourcesLambda表达式 概览 语法糖是指编程语言中的一种语法结构&#xff0c;它们并不提供新的功能&#xff0c;而是为了让代码更易读、更易写而设计的。语法糖使得某些常见的编程模式或…...

数据库使用SSL加密连接

简介 数据库开通SSL加密连接是确保数据传输过程中安全性的关键措施&#xff0c;它通过加密数据、验证服务器身份、保护敏感信息、维护数据完整性和可靠性&#xff0c;同时满足行业标准和法规要求&#xff0c;进而提升用户体验和信任度&#xff0c;为企业的数据安全和业务连续性…...

华为OD算法题汇总

60、计算网络信号 题目 网络信号经过传递会逐层衰减&#xff0c;且遇到阻隔物无法直接穿透&#xff0c;在此情况下需要计算某个位置的网络信号值。注意:网络信号可以绕过阻隔物 array[m][n]&#xff0c;二维数组代表网格地图 array[i][j]0&#xff0c;代表i行j列是空旷位置 a…...

服务器的rabbitmq的guest账号登不进去

要配置 RabbitMQ 允许 guest 账号从非 localhost 地址登录&#xff0c;需要执行以下步骤&#xff1a; 编辑 RabbitMQ 配置文件&#xff1a; 打开 RabbitMQ 的配置文件&#xff0c;通常位于 /etc/rabbitmq/rabbitmq.conf 或者 /etc/rabbitmq/rabbitmq-env.conf。如果这些文件不存…...

决策树(ID3,C4.5,C5.0,CART算法)以及条件推理决策树R语言实现

### 10.2.1 ID3算法基本原理 ### mtcars2 <- within(mtcars[,c(cyl,vs,am,gear)], {am <- factor(am, labels c("automatic", "manual"))vs <- factor(vs, labels c("V", "S"))cyl <- ordered(cyl)gear <- ordered…...

文心一言《使用手册》,文心一言怎么用?

一、认识文心一言 &#xff08;一&#xff09;什么是文心一言 文心一言是百度研发的 人工智能大语言模型产品&#xff0c;能够通过上一句话&#xff0c;预测生成下一段话。 任何人都可以通过输入【指令】和文心一言进行对话互动、提出问题或要求&#xff0c;让文心一言高效地…...

Spring Boot集成qwen:0.5b实现对话功能

1.什么是qwen:0.5b&#xff1f; 模型介绍&#xff1a; Qwen1.5是阿里云推出的一系列大型语言模型。 Qwen是阿里云推出的一系列基于Transformer的大型语言模型&#xff0c;在大量数据&#xff08;包括网页文本、书籍、代码等&#xff09;进行了预训练。 硬件要求&#xff1a;…...

GreenDao实现原理

GreenDao 是一款针对 Android 平台优化的轻量级对象关系映射 (ORM) 框架&#xff0c;它将 Java 对象映射到 SQLite 数据库&#xff0c;以简化数据持久化操作。GreenDao 的主要优点包括高性能、低内存占用、易于使用以及对数据库加密的支持。 以下是基于源码的 GreenDao 实现原…...

Perl语言之数组

Perl数组可以存储多个标量&#xff0c;并且标量数据类型可以不同。   数组变量以开头。访问与定义格式如下&#xff1a; #! /usr/bin/perl arr("asdfasd",2,23.56,a); print "输出所有:arr\n"; print "arr[0]$arr[0]\n"; #输出指定下标 print…...

写材料word和PPT

一、WORD 1、写内容 2、参考GPT改&#xff1a;内容、逻辑结构、语句 3、查标题及其标号 4、修改格式&#xff1a;仿宋 、正文统一为小三&#xff0c;标题三号&#xff0c;1.5倍行距&#xff0c;加页码。 采用VBA代码自动修改&#xff0c;不知为何标题无法修改字体 Sub 插入页…...

WinAsar:告别命令行!551KB的Electron asar文件可视化处理神器

WinAsar&#xff1a;告别命令行&#xff01;551KB的Electron asar文件可视化处理神器 【免费下载链接】WinAsar Portable and lightweight GUI utility to pack and extract asar( Electron archive ) files, Only 551 KB! 项目地址: https://gitcode.com/gh_mirrors/wi/WinA…...

告别静态分析!用R包SetMethods搞定面板数据QCA的三大一致性(附代码实战)

动态QCA实战指南&#xff1a;用R包SetMethods破解面板数据三大一致性难题 社会科学研究者常面临一个核心挑战&#xff1a;如何从随时间变化的面板数据中提取稳定可靠的因果模式&#xff1f;传统横截面QCA分析往往无法捕捉时间或个体效应&#xff0c;导致结论缺乏稳健性。本文将…...

厂房分区控温需求,水冷空调按需布设灵活调配

在工业生产与商业运营中&#xff0c;高温作业环境长期困扰着企业和劳动者。一方面&#xff0c;传统中央空调的高昂安装与运营成本让大多数中小企业望而却步&#xff1b;另一方面&#xff0c;超大厂房、物流仓库、汽车制造车间等开放或半开放场景&#xff0c;难以实现完全密封&a…...

手把手教你把Windows虚拟内存文件pagefile.sys从C盘挪走,给SSD系统盘腾出几十G空间

彻底解放C盘空间&#xff1a;Windows虚拟内存文件迁移全指南 你是否遇到过这样的场景&#xff1a;刚装完系统时C盘还剩下大半空间&#xff0c;用着用着却突然弹出"磁盘空间不足"的警告&#xff1f;打开资源管理器一看&#xff0c;一个名为pagefile.sys的"巨无霸…...

深圳不锈钢五金冲压件

在深圳&#xff0c;不锈钢五金冲压件的市场需求巨大&#xff0c;广泛应用于智能家居、无人机、医疗器械、安防设备等众多领域。然而&#xff0c;面对众多的供应商&#xff0c;如何挑选到合适的合作伙伴成为了许多企业的难题。今天&#xff0c;我们就来对比测评几家深圳的不锈钢…...

BarrageGrab:构建企业级直播弹幕实时采集系统的技术架构与实践指南

BarrageGrab&#xff1a;构建企业级直播弹幕实时采集系统的技术架构与实践指南 【免费下载链接】BarrageGrab 抖音快手bilibili直播弹幕wss直连&#xff0c;非系统代理方式&#xff0c;无需多开浏览器窗口 项目地址: https://gitcode.com/gh_mirrors/ba/BarrageGrab 在直…...

新能源场站通信实战:IEC104与Modbus TCP协议网关开发要点与配置指南

新能源场站通信实战&#xff1a;IEC104与Modbus TCP协议网关开发要点与配置指南 在新能源场站的监控系统中&#xff0c;协议转换网关扮演着至关重要的角色。光伏电站的逆变器、风电场的变流器、充电桩的智能电表等设备通常采用Modbus TCP协议进行数据采集&#xff0c;而电网调度…...

【RT-DETR实战】064、NMS后处理优化与替代方案:我在RT-DETR里踩过的那些坑

今天调一个RT-DETR的部署问题,模型推理速度明明达标了,但在实际视频流里跟踪目标时总出现“闪跳”——同一个目标在相邻帧里忽左忽右。 盯着输出看了半天,发现是相邻帧的检测框置信度相差0.01,NMS直接就把低分框干掉了,导致目标位置在帧间不连续。这个经典问题让我决定好…...

【扣子coze教程】0成本搭建自动生成公众号的飞书智能体(附实战工作流)

今天教大家0成本搭建自动生成公众号的飞书智能体&#xff0c;并部署至飞书。话不多说&#xff0c;咋们直接开始~ 1. 采集网站文章的工作流 如下是完整的工作流1.1 登录多维飞书表格 创建url、title、content、new_content列&#xff0c;为后续保存位置做准备其中url用以存放网页…...

从Halcon助手到你的程序:手把手教你将HSmartWindow中的ROI区域‘抠’出来并用起来

从Halcon助手到C#程序&#xff1a;ROI区域的高效迁移与应用实战 在工业视觉开发中&#xff0c;ROI&#xff08;Region of Interest&#xff09;的交互式调整是核心痛点之一。许多开发者习惯在Halcon助手中反复调试ROI参数&#xff0c;却苦于无法将这些精心调整的区域无缝迁移到…...