使用MethodInterceptor和ResponseBodyAdvice做分页处理

目录

一、需求

二、代码实现

父pom文件

pom文件

配置文件

手动注册SqlSessionFactory(MyBatisConfig )

对象

实体类Users

 抽象类AbstractQuery 

查询参数类UsersQuery 

三层架构

 UsersController 

 UsersServiceImpl 

 UsersMapper 

 UsersMapper.xml

PageX 注解

MyResponseBodyAdvice 

构造返回对象泛型ResponseDto

拦截器PageMethodInterceptor

拦截器注入(PageMethodInterceptorConfig )

结果展示


一、需求

使用ResponseBodyAdvice做分页处理_骑着蜗牛打天下的博客-CSDN博客

在之前使用过用ResponseBodyAdvice来做分页处理,但是我们还可以结合着Aop中的MethodInterceptor拦截器对分页进一步封装;

使用ResponseBodyAdvice的做法:

 

 这样的做法就是使用ResponseBodyAdvice去拦截controller层返回值,然后对返回的page类型的值进行封装成带有 total、pages、body等;

而本篇的目的是使用aop拦截器去拦截标注切点的方法然后对此方法进行拦截,拦截后就在拦截器内去做 PageHelper.startPage处理,然后在controller层返回时再使用ResponseBodyAdvice拦截,进一步的把数据给封装!

二、代码实现

父pom文件

<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><!--        <version>3.1.2</version>--><version>2.2.5.RELEASE</version><relativePath/> <!-- lookup parent from repository --></parent><groupId>com.chensir</groupId><artifactId>springboot</artifactId><version>0.0.1-SNAPSHOT</version><name>springboot</name><description>springboot</description><properties><java.version>8</java.version><hutool.version>5.8.3</hutool.version><lombok.version>1.18.24</lombok.version><alibaba-sdk.version>2.0.0</alibaba-sdk.version></properties><packaging>pom</packaging><modules><module>servlet</module><module>spring-interceptor</module><module>spring-aop</module><module>spring-united-reslut</module><module>spring-jdbc</module><module>spring-mybatis</module><module>spring-mybatis-pageX</module></modules><dependencyManagement><dependencies><!--钉钉机器人消息--><dependency><groupId>com.aliyun</groupId><artifactId>alibaba-dingtalk-service-sdk</artifactId><version>${alibaba-sdk.version}</version></dependency><dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>${hutool.version}</version></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>${lombok.version}</version></dependency>
<!--父pom中不要加此依赖,否则依赖clean会报错,原因是父pom中并没指定版本-->
<!--            <dependency>-->
<!--                <groupId>org.springframework.boot</groupId>-->
<!--                <artifactId>spring-boot-starter-web</artifactId>-->
<!--            </dependency>--><!--            <dependency>-->
<!--                <groupId>org.springframework.boot</groupId>-->
<!--                <artifactId>spring-boot-starter-test</artifactId>-->
<!--                <scope>test</scope>-->
<!--            </dependency>--></dependencies></dependencyManagement><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build></project>

pom文件

<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>com.chensir</groupId><artifactId>springboot</artifactId><version>0.0.1-SNAPSHOT</version><relativePath>../pom.xml</relativePath></parent><artifactId>spring-mybatis-pageX</artifactId><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-aop</artifactId></dependency><dependency><groupId>com.github.pagehelper</groupId><artifactId>pagehelper</artifactId><version>5.1.10</version></dependency><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>2.1.4</version></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><scope>runtime</scope></dependency><dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter-test</artifactId><version>2.1.4</version><scope>test</scope></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><configuration><excludes><exclude><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></exclude></excludes></configuration></plugin></plugins></build></project>

配置文件

spring.datasource.url=jdbc:mysql://localhost/db1?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&autoReconnect=true&rewriteBatchedStatements=true
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driveraop.MethodInterceptor.point = @annotation(com.chensir.annotation.PageX)

 手动注册SqlSessionFactory(MyBatisConfig )

