SpringBoot拦截器

目录

一、拦截器快速入门

(1)什么是拦截器

(2)拦截器的使用步骤

1、定义拦截器

🍀preHandle() 方法

🍀postHandle() 方法

🍀afterCompletion() 方法

2、注册配置拦截器

二、拦截器详解

1、拦截路径

2、拦截器执行流程

三、登录校验(图书管理系统)

1、定义拦截器

2、注册配置拦截器

3、更改图书馆管理系统代码(用户登录接口)

(1)后端代码

(2)前端代码

四、适配器模式

1、适配器模式定义

2、适配器模式角色

3、适配器模式的实现

4、适配器模式应用场景


        上篇博客完成了强制登录功能,后端程序需要根据 Session 来判断用户是否登录,但是实现方法是比较麻烦的,需要完成下面几个步骤:

1、需要修改每个接口的处理逻辑

2、需要修改每个接口的返回结果

3、接口定义修改,前段代码也需要跟着修改

        那有没有更简单的方式,统一拦截所有的请求,并进行 Session 的校验的?有,那就是Spring 框架提供的核心功能之一:拦截器


一、拦截器快速入门

(1)什么是拦截器

        拦截器是 Spring 框架提供的核心功能之一,主要用来拦截用户的请求,在指定的方法前后,根据业务需要执行预先设定的代码

        也就是说,允许开发人员提前预定义一些逻辑,在用户的请求、响应前后执行。也可以在用户请求前阻止其执行

        在拦截器当中,开发人员可以在应用程序中做一些通用性的操作,比如通过拦截器来拦截前端发来的请求,判断Session中是否有登录用户的信息,如果有 -> 就放行,如果没有 -> 就进行拦截。

        如图:

        这种情况就类似我们去银行办理业务,去银行办业务需要有带身份证,如果没有身份证,就不能取号,更不要提后续的业务,没有就要回家拿再过来,有就去取号,排队等待,办理你需要的业务

        拦截器在这里就类似你有没有身份证,有身份证才能办理后续的业务,没有就要执行其他逻辑(回家拿身份证)。

        接下来,我们来学习拦截器的基本使用。

(2)拦截器的使用步骤

        练习拦截器的使用以及后面的使用都是使用图书管理系统项目。

1、定义拦截器

        自定义拦截器,实现 HandlerInterceptor 接口,并且重写所有方法,代码如下:

@Slf4j
@Component
public class LoginInterceptor implements HandlerInterceptor {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {log.info("LoginInterceptor preHandle(目标方法执行前执行).....");return true;}@Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {log.info("LoginInterceptor postHandle(目标方案执行后执行).....");}@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {log.info("LoginInterceptor afterCompletion(视图渲染完毕后执行,最后执行).....");}
}

🍀preHandle() 方法

        目标方法执行前执行返回true:继续执行后续操作;返回false:中断后续操作。

🍀postHandle() 方法

        目标方法执行后执行

🍀afterCompletion() 方法

        视图渲染完毕后执行,最后执行(后端开发现在几乎不涉及视图了,暂不了解)。

2、注册配置拦截器

        创建一个 WebConfig 类,实现WebMvcConfigurer接口,并重写addInterceptors方法(),代码如下:

@Configuration
public class WebConfig implements WebMvcConfigurer {@AutowiredLoginInterceptor loginInterceptor;@Overridepublic void addInterceptors(InterceptorRegistry registry) {//注册自定义拦截器对象registry.addInterceptor(loginInterceptor).addPathPatterns("/**")//设置拦截器拦截的请求路径( /** 表⽰拦截所有请求;}
}

        现在启动服务器,访问任意接口,观察打印的日志

        查询bookId=1的图书信息,如图:

        观察日志:

        可以看到,在执行目标方法前,就执行了 preHandle() 方法了因为preHandle返回了true,才能执行执行目标方法,目标方法执行完后,执行 postHandle() 方法;最后才执行 afterCompletion() 方法

        现在我们把 preHandle() 方法的返回值修改成 false试试,观察打印结果

        再次访问 /book/queryBookById?bookId=1 ,观察返回的信息,这次没有返回信息了,如图:

        再看看控制台打印的日志:

        因为 preHandle() 方法返回的是 false所有没有打印 postHandle() 和afterCompletion() 方法,也就意味着中断了后续的操作


二、拦截器详解

        拦截器的入门程序完成后,接下来我们学习拦截器的使用细节。拦截器的使用细节主要介绍两个部分:1、拦截器的拦截路径配置      2、拦截器实现原理

1、拦截路径

