SpringMVC:拦截器(12)
拦截器
- 1. 拦截器概念
- 2. 拦截器入门案例
- 2.1 环境准备
- 2.2 拦截器开发
- 步骤1: 创建拦截器类
- 步骤2: 配置拦截器类
- 步骤3: SpringMVC添加SpringMvcSupport包扫描和interceptor包扫描
- 步骤4: 简化SpringMvcSupport的编写
- 5 测试
- 3. 拦截器参数解析(了解)
- 3.1 前置处理方法
- 3.2 后置处理方法
- 3.3 完成处理方法
- 4. 拦截器链配置
1. 拦截器概念

(1) 浏览器发送一个请求会先到Tomcat的web服务器
(2) Tomcat服务器接收到请求以后,会去判断请求的是静态资源还是动态资源
(3) 如果是静态资源,会直接到Tomcat的项目部署目录下去直接访问
(4) 如果是动态资源,就需要交给项目的后台代码进行处理
(5) 在找到具体的方法之前,我们可以去配置过滤器(可以配置多个Filter),按照顺序进行执行
(6) 然后进入到到中央处理器(SpringMVC中的内容),SpringMVC会根据配置的规则进行拦截
(7) 如果满足规则,则进行处理,找到其对应的controller类中的方法进行执行,完成后返回结果
(8) 如果不满足规则,则不进行处理
拦截器要做的事情:
- 拦截器(Interceptor)是一种动态拦截方法调用的机制,在SpringMVC中动态拦截控制器方法的执行
- 作用:
- 在指定的方法调用前后执行预先设定的代码
- 阻止原始方法的执行
- 拦截器就是用来做增强
注意区分过滤器和拦截器:
- 归属不同:Filter属于Servlet技术,Interceptor属于SpringMVC技术
- 拦截内容不同:Filter对所有访问进行增强,Interceptor仅针对SpringMVC的访问进行增强
2. 拦截器入门案例
2.1 环境准备
步骤1:创建一个Web的Maven项目
步骤2:在pom.xml中添加所需的jar包
<?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.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>org.example</groupId><artifactId>springMVC_12_interceptor</artifactId><version>1.0-SNAPSHOT</version><packaging>war</packaging><properties><maven.compiler.source>8</maven.compiler.source><maven.compiler.target>8</maven.compiler.target></properties><dependencies><dependency><groupId>javax.servlet</groupId><artifactId>javax.servlet-api</artifactId><version>3.1.0</version><scope>provided</scope></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-webmvc</artifactId><version>5.2.10.RELEASE</version></dependency><dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-databind</artifactId><version>2.9.0</version></dependency></dependencies><build><plugins><plugin><groupId>org.apache.tomcat.maven</groupId><artifactId>tomcat7-maven-plugin</artifactId><version>2.1</version><configuration><port>8080</port><path>/</path></configuration></plugin></plugins></build>
</project>
步骤3:编写Controller
package com.itheima.controller;import com.itheima.domain.Book;
import org.springframework.web.bind.annotation.*;/*** @Author Mr.Lu* @Date 2023/2/11 15:16* @ClassName BookController* @Version 1.0*/
@RestController
@RequestMapping("/books")
public class BookController {@PostMappingpublic String save(@RequestBody Book book){System.out.println("book save ..." + book);return "{'module':'book save'}";}@DeleteMapping("/{id}")public String delete(@PathVariable Integer id){System.out.println("book delete..." + id);return "{'module':'book delete'}";}@PutMappingpublic String update(@RequestBody Book book){System.out.println("book update ... " + book);return "{'module':'book update'}";}@GetMapping("/{id}")public String getById(@PathVariable Integer id){System.out.println("book getById ... " + id);return "{'module':'book getById'}";}@GetMappingpublic String getAll(){System.out.println("book getAll...");return "{'module':'book getAll'}";}
}
步骤4:创建模型类Book
package com.itheima.domain;/*** @Author Mr.Lu* @Date 2023/2/11 15:12* @ClassName Book* @Version 1.0*/
public class Book {private String name;private double price;public Book() {}public Book(String name, double proce) {this.name = name;this.price = proce;}public String getName() {return name;}public void setName(String name) {this.name = name;}public double getProce() {return price;}public void setProce(double proce) {this.price = proce;}@Overridepublic String toString() {return "Book{" +"name='" + name + '\'' +", proce=" + price +'}';}
}
步骤5:创建对应的配置类
@Configuration
@ComponentScan({"com.itheima.controller"})
@EnableWebMvc
public class SpringMvcConfig {
}
package com.itheima.config;import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import org.springframework.web.filter.CharacterEncodingFilter;
import org.springframework.web.servlet.support.AbstractDispatcherServletInitializer;import javax.servlet.Filter;public class ServletContainersInitConfig extends AbstractDispatcherServletInitializer {/*** 加载springmvc配置类** @return*/@Overrideprotected WebApplicationContext createServletApplicationContext() {AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext();ctx.register(SpringMvcConfig.class);return ctx;}/*** 设置由springmvc控制器处理的请求映射路径** @return*/@Overrideprotected String[] getServletMappings() {return new String[]{"/"};}/*** 加载spring配置类** @return*/@Overrideprotected WebApplicationContext createRootApplicationContext() {
// AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext();
// ctx.register(SpringConfig.class);
// return ctx;return null;}// 乱码处理@Overrideprotected Filter[] getServletFilters() {CharacterEncodingFilter filter = new CharacterEncodingFilter();filter.setEncoding("UTF-8");return new Filter[]{filter};}
}
2.2 拦截器开发
步骤1: 创建拦截器类
在com.itheima目录下面建一个interceptor包,在interceptor包下面建一个实现HandlerIntercepror接口的类,并重写里面的额三个方法。
注意: 拦截器中的preHandler方法,如果返回true,则代表放行,会执行原始Controller类中要请求的方法,如果返回false,则代表拦截,后面的就不会再执行了。

当有拦截器后,请求会先进入preHandle方法,
-
如果方法返回true,则放行继续执行后面的handle[controller的方法]和后面的方法
-
如果返回false,则直接跳过后面方法的执行。
package com.itheima.interceptor;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;// 定义拦截器类,实现HandlerInterceptor接口
// 注意当前类必须受Spring容器控制
@Component
public class ProjectInterceptor implements HandlerInterceptor {@Override// 原始方法调用前执行的内容public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {System.out.println("preHandle...");return true;}@Override// 原始方法调用后执行的内容public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {System.out.println("postHandle...");}@Override// 原始方法调用完成后执行的内容public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {System.out.println("afterCompletion...");}
}
步骤2: 配置拦截器类
在config目录下创建一个类来配置拦截器类
package com.itheima.config;import com.itheima.interceptor.*;
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.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;/*** @Author Mr.Lu* @Date 2023/2/12 15:13* @ClassName SpringMvcSupport* @Version 1.0*/
@Configuration
public class SpringMvcSupport extends WebMvcConfigurationSupport {@Autowired(required = false)private ProjectInterceptor projectInterceptor;// @Override
// protected void addResourceHandlers(ResourceHandlerRegistry registry) {
// registry.addResourceHandler("/pages/**").addResourceLocations("/pages/");
// }@Overrideprotected void addInterceptors(InterceptorRegistry registry) {// 配置拦截器registry.addInterceptor(projectInterceptor).addPathPatterns("/books", "/books/*"); // 为可变参数,可以写几种路径}
}
步骤3: SpringMVC添加SpringMvcSupport包扫描和interceptor包扫描
@Configuration
@ComponentScan({"com.itheima.controller", "com.itheima.interceptor", "com.itheima.config"})
@EnableWebMvc
public class SpringMvcConfig {
}
步骤4: 简化SpringMvcSupport的编写
让SpringMvcConfig类实现WebMvcConfigurer接口。
@Configuration
@ComponentScan({"com.itheima.controller"})
@EnableWebMvc
// 实现WebMvcConfigurer接口可以简化开发,但具有一定的侵入性
public class SpringMvcConfig implements WebMvcConfigurer {@Autowiredprivate ProjectInterceptor projectInterceptor;@Overridepublic void addInterceptors(InterceptorRegistry registry) {//配置多拦截器registry.addInterceptor(projectInterceptor).addPathPatterns("/books","/books/*");}
}
5 测试
访问http://localhost:8080/books


访问http://localhost:8080/books/666


3. 拦截器参数解析(了解)
3.1 前置处理方法
原始方法之前运行preHandle
public boolean preHandle(HttpServletRequest request,HttpServletResponse response,Object handler) throws Exception {System.out.println("preHandle");return true;
}
- request:请求对象
- response:响应对象
- handler:被调用的处理器对象,本质上是一个方法对象,对反射中的Method对象进行了再包装
3.2 后置处理方法
原始方法运行后运行,如果原始方法被拦截(前置方法返回false),则不执行
public void postHandle(HttpServletRequest request,HttpServletResponse response,Object handler,ModelAndView modelAndView) throws Exception {System.out.println("postHandle");
}
modelAndView:如果处理器执行完成具有返回结果,可以读取到对应数据与页面信息,并进行调整
3.3 完成处理方法
拦截器最后执行的方法,无论原始方法是否执行(只要前置方法返回true,那么完成处理方法就一定执行)
public void afterCompletion(HttpServletRequest request,HttpServletResponse response,Object handler,Exception ex) throws Exception {System.out.println("afterCompletion");
}
4. 拦截器链配置
步骤1:创建拦截器类:实现接口,并重写接口中的方法
拦截器2: ProjectInterceptor2
package com.itheima.interceptor;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;/*** @Author Mr.Lu* @Date 2023/2/12 15:09* @ClassName ProjectInterceptor* @Version 1.0*/// 定义拦截器类,实现HandlerInterceptor接口
// 注意当前类必须受Spring容器控制
@Component
public class ProjectInterceptor2 implements HandlerInterceptor {@Override// 原始方法调用前执行的内容public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {System.out.println("preHandle...222");return true;}@Override// 原始方法调用后执行的内容public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {System.out.println("postHandle...222");}@Override// 原始方法调用完成后执行的内容public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {System.out.println("afterCompletion...222");}
}
拦截器3:ProjectInterceptor3
package com.itheima.interceptor;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;/*** @Author Mr.Lu* @Date 2023/2/12 15:09* @ClassName ProjectInterceptor* @Version 1.0*/// 定义拦截器类,实现HandlerInterceptor接口
// 注意当前类必须受Spring容器控制
@Component
public class ProjectInterceptor3 implements HandlerInterceptor {@Override// 原始方法调用前执行的内容public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {System.out.println("preHandle...333");return true;}@Override// 原始方法调用后执行的内容public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {System.out.println("postHandle...333");}@Override// 原始方法调用完成后执行的内容public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {System.out.println("afterCompletion...333");}
}
步骤2:配置拦截器类
package com.itheima.config;import com.itheima.interceptor.*;
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.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;/*** @Author Mr.Lu* @Date 2023/2/12 15:13* @ClassName SpringMvcSupport* @Version 1.0*/
@Configuration
public class SpringMvcSupport extends WebMvcConfigurationSupport {@Autowired(required = false)private ProjectInterceptor projectInterceptor;@Autowired(required = false)private ProjectInterceptor2 projectInterceptor2;@Autowired(required = false)private ProjectInterceptor3 projectInterceptor3;// @Override
// protected void addResourceHandlers(ResourceHandlerRegistry registry) {
// registry.addResourceHandler("/pages/**").addResourceLocations("/pages/");
// }@Overrideprotected void addInterceptors(InterceptorRegistry registry) {// 配置拦截器registry.addInterceptor(projectInterceptor).addPathPatterns("/books", "/books/*");registry.addInterceptor(projectInterceptor2).addPathPatterns("/books", "/books/*");registry.addInterceptor(projectInterceptor3).addPathPatterns("/books", "/books/*");}
}
步骤3:运行程序,观察顺序

拦截器执行的顺序是和配置顺序有关,先进后出。
- 当配置多个拦截器时,形成拦截器链
- 拦截器链的运行顺序参照拦截器添加顺序为准
- 当拦截器中出现对原始处理器的拦截,后面的拦截器均终止运行
- 当拦截器运行中断,仅运行配置在前面的拦截器的afterCompletion操作
注:
-
当ProjectInterceptor,ProjectInterceptor2,ProjectInterceptor3中的preHandle方法都返回true时,拦截器链执行顺序为:pre1, pre2, pre3, Controller, post3, post2, post1, after3, after2, after1.
-
当ProjectInterceptor,ProjectInterceptor2中的preHandle方法返回true,ProjectInterceptor3中的preHandle方法返回false时,拦截器链执行顺序为:pre1, pre2, pre3, after2, after1.
-
当ProjectInterceptor中的preHandle方法返回true,ProjectInterceptor2中的preHandle方法返回false时,拦截器链执行顺序为:pre1, pre2, after1.
-
当ProjectInterceptor中的preHandle方法返回false时,拦截器链执行顺序为:pre1

相关文章:
SpringMVC:拦截器(12)
拦截器1. 拦截器概念2. 拦截器入门案例2.1 环境准备2.2 拦截器开发步骤1: 创建拦截器类步骤2: 配置拦截器类步骤3: SpringMVC添加SpringMvcSupport包扫描和interceptor包扫描步骤4: 简化SpringMvcSupport的编写5 测试3. 拦截器参数解析(了解)3.1 前置处理…...
计算机网络3:HTTP1.0和HTTP1.1的区别
目录1. HTTP是什么2.HTTP1.0和HTTP1.1的区别3.名词解释(1)If-Modified-Since(IMS)、Expires(2)If-None-Match,Etag(3)If-Unmodified-Since1. HTTP是什么 超文本传输协议…...
Urho3D 编辑器说明
Urho3D编辑器是一个脚本应用程序,可以与Urho3D播放器应用程序一起运行。要开始,请执行以下任意命令:(在bin目录中)Editor.bat、Editor.sh或Urho3DPlayer Scripts/Editor.as Urho3D播放器应用程序支持的所有命令行选项…...
C++类基础(十一)
运算符重载(二) ● 对称运算符通常定义为非成员函数以支持首个操作数的类型转换 struct Str {int val 0;Str(int input): val(input){}auto operator(Str x){std::cout << "auto operator(Str x)\n";return Str(val x.val);} }; int …...
Windows安装系列:SVN Server服务
一、下载与安装 1、下载VisualSVN-Server-5.1.1-x64.msi 地址:Download | VisualSVN Server 2、找到最新版本SVN 5.1.1,直接双击它,弹出如下安装界面 3、点击Next 4、勾选我接受, 点击"Next" 5、默认选项,…...
快速傅里叶算法(FFT)快在哪里?
目录 前言 1、DFT算法 2、FFT算法 2.1 分类 2.2 以基2 DIT(时间抽取) FFT 算法为例 2.2.1 一次分解 2.2.2 多次分解 参考 前言 对信号分析的过程中,为了能换一个角度观察问题,很多时候需要把时域信号波形变换到频域进行分…...
利用Markdown写学术论文资料汇总贴
1是最详细的,重点看! Markdown 写作,Pandoc 转换:我的纯文本学术写作流程 2补充一些细节,也可以看看。 用Markdown写作学术论文 3写得和上面差不多,如果上面两篇有什么问题还没解决,可以看看…...
MySQL 高级查询
目录1.左关联2.右关联3.子查询4.联合查询5.分组查询1.左关联 MySQL中的左关联(Left Join)是一种基于共同列的连接操作, 它将左侧表中的所有行与右侧表中匹配的行结合在一起, 如果右侧表中没有匹配的行,则结果集中右侧…...
JavaSE学习day4_01 循环for,while,do...while
1. 循环高级 1.1 无限循环 for、while、do...while都有无限循环的写法。 最为常用的是while格式的。 因为无限循环是不知道循环次数的,所以用while格式的 代码示例: while(true){} 1.2 跳转控制语句(掌握) 跳转控制语句&…...
C/C++中的static关键字
概述在C/C中都有static关键字的使用,可以分别修饰变量和函数,分为静态变量【静态成员】、静态成员函数。2. static用法概况静态变量的作用范围在一个文件内,程序开始时分配空间,结束时释放空间,默认初始化为0ÿ…...
67 自注意力【动手学深度学习v2】
67 自注意力【动手学深度学习v2】 深度学习学习笔记 学习视频:https://www.bilibili.com/video/BV19o4y1m7mo/?spm_id_fromautoNext&vd_source75dce036dc8244310435eaf03de4e330 给定长为n 的序列,每个xi为长为d的向量,自注意力将xi 既当…...
电子学会2022年12月青少年软件编程(图形化)等级考试试卷(二级)答案解析
青少年软件编程(图形化)等级考试试卷(二级) 一、单选题(共25题,共50分) 1. 一个骰子,从3个不同角度看过去的点数如图所示,请问5的对面是什么点数?( ) …...
关于链表中插入结点的操作……
服了,好久没敲链表了,这都忘了 newnode->next cur->next; cur->next newnode; newnode->next cur->next; cur->next newnode; newnode->next cur->next; cur->next newnode; newnode->next cur->next; cur-…...
【项目精选】百货中心供应链管理系统
点击下载源码 近年来,随着计算机技术的发展,以及信息化时代下企业对效率的需求,计算机技术与通信技术已经被越来越多地应用到各行各业中去。百货中心作为物流产业链中重要的一环,为了应对新兴消费方式的冲击,从供货到销…...
Qt优秀开源项目之十六:SQLite数据库管理系统—SQLiteStudio
首先,感谢CSDN官方认可 SQLiteStudio是一款开源、跨平台(Windows、Linux和MacOS)的SQLite数据库管理系统。 github地址:https://github.com/pawelsalawa/sqlitestudio 官网:https://sqlitestudio.pl/ 特性很多…...
Python __doc__属性:查看文档
在使用 dir() 函数和 __all__ 变量的基础上,虽然我们能知晓指定模块(或包)中所有可用的成员(变量、函数和类),比如:import string print(string.__all__)程序执行结果为:[ascii_lett…...
电子科技大学操作系统期末复习笔记(一):操作系统概述
目录 前言 操作系统概述 操作系统的目标与功能 操作系统的定义 目标 功能 操作系统的历史 单用户系统 简单批处理系统 多道批处理系统 分时系统 个人电脑 → 分布式系统 → 互联网时代 → 移动计算时代 → ...... 实时系统 操作系统的基本特征 并发 共享 虚拟…...
[实践篇]13.20 Qnx进程管理slm学习笔记(三)
【QNX Hypervisor 2.2用户手册】目录(完结) 4.2 模块 我们可以将组件组合成一个模块。模块中的进程可以组成一个子系统,也可以用于建立一组系统状态,例如基本操作和各种更高级别操作。注意,必须命名模块,以便可以在内部引用它们。而且每个模块必须描述成一个元素,形势如…...
冰冰学习笔记:多线程
欢迎各位大佬光临本文章!!! 还请各位大佬提出宝贵的意见,如发现文章错误请联系冰冰,冰冰一定会虚心接受,及时改正。 本系列文章为冰冰学习编程的学习笔记,如果对您也有帮助,还请各位…...
补充一些前端面试题
javascript有哪些库指路>js中的库uniapp和vue有什么区别什么是uniappuni-app(uni,读you ni,是统一的意思)是一个使用Vue.js开发所有前端应用的框架,开发者编写一套代码,可发布到iOS、Android、Web&#…...
多场景 OkHttpClient 管理器 - Android 网络通信解决方案
下面是一个完整的 Android 实现,展示如何创建和管理多个 OkHttpClient 实例,分别用于长连接、普通 HTTP 请求和文件下载场景。 <?xml version"1.0" encoding"utf-8"?> <LinearLayout xmlns:android"http://schemas…...
前端开发面试题总结-JavaScript篇(一)
文章目录 JavaScript高频问答一、作用域与闭包1.什么是闭包(Closure)?闭包有什么应用场景和潜在问题?2.解释 JavaScript 的作用域链(Scope Chain) 二、原型与继承3.原型链是什么?如何实现继承&a…...
06 Deep learning神经网络编程基础 激活函数 --吴恩达
深度学习激活函数详解 一、核心作用 引入非线性:使神经网络可学习复杂模式控制输出范围:如Sigmoid将输出限制在(0,1)梯度传递:影响反向传播的稳定性二、常见类型及数学表达 Sigmoid σ ( x ) = 1 1 +...
Java面试专项一-准备篇
一、企业简历筛选规则 一般企业的简历筛选流程:首先由HR先筛选一部分简历后,在将简历给到对应的项目负责人后再进行下一步的操作。 HR如何筛选简历 例如:Boss直聘(招聘方平台) 直接按照条件进行筛选 例如:…...
大数据学习(132)-HIve数据分析
🍋🍋大数据学习🍋🍋 🔥系列专栏: 👑哲学语录: 用力所能及,改变世界。 💖如果觉得博主的文章还不错的话,请点赞👍收藏⭐️留言Ǵ…...
九天毕昇深度学习平台 | 如何安装库?
pip install 库名 -i https://pypi.tuna.tsinghua.edu.cn/simple --user 举个例子: 报错 ModuleNotFoundError: No module named torch 那么我需要安装 torch pip install torch -i https://pypi.tuna.tsinghua.edu.cn/simple --user pip install 库名&#x…...
C++.OpenGL (20/64)混合(Blending)
混合(Blending) 透明效果核心原理 #mermaid-svg-SWG0UzVfJms7Sm3e {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-SWG0UzVfJms7Sm3e .error-icon{fill:#552222;}#mermaid-svg-SWG0UzVfJms7Sm3e .error-text{fill…...
根目录0xa0属性对应的Ntfs!_SCB中的FileObject是什么时候被建立的----NTFS源代码分析--重要
根目录0xa0属性对应的Ntfs!_SCB中的FileObject是什么时候被建立的 第一部分: 0: kd> g Breakpoint 9 hit Ntfs!ReadIndexBuffer: f7173886 55 push ebp 0: kd> kc # 00 Ntfs!ReadIndexBuffer 01 Ntfs!FindFirstIndexEntry 02 Ntfs!NtfsUpda…...
AI语音助手的Python实现
引言 语音助手(如小爱同学、Siri)通过语音识别、自然语言处理(NLP)和语音合成技术,为用户提供直观、高效的交互体验。随着人工智能的普及,Python开发者可以利用开源库和AI模型,快速构建自定义语音助手。本文由浅入深,详细介绍如何使用Python开发AI语音助手,涵盖基础功…...
在 Visual Studio Code 中使用驭码 CodeRider 提升开发效率:以冒泡排序为例
目录 前言1 插件安装与配置1.1 安装驭码 CodeRider1.2 初始配置建议 2 示例代码:冒泡排序3 驭码 CodeRider 功能详解3.1 功能概览3.2 代码解释功能3.3 自动注释生成3.4 逻辑修改功能3.5 单元测试自动生成3.6 代码优化建议 4 驭码的实际应用建议5 常见问题与解决建议…...