package com.chensir.config;import com.github.pagehelper.PageInterceptor;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.boot.autoconfigure.ConfigurationCustomizer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver;
import org.springframework.util.CollectionUtils;import javax.sql.DataSource;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;@Configuration
@Slf4j
public class MyBatisConfig {@Autowiredprivate ConfigurationCustomizer configurationCustomizer;/*** 自己注册SqlSessionFactory 目的是增强功能,添加分页插件* @param ds 代表数据源* @return* @throws Exception*/@Beanpublic SqlSessionFactory sqlSessionFactory(DataSource ds) throws Exception {SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean();// 设置数据源factoryBean.setDataSource(ds);// 把分页插件设置到SqlSessionFactory插件库factoryBean.setPlugins(new PageInterceptor());// 配置mapper.xml地址factoryBean.setMapperLocations(resolveMapperLocations());//驼峰映射注册到SqlSessionFactory中org.apache.ibatis.session.Configuration configuration = new org.apache.ibatis.session.Configuration();configurationCustomizer.customize(configuration);factoryBean.setConfiguration(configuration);// 返回具体实例对象SqlSessionFactory bean = factoryBean.getObject();return bean;}/*** 开启驼峰映射* @return*/@Beanpublic ConfigurationCustomizer configurationCustomizer(){return new ConfigurationCustomizer() {@Overridepublic void customize(org.apache.ibatis.session.Configuration configuration) {configuration.setMapUnderscoreToCamelCase(true);}};}/*** 查找 xxxMapper.xml* @return*/public Resource[] resolveMapperLocations() {ResourcePatternResolver resourceResolver = new PathMatchingResourcePatternResolver();List<String> mapperLocations = new ArrayList<>();mapperLocations.add("classpath*:mapper/*Mapper.xml");
//        mapperLocations.add("classpath*:com/meiwei/ping/dao/**/*Mapper.xml");List<Resource> resources = new ArrayList();if (!CollectionUtils.isEmpty(mapperLocations)) {for (String mapperLocation : mapperLocations) {try {Resource[] mappers = resourceResolver.getResources(mapperLocation);resources.addAll(Arrays.asList(mappers));} catch (IOException e) {log.error("Get myBatis resources happened exception", e);}}}return resources.toArray(new Resource[resources.size()]);}}

对象

实体类Users

@Data
public class Users {private Long id;private String name;private Integer age;private String sex;private String tel;// 数据库timestamp类型时间转化java规定格式时间@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd")// 接受前端表单传递过来的字符串类型的时间数@DateTimeFormat(pattern = "yyyy-MM-dd")private Date createTime;@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd")@DateTimeFormat(pattern = "yyyy-MM-dd")private LocalDateTime updateTime;
}

 抽象类AbstractQuery 

public abstract class AbstractQuery implements Serializable {private Integer pageNum = 1;private Integer pageSize = 10;public Integer getPageNum() {return pageNum;}public void setPageNum(Integer pageNum) {this.pageNum = pageNum;}public Integer getPageSize() {return pageSize;}public void setPageSize(Integer pageSize) {this.pageSize = pageSize;}
}

查询参数类UsersQuery 

@Data
public class UsersQuery extends AbstractQuery {private Long id;private String name;private Integer age;private String sex;private String tel;
}

三层架构

 UsersController 

@RestController
public class UsersController {@Resourceprivate UsersService usersService;@PostMapping("/pageQuery")public List selectUsersByPageQuery(@RequestBody UsersQuery usersQuery){// 使用MethodInterceptor进行分页 @PageX为切点,使用地方开启分页处理List<Users> usersList = usersService.selectUsersByPageQuery(usersQuery);return usersList;}@GetMapping("/demo1")public List selectUsersList(Integer pageNum,Integer pageSize) {// 启用分页,查询第一页,每页3条PageHelper.startPage(pageNum,pageSize);//-------------PageInfo方式---------------
//        PageInfo<Users> usersPageInfo = new PageInfo<>(usersService.selectUsersList());
//        return usersPageInfo;//-------------PageInfo方式---------------//-------------Page方式---------------
//        List<Users> users = usersService.selectUsersList();
//        Page page = (Page) users;
//        int pages = page.getPages();
//        long total = page.getTotal();
//
//
//        Map<String,Object> pageMap = new HashMap<>();
//        pageMap.put("pages",pages);
//        pageMap.put("total",total);
//        pageMap.put("items",users);
//        return pageMap;//-------------Page方式---------------//-----------使用ResponseBodyAdvice------------List<Users> users = usersService.selectUsersList();return users;//-----------使用ResponseBodyAdvice------------}@GetMapping("/demo2")public Users selectUsers(){Users users = usersService.selectUsers();return users;}@GetMapping("/demo3")public Map selectUsersToMap(){return usersService.selectUsersToMap();}
}