        拦截路径是指我们定义的这个拦截器,对哪些请求生效。

        我们在注册配置拦截器的时候,通过 addPathPatterns() 方法指定要拦截哪些请求。也可以通过 excludePathPatterns() 指定不拦截哪些请求

        上述代码中,我们配置的是 /** ,表示拦截所有的请求。

        比如用户登录校验,我们希望可以对除了登录之外所有的路径生效,代码如下:

@Configuration
public class WebConfig implements WebMvcConfigurer {@AutowiredLoginInterceptor loginInterceptor;@Overridepublic void addInterceptors(InterceptorRegistry registry) {//注册自定义拦截器对象registry.addInterceptor(loginInterceptor).addPathPatterns("/**")//设置拦截器拦截的请求路径( /** 表⽰拦截所有请求.excludePathPatterns("/user/login")//设置拦截器不拦截哪些请求路径;}
}

        现在请求 /user/login 接口,就不会打印上面说的那三个接口了

        因为没有拦截它,也就不会执行那三个方法,打印其日志了。

        在拦截器中除了可以设置 /** 拦截所有资源外,还有一些常见拦截路径设置:

拦截路径含义举例
/*⼀级路径能匹配/user,/book,/login,不能匹配 /user/login
/**任意级路径能匹配/user,/user/login,/user/reg
/book/*/book下的⼀级路径能匹配/book/addBook,不能匹配/book/addBook/1,/book
/book/**/book下的任意级路径能匹配/book,/book/addBook,/book/addBook/2,不能匹
配/user/login

2、拦截器执行流程

        正常的调⽤顺序:

         

        有了拦截器后,会在调用 Controller 之前进行相应的业务处理,执行的流程如下图:

        

1添加拦截器后,执行 Controller 的方法之前,请求会先被拦截器拦截住,执行 preHadnle() 方法,这个方法需要返回一个布尔类型的值。如果返回true,就表示放行本次操作,继续访问 controller中的方法;如果返回false,则拦截(controller中的方法也不会执行)。

2controller当中的方法执行完毕后在回过来执行 postHandle() 这个方法 以及 afterCompletion() 方法,执行完毕之后,最终给浏览器响应数据。


三、登录校验(图书管理系统)

        学习了拦截器的基本操作之后,接下来我们需要完成最后一步操作:通过拦截器来完成图书管理系统中的登录校验功能。

1、定义拦截器

        从 session 中获取用户信息,如果 session 中不存在,就返回false,并设置http状态码为401,否则返回true。代码如下:

@Slf4j
@Component
public class LoginInterceptor implements HandlerInterceptor {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {log.info("LoginInterceptor preHandle(目标方法执行前执行).....");//获取Session,判断Session中存储的userinfo信息是否为空HttpSession session = request.getSession(true);UserInfo userInfo = (UserInfo) session.getAttribute(Constant.USER_SESSION_KEY);if(userInfo == null || userInfo.getId() <= 0) {//用户未登录response.setStatus(401);return false;}return true;}
}

http状态码401:Unauthorized
        Indicates that authentication is required and was either not provided or has failed. If the request already included authorization credentials, then the 401 status code indicates that those credentials were not accepted.

        中文解释:未经过认证。指示身份验证是必需的,没有提供身份验证或身份验证失败。如果请求已经包含授权凭据,那么401状态码表示不接受这些凭据。

        其中 request.getSession() 方法有下面两种形式,有参和无参,如图:

        其中,无参的 getSession() 方法 默认 是 getSession(true);

         getSession(true) 表示如果有Session,则返回Session,如果没有,则创建一个Session

        getSession(false) 表示 获取Session可能会是null

2、注册配置拦截器

        配置拦截器拦截所有的请求,除了 /user/login 和前端的页面,代码如下:

@Configuration
public class WebConfig implements WebMvcConfigurer {@Autowiredprivate LoginInterceptor loginInterceptor;@Overridepublic void addInterceptors(InterceptorRegistry registry) {//注册自定义拦截器对象registry.addInterceptor(loginInterceptor).addPathPatterns("/**")//设置拦截器拦截的请求路径( /** 表⽰拦截所有请求.excludePathPatterns("/user/login")//设置拦截器不拦截哪些请求路径.excludePathPatterns("/css/**")//排除前端静态资源.excludePathPatterns("/js/**").excludePathPatterns("/pic/**").excludePathPatterns("/**/*.html");}
}

也可以改成下面这样子,定义一个链表,把要排除的路径都放进链表中,代码如下:

//也可以改成下面这样子
//定义一个链表,把要排除的路径都放进链表中
@Configuration
public class WebConfig implements WebMvcConfigurer {@AutowiredLoginInterceptor loginInterceptor;private List<String> excludePaths = Arrays.asList("/user/login","/css/**","/js/**","/pic/**","/**/*.html");@Overridepublic void addInterceptors(InterceptorRegistry registry) {//注册自定义拦截器对象registry.addInterceptor(loginInterceptor).addPathPatterns("/**")//设置拦截器拦截的请求路径( /** 表⽰拦截所有请求.excludePathPatterns(excludePaths)//设置拦截器排除拦截的路径;}
}