 UsersServiceImpl 

@Service
public class UsersServiceImpl implements UsersService {@Resourceprivate UsersMapper usersMapper;@Overridepublic List<Users> selectUsersList() {return usersMapper.selectUsersList();}@Overridepublic Users selectUsers() {return usersMapper.selectUsers();}@Overridepublic Map<String, Object> selectUsersToMap() {return usersMapper.selectUsersToMap();}@Overridepublic List<Users> selectUsersByPageQuery(UsersQuery usersQuery) {return usersMapper.selectUsersByPageQuery(usersQuery);}
}

 UsersMapper 

@Mapper
public interface UsersMapper {List<Users> selectUsersList();Users selectUsers();Map<String,Object> selectUsersToMap();//此接口带有@PageX 拦截器会拦截它 然后做分页处理@PageXList<Users> selectUsersByPageQuery(UsersQuery usersQuery);
}

 UsersMapper.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.chensir.mapper.UsersMapper"><select id="selectUsersList" resultType="com.chensir.domain.entity.Users">select * from users</select><select id="selectUsers" resultType="com.chensir.domain.entity.Users">select * from users where id = 1</select><select id="selectUsersToMap" resultType="java.util.Map">select * from users where id = 1</select><select id="selectUsersByPageQuery" resultType="com.chensir.domain.entity.Users">select * from users<where>1=1<if test="name != null and name != ''">and name like concat('%', #{name},'%')</if></where></select>
</mapper>

 PageX 注解

注解来作为切点,使用时,在配置文件中先配置,注入@bean时使用@value取值,然后对带有此注解的方法进行扫描拦截;

@Deprecated
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface PageX {
}

MyResponseBodyAdvice 

package com.chensir.advice;import cn.hutool.core.lang.Dict;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.github.pagehelper.Page;
import org.springframework.core.MethodParameter;
import org.springframework.http.MediaType;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;import javax.servlet.http.HttpServletRequest;// 拦截范围为 com.chensir.controller包下内容
@RestControllerAdvice(basePackages = {"com.chensir.controller"})
public class MyResponseBodyAdvice implements ResponseBodyAdvice {// 是否开启拦截 true开启 false不开启@Overridepublic boolean supports(MethodParameter methodParameter, Class aClass) {// 此处应该改为true,否则除了异常外 走到此处为false后就直接返回,也不再继续往下走了!return true;}// 如果接口返回异常就在此处拦截 进行封装;value = Exception.class 对所有的异常均拦截!@ExceptionHandler(value = Exception.class)public Object defaultErrorHandler(HttpServletRequest req, Exception ex){ResponseDto<Object> responseDto = new ResponseDto<>();responseDto.setCode(501);responseDto.setMessage(ex.getMessage());return responseDto;}@Overridepublic Object beforeBodyWrite(Object body, MethodParameter methodParameter, MediaType mediaType, Class aClass, ServerHttpRequest serverHttpRequest, ServerHttpResponse serverHttpResponse) {ResponseDto<Object> responseDto = new ResponseDto<>();// 先用hutool定义为nullString message = StrUtil.EMPTY;responseDto.setCode(0);responseDto.setMessage(message);if (body instanceof Page){Page page = (Page) body;int pages = page.getPages();//总页数long total = page.getTotal();//总条数Dict dict = Dict.create().set("total",total).set("pages",pages).set("item",body);responseDto.setData(dict);}else {responseDto.setData(body);}// 如果是string类型就用json封装一下;if (aClass == StringHttpMessageConverter.class) {return JSONUtil.toJsonStr(responseDto);} else {return responseDto;}}
}

构造返回对象泛型ResponseDto<T>

// 泛型
@Data
public class ResponseDto<T> implements Serializable {// 返回码(内部拟定)private int code;// 返回信息private String message;private T data;
}

拦截器PageMethodInterceptor

package com.chensir.interceptor;import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONUtil;
import com.chensir.domain.AbstractQuery;
import com.github.pagehelper.PageHelper;
import lombok.extern.slf4j.Slf4j;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;import java.lang.reflect.Method;@Slf4j
public class PageMethodInterceptor implements MethodInterceptor {@Overridepublic Object invoke(MethodInvocation invocation) throws Throwable {// 获取方法Method method = invocation.getMethod();//获取参数Object[] arguments = invocation.getArguments();//获取第一个参数Object arg0 = arguments[0];if (arg0 instanceof AbstractQuery) {AbstractQuery query = (AbstractQuery) arg0;Integer pageNum = query.getPageNum();//参数 第几页Integer pageSize = query.getPageSize();//参数 每页多少条if (ObjectUtil.isNotEmpty(pageNum) && ObjectUtil.isNotEmpty(pageSize)) {//走到这肯定要分页了PageHelper.startPage(pageNum,pageSize);}}//获取返回值Object value = invocation.proceed();log.info("方法:{},参数:{},返回值:{}", method.getName(), JSONUtil.toJsonStr(arguments), value);return value;}
}

拦截器注入(PageMethodInterceptorConfig )

advisor.setExpression(point); 拦截切点为@PageX的注解

@Configuration
public class PageMethodInterceptorConfig {@Value("${aop.MethodInterceptor.point}")private String point;@Beanpublic AspectJExpressionPointcutAdvisor aspectJExpressionPointcutAdvisor(){AspectJExpressionPointcutAdvisor advisor = new AspectJExpressionPointcutAdvisor();advisor.setAdvice(new PageMethodInterceptor());advisor.setExpression(point);return advisor;}
}

结果展示

 

 

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

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

相关文章

苹果电脑图像元数据编辑器:MetaImage for Mac

MetaImage for Mac是一款功能强大的照片元数据编辑器&#xff0c;它可以帮助用户编辑并管理照片的元数据信息&#xff0c;包括基本信息和扩展信息。用户可以根据需要进行批量处理&#xff0c;方便快捷地管理大量照片。 MetaImage for Mac还提供了多种导入和导出格式&#xff0…

12v转5v降压模块

问&#xff1a;什么是12V转5V降压模块&#xff1f;它的功能是什么&#xff1f; 答&#xff1a;12V转5V降压模块是一种电子设备&#xff0c;用于将输入电压为12V的直流电转换为输出电压为5V的直流电。它的主要功能是为电子设备提供所需的适当电压&#xff0c;以便它们能够正常运…

mysql进阶篇(二)

前言 「作者主页」&#xff1a;雪碧有白泡泡 「个人网站」&#xff1a;雪碧的个人网站 「推荐专栏」&#xff1a; ★java一站式服务 ★ ★ React从入门到精通★ ★前端炫酷代码分享 ★ ★ 从0到英雄&#xff0c;vue成神之路★ ★ uniapp-从构建到提升★ ★ 从0到英雄&#xff…

GCC编译过程:预处理->编译->汇编->链接

目录 引言 概括介绍 一、预处理 二、编译 三、汇编 四、链接 总结 引言 当使用集成开发环境&#xff08;IDE&#xff09;进行C语言编程时&#xff0c;点击"编译"按钮后&#xff0c;整个C程序从源代码到可执行文件的生成过程会自动完成。IDE会在后台为我们执行C…

QT QLCDNumber 使用详解

本文详细的介绍了QLCDNumber控件的各种操作&#xff0c;例如&#xff1a;新建界面、源文件、设置显示位数、设置进制、设置外观、设置小数点、设置溢出、显示事件、其它文章等等操作。 实际开发中&#xff0c;一个界面上可能包含十几个控件&#xff0c;手动调整它们的位置既费时…

Activity启动过程详解(Android 12源码分析)

Activity的启动方式 启动一个Activity&#xff0c;通常有两种情况&#xff0c;一种是在应用内部启动Activity&#xff0c;另一种是Launcher启动 1、应用内启动 通过startActivity来启动Activity 启动流程&#xff1a; 一、Activity启动的发起 二、Activity的管理——ATMS 三、…

怎么在JMeter中的实现关联

我们一直用的phpwind这个系统做为演示系统, 如果没有配置好的同学, 请快速配置之后接着往下看哦. phpwind发贴时由于随着登陆用户的改变, verifycode是动态变化的, 因此需要用到关联. LoadRunner的关联函数是reg_save_param, Jmeter的关联则是利用后置处理器来完成. 在需要查…

字节编码学习

字节编码学习 文章目录 字节编码学习01_字节与ASCII码表02_每个国家都有独特的码表03_国际化UTF-804_编码本和解码本不一致&#xff0c;乱码 01_字节与ASCII码表 public class Demo01 {public static void main(String[] args) {// 计算机的底层全部都是字节 ---- ----// 一个…

1.利用matlab建立符号表达式(matlab程序)

1.简述 、 1. 使用sym命令创建符号变量和表达式 语法&#xff1a; sym(‘变量’,参数) %把变量定义为符号对象 说明&#xff1a;参数用来设置限定符号变量的数学特性&#xff0c;可以选择为’positive’、’real’和’unreal’&#xff0c; ’positive’ 表示为“正、实”符…

C++的auto究竟是何方神圣

C的auto究竟是何方神圣 前言&#x1f64c;auto&#xff08;C 11&#xff09; 的使用细则auto是什么&#xff1f; auto声明的变量是在什么时期被编译器推导出来呢&#xff1f;为什么使用auto进行定义变量时&#xff0c;必须进行初始化&#xff1f; auto 的使用场景auto与指针和引…

软件安全测试包含哪些内容和方法?安全测试报告的必要性

软件安全测试是一种通过模拟真实攻击的方式&#xff0c;对软件系统进行全面的安全性评估和测试&#xff0c;以发现潜在的安全漏洞和弱点&#xff0c;是确保软件系统安全性的重要措施。在进行软件安全测试时&#xff0c;我们需要了解测试的内容和方法&#xff0c;以及为什么进行…

FastAPI 构建 API 高性能的 web 框架(一)

如果要部署一些大模型一般langchainfastapi&#xff0c;或者fastchat&#xff0c; 先大概了解一下fastapi,本篇主要就是贴几个实际例子。 官方文档地址&#xff1a; https://fastapi.tiangolo.com/zh/ 1 案例1:复旦MOSS大模型fastapi接口服务 来源&#xff1a;大语言模型工程…

C语言学习笔记 vscode使用外部console-11

前言 在默认情况下&#xff0c;我们运行C语言程序都是在vscode终端的&#xff0c;在小程序运行时这个是没有问题的&#xff0c;但是当程序变得复杂它就不好用了&#xff0c;这时我们可以将这个终端设置为外部console&#xff0c;这样方便处理更多、更复杂的程序。 步骤 1.点击…

PCB电路板设计基础入门学习笔记

文章目录&#xff1a; 一&#xff1a;Arduino线路板绘制&#xff08;原理图库、PCB库、原理图、PCB图绘制&#xff09; 1.原理图库绘制Schematic Library&#xff08;有现成库&#xff0c;没有就自己画&#xff09;[SCH Library] 方法一&#xff1a;自己依次画 ATMEGA328P-…

HTTP——十一、Web的攻击技术

HTTP 一、针对Web的攻击技术1、HTTP 不具备必要的安全功能2、在客户端即可篡改请求3、针对Web应用的攻击模式 二、因输出值转义不完全引发的安全漏洞1、跨站脚本攻击2、SQL 注入攻击3、OS命令注入攻击4、HTTP首部注入攻击5、邮件首部注入攻击6、目录遍历攻击7、远程文件包含漏洞…

【cluster_block_exception】写操作elasticsearch索引报错

【cluster_block_exception】操作elasticsearch索引b报错 背景导致原因&#xff1a;解决方法&#xff1a; 背景 今天线上elk的数据太多&#xff0c;服务器的空间不足了。所以打算删除一些没用用的数据。我是用下面的request&#xff1a; POST /{index_name}/_delete_by_query…

Promise详细版

promise基础原理到难点分析 常见的Promise的方法解读 扩展async和await深入分析 逐步分析Promise底层逻辑代码 一、Promise基础 1.什么是promise 为了解决回调地狱&#xff1a; //2.设置点击事件btn.onclick function() {//3.创建ajax实例化对象let xhr new XMLHttpRe…

流量,日志分析

wireshark wireshark中有捕获过滤器和显示过滤器 常用的捕获过滤表达式&#xff1a; 常见的显示过滤表达式&#xff1a; 语法&#xff1a; 1.过滤IP&#xff0c;如来源IP或者目标IP等于某个IP 例子: ip.src eq 192.168.1.107 or ip.dst eq 192.168.1.107 或者 ip.addr eq 1…

DAY03_Spring—SpringAOPAOP切入点表达式AOP通知类型Spring事务管理

目录 一 AOP1 AOP简介问题导入1.1 AOP简介和作用1.2 AOP中的核心概念 2 AOP入门案例问题导入2.1 AOP入门案例思路分析2.2 AOP入门案例实现【第一步】导入aop相关坐标【第二步】定义dao接口与实现类【第三步】定义通知类&#xff0c;制作通知方法【第四步】定义切入点表达式、配…

(八)穿越多媒体奇境:探索Streamlit的图像、音频与视频魔法

文章目录 1 前言2 st.image&#xff1a;嵌入图像内容2.1 图像展示与描述2.2 调整图像尺寸2.3 使用本地文件或URL 3 st.audio&#xff1a;嵌入音频内容3.1 播放音频文件3.2 生成音频数据播放 4 st.video&#xff1a;嵌入视频内容4.1 播放视频文件4.2 嵌入在线视频 5 结语&#x…