        运行程序,进行测试

        访问:http://127.0.0.1:8080/book_list.html?pageNum=1

        可以看到有401的状态码。

        通过fiddler抓包观察:

        返回的响应状态码就是401。

        现在进行登录,如图:

        再次访问:http://127.0.0.1:8080/book_list.html?pageNum=1,如图:有内容了

3、更改图书馆管理系统代码(用户登录接口)

(1)后端代码

        因为我们已经定义和注册配置了拦截器,所以这里统一帮我们做了校验用户是否登录,没有登录就返回false(拦截),并且设置响应的状态码为401;用户已经登录了,能获取到的Session能通过它拿到userInfo信息,userinfo也有对应的用户信息,就是用户登录了,则返回 true;就是上面定义拦截器的内容,代码如下:

@Slf4j
@Component
public class LoginInterceptor implements HandlerInterceptor {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {log.info("LoginInterceptor preHandle(目标方法执行前执行).....");//获取Session,判断Session中存储的userinfo信息是否为空HttpSession session = request.getSession(true);UserInfo userInfo = (UserInfo) session.getAttribute(Constant.USER_SESSION_KEY);if(userInfo == null || userInfo.getId() <= 0) {//用户未登录response.setStatus(401);return false;}return true;}
}

        修改 controller的"/book/getBookListByPage" 接口,也就是删除一些逻辑判断,因为拦截器已经帮我们做了这些逻辑处理,代码如下:

    @RequestMapping("/getBookListByPage")public Result<PageResult<BookInfo>> getBookListByPage(PageRequest pageRequest, HttpSession session) {log.info("查询图书的列表, 请求参数pageRequest: {}", pageRequest);//从session中获取用户信息//如果用户信息为空, 说明用户未登录
//        UserInfo loginUserInfo = (UserInfo) session.getAttribute(Constant.USER_SESSION_KEY);
//        if(loginUserInfo == null || loginUserInfo.getId() < 0) {
//            return Result.nologin();
//        }
//        //参数校验
//        if(pageRequest.getPageNum() == null) {
//            //返回默认第一页,如果pageSize也没设置,则会使用默认的10
//            pageRequest.setPageNum(1);
//        }PageResult<BookInfo> bookList = bookService.getBookListByPage(pageRequest);return Result.success(bookList);}

        现在进行测试,未登录,访问:http://127.0.0.1:8080/book_list.html?pageNum=1,返回401状态码

        登录后,再访问,结果如下:能返回信息

        但上面没有实现强制登录功能,不应该出现401的状态码,应该跳转到登录界面,这是因为还没有改前端代码,下面修改前端代码。

(2)前端代码

getBookList();function getBookList() {$.ajax({url: "/book/getBookListByPage" + location.search,type: "get",success: function (result) {// if (result.code == "NOLOGIN") {//用户登录//     location.href = "login.html";// }if (result.data != null && result.data.records != null) {console.log("拿到参数")var finalHtml = "";for (book of result.data.records) {finalHtml += '<tr>';finalHtml += '<td><input type="checkbox" name="selectBook" value="' + book.id + '" id="' + book.id + '" class="book-select"></td>'finalHtml += '<td>' + book.id + '</td>';finalHtml += '<td>' + book.bookName + '</td>';finalHtml += '<td>' + book.author + '</td>';finalHtml += '<td>' + book.count + '</td>';finalHtml += '<td>' + book.price + '</td>';finalHtml += '<td>' + book.publish + '</td>';finalHtml += '<td>' + book.statusCN + '</td>';finalHtml += '<td>';finalHtml += '<div class="op">';finalHtml += '<a href="book_update.html?bookId=' + book.id + '">修改</a>';finalHtml += '<a href="javascript:void(0)" onclick="deleteBook(' + book.id + ')">删除</a>';finalHtml += '</div>';finalHtml += '</td>';finalHtml += '</tr>';}$("tbody").html(finalHtml);var data = result.data;//翻页信息$("#pageContainer").jqPaginator({totalCounts: data.count, //总记录数pageSize: 10,    //每页的个数visiblePages: 5, //可视页数currentPage: data.pageRequest.pageNum,  //当前页码first: '<li class="page-item"><a class="page-link">首页</a></li>',prev: '<li class="page-item"><a class="page-link" href="javascript:void(0);">上一页<\/a><\/li>',next: '<li class="page-item"><a class="page-link" href="javascript:void(0);">下一页<\/a><\/li>',last: '<li class="page-item"><a class="page-link" href="javascript:void(0);">最后一页<\/a><\/li>',page: '<li class="page-item"><a class="page-link" href="javascript:void(0);">{{page}}<\/a><\/li>',//页面初始化和页码点击时都会执行onPageChange: function (page, type) {console.log("第" + page + "页, 类型:" + type);if (type == "change") {location.href = "book_list.html?pageNum=" + page;}}});}},error: function (error) {console.log(error);if(error != null && error.status == 401) {location.href = "login.html";}}});}

        也就是多增加 error 时,应该怎么做,上面是进行判断了返回响应的信息,响应是不是空,已经响应的状态码是不是401,是的话就给他跳转到登录界面。

        现在进行测试一下,URL:http://127.0.0.1:8080/book_list.html?pageNum=1,会跳转到登录界面

        观察日主,如图:

        打印了preHandle()方法执行后就没有后续的内容了。

        要是登录后,再访问 http://127.0.0.1:8080/book_list.html?pageNum=1,就会展示第一页的图书列表。

        还有其他接口的代码没改,后面会学习统一功能,到时候使用统一功能再一起改。


四、适配器模式

1、适配器模式定义

        适配器模式,也叫包装模式。将一个类的接口,转换成客户期望的另一个接口,适配器让原本接口不兼容的类也可以合作无间

        简单来说就是目标类不能直接使用,通过一个新类进行包装一下,适配调用方使用。把两个不兼容的接口通过一定的方式使之兼容。

        比如下图的两个接口,本身是不兼容的(参数类型不一样,参数个数不一样等等)

        可以通过适配器的方式,使之兼容

        而在日常生活中,适配器模式也非常常见,例如转换插头、网络转接头、耳机转接头等。

        出国旅游必备物品之一就是转换插头。不同国家的插头标准是不一样的,出国后我们手机 / 电脑充电器可能就没办法使用了。比如美国电器 110V,中国 220V,就要有一个适配器将 110V 转化为 220V。国内经常使用转换插头把两头转为三头,或者三头转两头。

2、适配器模式角色

Target目标接口(可以是抽象类或接口),客户希望直接用的接口

Adaptee适配者,但是与 Target 不兼容

Adapter适配器类,此模式的核心。通过继承或者引用适配者的对象,把适配者转为目标接口

client需要使用适配器的对象

3、适配器模式的实现

        场景:之前学习的 Slf4j 就使用了适配器模式Slf4j 提供了一系列打印日志的 API, 底层调用的是 log4j 或者 logback 来打日志,我们作为调用者,只需要调用 Slf4j 的API 即可

代码如下:

        Target:

public interface Slf4jLog {void log(String message);
}

        Adaptee:

public class Log4j {public void log4jPrint(String message) {System.out.println("我是Log4j, 打印内容是: " + message);}
}

        Adapter:

        Log4j 想使用 Slf4jLog log接口,但是不行,因为自身 打印的方法 和Slf4jLog 的不同。所以这时候就就需要使用适配器,定义一个类,通过继承 Slf4jLog 接口,来实现它的方法,再引入 Log4j,打印Log4j的内容。

public class Log4jAdapter implements Slf4jLog{private Log4j log4j;public Log4jAdapter(Log4j log4j) {this.log4j = log4j;}@Overridepublic void log(String message) {log4j.log4jPrint("我是适配器, 打印日志为: " + message);}
}

        client

public class Main {public static void main(String[] args) {Slf4jLog slf4jLog = new Log4jAdapter(new Log4j());slf4jLog.log("我是客户端");}
}

        打印内容如下:

        可以看到,适配器就是起到一层包装的效果因为接口和 Slf4jLog 不同,所以就使用适配器类 实现 Slf4jLog 接口,同时引用 Log4j,使用 Log4j 的打印方法包装一层再给 Log4j 打印)。

        最终还是给 Log4j 打印适配器的作用就是给两个不同的接口,给其中一个接口进行包装一下,再丢给另一个接口进行使用

        可以看出,有了适配器模型,对已经定义好的接口,可以不进行修改,只需要通过适配器转换下,就可以更换日志框架,保障系统的平稳运行

4、适配器模式应用场景

        一般来说,适配器模式可以看做一种 “补偿模式”,用来 补救 设计上的缺陷。应用这种模式算是 “无奈之举”,如果在设计初期,我们就能协调规避接口不兼容的问题,就不需要使用适配器模式了

        所以,适配器模式更多的应用场景主要是对正在运行的代码进行改造,并且希望可以复用原有代码实现新的功能,比如版本升级等

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

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

相关文章

中国剩余定理

模板代码&#xff1a; #include<bits/stdc.h> using namespace std; using ll long long; #define fi first #define se second const ll mod998244353; const int N2e510; #define int llint n,m[300],r[300]; int exgcd(int a,int b,int &x,int &y){if(b0){x…

如何用Vue3和Plotly.js打造交互式仪表盘

本文由ScriptEcho平台提供技术支持 项目地址&#xff1a;传送门 Vue.js 中使用 Plotly.js 创建指示器卡片 应用场景介绍 指示器卡片是一种用于可视化数据并提供关键见解的交互式组件。它们通常用于仪表板、分析应用程序和监控系统。Plotly.js 是一个流行的 JavaScript 库&a…

Kotlin linkedMapOf filterKeys

Kotlin linkedMapOf filterKeys fun main(args: Array<String>) {val lhm linkedMapOf<String, Any>(Pair("name", "phil"), //因为key相同都为 name&#xff0c;被后面的覆盖。Pair("year", 2024),Pair("name", "f…

Face_recognition实现人脸识别

这里写自定义目录标题 欢迎使用Markdown编辑器一、安装人脸识别库face_recognition1.1 安装cmake1.2 安装dlib库1.3 安装face_recognition 二、3个常用的人脸识别案例2.1 识别并绘制人脸框2.2 提取并绘制人脸关键点2.3 人脸匹配及标注 欢迎使用Markdown编辑器 本文基于face_re…

无法下载 https://mirrors./ubuntu/dists/bionic/main/binary-arm64/Packages

ubuntu系统执行sudo apt update命令的时候&#xff0c;遇到如下问题&#xff1a; 忽略:82 https://mirrors.tuna.tsinghua.edu.cn/ubuntu bionic-backports/universe arm64 Packages 错误:81 https://mirrors.tuna.tsinghua.edu.cn/ubuntu bionic-backports/main arm64 Packa…

Oracle 19c 统一审计表清理

zabbix 收到SYSAUX表空间告警超过90%告警&#xff0c;最后面给出的清理方法只适合ORACLE 统一审计表的清理&#xff0c;传统审计表的清理SYS.AUD$不适合&#xff0c;请注意。 SQL> Col tablespace_name for a30 Col used_pct for a10 Set line 120 pages 120 select total.…

Vue 3 中集成 ECharts(附一些案例)

Vue 3 中集成 ECharts 的完全指南 引言 在现代Web开发中&#xff0c;Vue 3以其卓越的性能和灵活的Composition API赢得了广泛的关注。而ECharts&#xff0c;作为开源的一个使用JavaScript实现的强大可视化库&#xff0c;以其丰富的图表类型和高度可定制性成为了数据可视化的首…

EAI四个层次服务-系统架构师(二十六)

1、&#xff08;重点&#xff09;系统应用集成提供了4个不同层次服务&#xff0c;最上层服务是&#xff08;&#xff09;服务。 解析: EAI&#xff08;Enterprise Application Integration&#xff09;系统应用集成&#xff0c;相关概念。 实施EAI必须保证&#xff1a;应用程…

超详细版阿里云控制台环境配置+数据库配置

一、登录阿里云控制台 登录阿里云控制台&#xff0c;找到实例&#xff0c;切到阿里云服务器所在地址 &#x1f36d;不知道自己的服务器地址在哪边也没有关系&#xff0c;随便选择一个&#xff0c;查询不到记录的话会有以下提示&#xff0c;可以根据提示进行切换&#xff08;适…

贝叶斯估计(1):期末大乱炖

写在前面&#xff01; 1 先验分布和后验分布 三种信息&#xff1a;总体信息、样本信息、先验信息 总体信息&#xff1a;“总体是正态分布”&#xff1b;样本信息&#xff1a;总体抽取的样本提供的信息&#xff0c;是最新鲜的信息&#xff1b;先验信息&#xff1a;在抽样之前就…

罗剑锋的C++实战笔记学习(二):容器、算法库、多线程

4、容器 1&#xff09;、容器的通用特性 所有容器都具有的一个基本特性&#xff1a;它保存元素采用的是值&#xff08;value&#xff09;语义&#xff0c;也就是说&#xff0c;容器里存储的是元素的拷贝、副本&#xff0c;而不是引用 容器操作元素的很大一块成本就是值的拷贝…

DBA 数据库管理

数据库&#xff1a;存储数据的仓库 数据库服务软件&#xff1a; 关系型数据库&#xff1a; 存在硬盘 &#xff0c;制作表格的 数据库的参数 [rootmysql50 ~]# cat /etc/my.cnf.d/mysql-server.cnf 主配置文件 [mysqld] datadir/var/lib/mysql 存放数据库目录…

浅谈信息技术高效课堂管理:策略、技巧与实践

引言&#xff1a; 在信息化教育的浪潮中&#xff0c;信息技术课程正逐渐成为学校教育体系中的重要组成部分。然而&#xff0c;信息技术课堂的特殊性——高互动性、高度依赖电子设备&#xff0c;给课堂管理带来了前所未有的挑战。如何在保证教学效率的同时&#xff0c;维护良好…

多端多商户自定义DIY商城小程序源码系统 前后端分离 带完整的安装代码包以及搭建教程

系统概述 在当今数字化时代&#xff0c;电子商务的发展日新月异&#xff0c;为了满足不断变化的市场需求和用户期望&#xff0c;我们自豪地推出了一款具有前瞻性的创新产品——多端多商户自定义 DIY 商城小程序源码系统。这款系统不仅具备前后端分离的先进架构&#xff0c;还配…

git 禁止dev合并到任何其他分支

创建 pre-merge-commit 钩子 导航到 Git 仓库的钩子目录&#xff1a; cd /path/to/your/repo/.git/hooks创建或编辑 pre-merge-commit 钩子&#xff1a; 也可以通过指令创建 nano pre-merge-commit在钩子文件中添加以下代码&#xff1a; #!/bin/sh# 获取当前分支名称 curr…

使用tcpdump抓取本本机的所有icmp包

1、抓取本机所有icmp包 tcpdump -i any icmp -vv 图中上半部分&#xff0c;是源主机tmp179无法ping通目标主机192.168.10.79&#xff08;因为把该主机关机了&#xff09;的状态&#xff0c;注意看&#xff0c;其中有unreachable 图中下半部分&#xff0c;是源主机tmp179可以p…

RIP环境下的MGRE网络

首先将LSP的IP地址进行配置 其他端口也进行同样的配置 将serial3/0/1配置25.0.0.2 24 将serial4/0/0配置35.0.0.2 24 将GE0/0/0配置45.0.0.2 24 进行第二步 R1与R5之间使用ppp的pap认证 在R5中进行配置 在aaa空间中创建账号和密码 将这个账号和密码使用在ppp协议中 然后…

什么是静态住宅代理?一文看懂它

静态住宅代理&#xff08;也称为 ISP 代理&#xff09;是最流行的代理类型之一。它们也是隐藏身份和在线匿名的最佳方式之一。但是您需要了解它们什么&#xff1f;是什么让它们如此特别&#xff1f;为什么您要使用住宅代理而不是仅仅使用常规代理服务&#xff1f;如果你感兴趣&…

移动的话费充值卡有什么用?

现在大部分人充话费都是直接用微信啊、支付宝啥的充 话费卡绑定麻烦不说&#xff0c;一些不太熟悉操作的人&#xff0c;对话费卡的使用方法更是头疼 这不前两天我刚用积分兑了几张移动的话费卡&#xff0c;绑定过程真的太麻烦了 最后还是在收卡云上卖出去了&#xff0c;这样…

周鸿祎数字分身亮相世界人工智能大会,应对“刁难提问”对答如流

近日&#xff0c;2024世界人工智能大会&#xff08;WAIC&#xff09;在上海举办&#xff0c;三六零集团&#xff08;601360.SH&#xff0c;下称“360”&#xff09;携多款大模型创新应用亮相全球顶尖盛会&#xff0c;以技术引擎、场景应用、安全赋能和产业联盟四大主题&#xf…