【Spring MVC】Filter 过滤器异常处理 HandlerExceptionResolver 分析

文章目录

    • 前言
    • 版本说明
    • 测试 Demo
      • 1、自定义过滤器 DemoFilter
      • 2、自定义业务异常 ServiceException
      • 3、自定义异常处理类 DemoExceptionHandler
      • 4、DemoController
      • 5、请求测试
    • 问题分析
      • 1、日志打印记录
      • 2、Debug 方法
    • 解决方案
      • 1、修改自定义过滤器
      • 2、请求测试
    • 解决方案分析
      • 1、日志打印记录
      • 2、Debug 方法
    • 对比总结
    • 扩展
      • Filter、Interceptor、ControllerAdvice、Aspect 执行顺序
    • 附录
      • 附录1:直接抛出异常的详细日志

前言

最近在开发过滤器功能的时候遇到一个有趣的问题:

FilterChain#doFilter 方法之前抛出了一个异常,但是这个异常无法被异常处理器捕获,需要使用 HandlerExceptionResolver 来处理异常。

因此本文来分析一下这个问题。

版本说明

本文使用的版本如下:

  • Spring Bootv3.1.5
  • Lombokv1.18.26
  • Hutoolv5.8.15

测试 Demo

Demo 打成了压缩包(在文章开头)可以自行下载使用。

1、自定义过滤器 DemoFilter

在这里插入图片描述

2、自定义业务异常 ServiceException

在这里插入图片描述

3、自定义异常处理类 DemoExceptionHandler

在这里插入图片描述

4、DemoController

在这里插入图片描述

5、请求测试

请求 URL:

http://localhost:8080/hello

请求结果:

在这里插入图片描述

返回了错误码 500,且错误信息是:

{"timestamp": "2023-11-26T03:43:07.655+00:00","status": 500,"error": "Internal Server Error","path": "/hello"
}

这里并没有返回理想中的结果:

在自定义异常处理器重定义的错误码是 400,返回信息应该是 ServiceException: / by zero

问题分析

1、日志打印记录

根据日志的打印结果来 Debug 分析一下整个流程:

2023-11-26T11:49:25.841+08:00  INFO 5748 --- [  XNIO-1 task-2] space.zlyx.demo.mvc.filter.DemoFilter    : DemoFilterBefore: 在请求经过过滤器之前的操作
2023-11-26T11:49:25.842+08:00 ERROR 5748 --- [  XNIO-1 task-2] io.undertow.request                      : UT005023: Exception handling request to /hellospace.zlyx.demo.mvc.exception.ServiceException: ServiceException: / by zero
# 省略详细报错(完整日志可查看文末附录)2023-11-26T11:49:25.842+08:00 DEBUG 5748 --- [  XNIO-1 task-2] o.s.web.servlet.DispatcherServlet        : "ERROR" dispatch for GET "/error", parameters={}
2023-11-26T11:49:25.843+08:00 DEBUG 5748 --- [  XNIO-1 task-2] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped to org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController#error(HttpServletRequest)
2023-11-26T11:49:25.843+08:00 DEBUG 5748 --- [  XNIO-1 task-2] o.s.w.s.m.m.a.HttpEntityMethodProcessor  : Using 'application/json', given [*/*] and supported [application/json, application/*+json]
2023-11-26T11:49:25.844+08:00 DEBUG 5748 --- [  XNIO-1 task-2] o.s.w.s.m.m.a.HttpEntityMethodProcessor  : Writing [{timestamp=Sun Nov 26 11:49:25 CST 2023, status=500, error=Internal Server Error, path=/hello}]
2023-11-26T11:49:25.845+08:00 DEBUG 5748 --- [  XNIO-1 task-2] o.s.web.servlet.DispatcherServlet        : Exiting from "ERROR" dispatch, status 500

日志信息可以看出异常抛出之后没有进入异常处理器,直接就写出了。

2、Debug 方法

org.springframework.web.servlet.DispatcherServlet#doService

在这里插入图片描述

org.springframework.web.servlet.DispatcherServlet#logRequest

在这里插入图片描述

在这里插入图片描述

org.springframework.web.servlet.DispatcherServlet#doDispatch

在这里插入图片描述

// Actually invoke the handler.
mv = ha.handle(processedRequest, response, mappedHandler.getHandler());

org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod#invokeAndHandle

在这里插入图片描述

org.springframework.web.servlet.mvc.method.annotation.HttpEntityMethodProcessor#handleReturnValue

在这里插入图片描述

org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodProcessor#writeWithMessageConverters

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

解决方案

1、修改自定义过滤器

在自定义过滤器中使用 HandlerExceptionResolver 处理异常信息:

在这里插入图片描述

2、请求测试

请求 URL:

http://localhost:8080/hello

请求结果:

在这里插入图片描述

修改之后返回了正确的错误信息以及错误码。

解决方案分析

1、日志打印记录

2023-11-26T13:02:11.053+08:00  INFO 11220 --- [  XNIO-1 task-2] space.zlyx.demo.mvc.filter.DemoFilter    : DemoFilterBefore: 在请求经过过滤器之前的操作
2023-11-26T13:02:11.053+08:00 DEBUG 11220 --- [  XNIO-1 task-2] .m.m.a.ExceptionHandlerExceptionResolver : Using @ExceptionHandler space.zlyx.demo.mvc.handler.DemoExceptionHandler#handleServiceException(ServiceException, HttpServletRequest)
2023-11-26T13:02:11.054+08:00 ERROR 11220 --- [  XNIO-1 task-2] s.z.d.mvc.handler.DemoExceptionHandler   : 业务异常捕获:Filter ServiceException: / by zero
2023-11-26T13:02:11.054+08:00 DEBUG 11220 --- [  XNIO-1 task-2] m.m.a.RequestResponseBodyMethodProcessor : Using 'text/plain', given [*/*] and supported [text/plain, */*, application/json, application/*+json]
2023-11-26T13:02:11.054+08:00 DEBUG 11220 --- [  XNIO-1 task-2] m.m.a.RequestResponseBodyMethodProcessor : Writing ["Filter ServiceException: / by zero"]
2023-11-26T13:02:11.055+08:00 DEBUG 11220 --- [  XNIO-1 task-2] .m.m.a.ExceptionHandlerExceptionResolver : Resolved [ServiceException(code=null, message=Filter ServiceException: / by zero)]
2023-11-26T13:02:11.055+08:00 DEBUG 11220 --- [  XNIO-1 task-2] o.s.web.servlet.DispatcherServlet        : GET "/hello", parameters={}
2023-11-26T13:02:11.055+08:00 DEBUG 11220 --- [  XNIO-1 task-2] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped to space.zlyx.demo.mvc.controller.DemoController#hello(HttpServletRequest, HttpServletResponse)
2023-11-26T13:02:11.055+08:00  INFO 11220 --- [  XNIO-1 task-2] s.z.demo.mvc.controller.DemoController   : DemoController hello
2023-11-26T13:02:11.055+08:00 DEBUG 11220 --- [  XNIO-1 task-2] m.m.a.RequestResponseBodyMethodProcessor : Found 'Content-Type:text/plain;charset=UTF-8' in response
2023-11-26T13:02:11.055+08:00 DEBUG 11220 --- [  XNIO-1 task-2] m.m.a.RequestResponseBodyMethodProcessor : Writing ["Hello World"]
2023-11-26T13:02:11.056+08:00 DEBUG 11220 --- [  XNIO-1 task-2] o.s.web.servlet.DispatcherServlet        : Completed 400 BAD_REQUEST
2023-11-26T13:02:11.056+08:00  INFO 11220 --- [  XNIO-1 task-2] space.zlyx.demo.mvc.filter.DemoFilter    : DemoFilterAfter: 在请求经过过滤器之后的操作

2、Debug 方法

在这里插入图片描述

在这里插入图片描述

org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver#doResolveHandlerMethodException

在这里插入图片描述

org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod#invokeAndHandle

在这里插入图片描述

DemoExceptionHandler#handleServiceException

在这里插入图片描述

org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor#handleReturnValue

在这里插入图片描述

org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodProcessor#writeWithMessageConverters

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

对比总结

经过两种不同的方式的调用对比,可以得出以下结论:

  1. FilterChain#doFilter 之前直接抛出异常,则过滤器链中断,抛出异常之后结果由 HttpEntityMethodProcessor 进行处理。
  2. 使用 HandlerExceptionResolver#resolveException 方法,异常会被 ExceptionHandlerExceptionResolver 进行处理,此时能够被异常拦截器捕获,最终返回的结果由 RequestResponseBodyMethodProcessor 进行处理。
  3. 使用 HandlerExceptionResolver 时,因为过滤器链没有中断,因此内部会继续执行 controller 方法,但是请求结果已经提前输出了。

扩展

Filter、Interceptor、ControllerAdvice、Aspect 执行顺序

在没有异常的情况下,各组件调用顺序如下(不包含 ControllerAdvice):

  • FilterChain#doFilter 之前
  • Interceptor#preHandle
  • Aspect#before
  • Controller
  • Aspect#afterReturning
  • Aspect#after
  • Interceptor#postHandle
  • Interceptor#afterCompletion
  • FilterChain#doFilter 之后

在本文基础上顺便测试了一下 Interceptor 以及 Aspect,并在各个组件中抛出异常,得到的结果如下:

注:ControllerAdvice 即异常处理器

异常位置异常抛出方式调用方法
FilterHandlerExceptionResolverFilterChain#doFilter 之前(异常)
ControllerAdvice
Interceptor#preHandle
Aspect#before
Controller
Aspect#afterReturning
Aspect#after
Interceptor#postHandle
Interceptor#afterCompletion
FilterChain#doFilter 之后
Interceptor直接抛异常FilterChain#doFilter 之前
Interceptor#preHandle(异常)
ControllerAdvice
FilterChain#doFilter 之后
Aspect直接抛异常FilterChain#doFilter 之前
Interceptor#preHandle
Aspect#before(异常)
ControllerAdvice
Interceptor#afterCompletion
FilterChain#doFilter 之后
Controller直接抛异常FilterChain#doFilter 之前
Interceptor#preHandle
Aspect#before
Controller(异常)
Aspect#afterThrowing
Aspect#after
ControllerAdvice
Interceptor#afterCompletion
FilterChain#doFilter 之后

请求进入执行顺序:
Filter —— Interceptor —— Aspect —— Controller

异常抛出执行顺序:
Controller —— Aspect —— ControllerAdvice —— Interceptor —— Filter

附录

附录1:直接抛出异常的详细日志

2023-11-26T11:49:25.841+08:00  INFO 5748 --- [  XNIO-1 task-2] space.zlyx.demo.mvc.filter.DemoFilter    : DemoFilterBefore: 在请求经过过滤器之前的操作
2023-11-26T11:49:25.842+08:00 ERROR 5748 --- [  XNIO-1 task-2] io.undertow.request                      : UT005023: Exception handling request to /hellospace.zlyx.demo.mvc.exception.ServiceException: ServiceException: / by zeroat space.zlyx.demo.mvc.filter.DemoFilter.doFilter(DemoFilter.java:40) ~[classes/:na]at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:67) ~[undertow-servlet-2.3.10.Final.jar:2.3.10.Final]at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131) ~[undertow-servlet-2.3.10.Final.jar:2.3.10.Final]at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100) ~[spring-web-6.0.13.jar:6.0.13]at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[spring-web-6.0.13.jar:6.0.13]at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:67) ~[undertow-servlet-2.3.10.Final.jar:2.3.10.Final]at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131) ~[undertow-servlet-2.3.10.Final.jar:2.3.10.Final]at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93) ~[spring-web-6.0.13.jar:6.0.13]at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[spring-web-6.0.13.jar:6.0.13]at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:67) ~[undertow-servlet-2.3.10.Final.jar:2.3.10.Final]at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131) ~[undertow-servlet-2.3.10.Final.jar:2.3.10.Final]at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) ~[spring-web-6.0.13.jar:6.0.13]at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[spring-web-6.0.13.jar:6.0.13]at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:67) ~[undertow-servlet-2.3.10.Final.jar:2.3.10.Final]at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131) ~[undertow-servlet-2.3.10.Final.jar:2.3.10.Final]at io.undertow.servlet.handlers.FilterHandler.handleRequest(FilterHandler.java:84) ~[undertow-servlet-2.3.10.Final.jar:2.3.10.Final]at io.undertow.servlet.handlers.security.ServletSecurityRoleHandler.handleRequest(ServletSecurityRoleHandler.java:62) ~[undertow-servlet-2.3.10.Final.jar:2.3.10.Final]at io.undertow.servlet.handlers.ServletChain$1.handleRequest(ServletChain.java:68) ~[undertow-servlet-2.3.10.Final.jar:2.3.10.Final]at io.undertow.servlet.handlers.ServletDispatchingHandler.handleRequest(ServletDispatchingHandler.java:36) ~[undertow-servlet-2.3.10.Final.jar:2.3.10.Final]at io.undertow.servlet.handlers.RedirectDirHandler.handleRequest(RedirectDirHandler.java:68) ~[undertow-servlet-2.3.10.Final.jar:2.3.10.Final]at io.undertow.servlet.handlers.security.SSLInformationAssociationHandler.handleRequest(SSLInformationAssociationHandler.java:117) ~[undertow-servlet-2.3.10.Final.jar:2.3.10.Final]at io.undertow.servlet.handlers.security.ServletAuthenticationCallHandler.handleRequest(ServletAuthenticationCallHandler.java:57) ~[undertow-servlet-2.3.10.Final.jar:2.3.10.Final]at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43) ~[undertow-core-2.3.10.Final.jar:2.3.10.Final]at io.undertow.security.handlers.AbstractConfidentialityHandler.handleRequest(AbstractConfidentialityHandler.java:46) ~[undertow-core-2.3.10.Final.jar:2.3.10.Final]at io.undertow.servlet.handlers.security.ServletConfidentialityConstraintHandler.handleRequest(ServletConfidentialityConstraintHandler.java:64) ~[undertow-servlet-2.3.10.Final.jar:2.3.10.Final]at io.undertow.security.handlers.AuthenticationMechanismsHandler.handleRequest(AuthenticationMechanismsHandler.java:60) ~[undertow-core-2.3.10.Final.jar:2.3.10.Final]at io.undertow.servlet.handlers.security.CachedAuthenticatedSessionHandler.handleRequest(CachedAuthenticatedSessionHandler.java:77) ~[undertow-servlet-2.3.10.Final.jar:2.3.10.Final]at io.undertow.security.handlers.AbstractSecurityContextAssociationHandler.handleRequest(AbstractSecurityContextAssociationHandler.java:43) ~[undertow-core-2.3.10.Final.jar:2.3.10.Final]at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43) ~[undertow-core-2.3.10.Final.jar:2.3.10.Final]at io.undertow.servlet.handlers.SendErrorPageHandler.handleRequest(SendErrorPageHandler.java:52) ~[undertow-servlet-2.3.10.Final.jar:2.3.10.Final]at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43) ~[undertow-core-2.3.10.Final.jar:2.3.10.Final]at io.undertow.servlet.handlers.ServletInitialHandler.handleFirstRequest(ServletInitialHandler.java:276) ~[undertow-servlet-2.3.10.Final.jar:2.3.10.Final]at io.undertow.servlet.handlers.ServletInitialHandler$2.call(ServletInitialHandler.java:135) ~[undertow-servlet-2.3.10.Final.jar:2.3.10.Final]at io.undertow.servlet.handlers.ServletInitialHandler$2.call(ServletInitialHandler.java:132) ~[undertow-servlet-2.3.10.Final.jar:2.3.10.Final]at io.undertow.servlet.core.ServletRequestContextThreadSetupAction$1.call(ServletRequestContextThreadSetupAction.java:48) ~[undertow-servlet-2.3.10.Final.jar:2.3.10.Final]at io.undertow.servlet.core.ContextClassLoaderSetupAction$1.call(ContextClassLoaderSetupAction.java:43) ~[undertow-servlet-2.3.10.Final.jar:2.3.10.Final]at io.undertow.servlet.handlers.ServletInitialHandler.dispatchRequest(ServletInitialHandler.java:256) ~[undertow-servlet-2.3.10.Final.jar:2.3.10.Final]at io.undertow.servlet.handlers.ServletInitialHandler$1.handleRequest(ServletInitialHandler.java:101) ~[undertow-servlet-2.3.10.Final.jar:2.3.10.Final]at io.undertow.server.Connectors.executeRootHandler(Connectors.java:393) ~[undertow-core-2.3.10.Final.jar:2.3.10.Final]at io.undertow.server.HttpServerExchange$1.run(HttpServerExchange.java:859) ~[undertow-core-2.3.10.Final.jar:2.3.10.Final]at org.jboss.threads.ContextHandler$1.runWith(ContextHandler.java:18) ~[jboss-threads-3.5.0.Final.jar:3.5.0.Final]at org.jboss.threads.EnhancedQueueExecutor$Task.run(EnhancedQueueExecutor.java:2513) ~[jboss-threads-3.5.0.Final.jar:3.5.0.Final]at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.run(EnhancedQueueExecutor.java:1538) ~[jboss-threads-3.5.0.Final.jar:3.5.0.Final]at org.xnio.XnioWorker$WorkerThreadFactory$1$1.run(XnioWorker.java:1282) ~[xnio-api-3.8.8.Final.jar:3.8.8.Final]at java.base/java.lang.Thread.run(Thread.java:833) ~[na:na]2023-11-26T11:49:25.842+08:00 DEBUG 5748 --- [  XNIO-1 task-2] o.s.web.servlet.DispatcherServlet        : "ERROR" dispatch for GET "/error", parameters={}
2023-11-26T11:49:25.843+08:00 DEBUG 5748 --- [  XNIO-1 task-2] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped to org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController#error(HttpServletRequest)
2023-11-26T11:49:25.843+08:00 DEBUG 5748 --- [  XNIO-1 task-2] o.s.w.s.m.m.a.HttpEntityMethodProcessor  : Using 'application/json', given [*/*] and supported [application/json, application/*+json]
2023-11-26T11:49:25.844+08:00 DEBUG 5748 --- [  XNIO-1 task-2] o.s.w.s.m.m.a.HttpEntityMethodProcessor  : Writing [{timestamp=Sun Nov 26 11:49:25 CST 2023, status=500, error=Internal Server Error, path=/hello}]
2023-11-26T11:49:25.845+08:00 DEBUG 5748 --- [  XNIO-1 task-2] o.s.web.servlet.DispatcherServlet        : Exiting from "ERROR" dispatch, status 500

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

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

相关文章

提升技能素养,AMCAP做出合适的决策

近年来,智能配置投资与理财逐渐受到关注并走俏。这是一种简单快捷的智慧化理财方式,通过将个人和家族的闲置资金投入到低风险高流动性的产品中。 国际财富管理投资机构AMCAP集团金融分析师表示:智能配置投资与理财之所以持续走俏&#xff0c…

6.3 Windows驱动开发:内核枚举IoTimer定时器

内核I/O定时器(Kernel I/O Timer)是Windows内核中的一个对象,它允许内核或驱动程序设置一个定时器,以便在指定的时间间隔内调用一个回调函数。通常,内核I/O定时器用于周期性地执行某个任务,例如检查驱动程序…

在Linux上安装KVM虚拟机

一、搭建KVM环境 KVM(Kernel-based Virtual Machine)是一个基于内核的系统虚拟化模块,从Linux内核版本2.6.20开始,各大Linux发行版就已经将其集成于发行版中。KVM与Xen等虚拟化相比,需要硬件支持的完全虚拟化。KVM由内…

使用 kubeadm 部署 Kubernetes 集群(一)linux环境准备

一、 初始化集群环境 准备三台 rocky8.8 操作系统的 linux 机器。每台机器配置:4VCPU/4G 内存/60G 硬盘 环境说明: IP 主机名 角色 内存 cpu 192.168.1.63 xuegod63 master 4G 4vCPU 192.168.1.64 xuegod64 worker 4G 4vCPU 192.168.1.62 xuegod62 work…

Python 异常处理(try except)

文章目录 1 概述1.1 异常示例 2 异常处理2.1 捕获异常 try except2.2 抛出异常 raise 3 异常类型3.1 内置异常3.2 自定义异常 1 概述 1.1 异常示例 异常:程序执行中出现错误,若不处理,则程序终止 示例代码: v 6 / 0 # 除数不…

基于matlab的图像去噪算法设计与实现

摘 要 随着我们生活水平的提高,科技产品飞速更新换代,在信息传输中,图像传输所占的比重越来越大。但自然噪声会在图像传输时干扰其传输过程,甚至会使图片不能表达其原来的意义。去噪处理就是为了去除图像中的噪声,从而…

【数据清洗 | 数据规约】数据类别型数据 编码最佳实践,确定不来看看?

🤵‍♂️ 个人主页: AI_magician 📡主页地址: 作者简介:CSDN内容合伙人,全栈领域优质创作者。 👨‍💻景愿:旨在于能和更多的热爱计算机的伙伴一起成长!!&…

tex2D使用学习

1. 背景&#xff1a; 项目中使用到了纹理进行插值的加速&#xff0c;因此记录一些自己在学习tex2D的一些过程 2. 代码&#xff1a; #include "cuda_runtime.h" #include "device_launch_parameters.h" #include <assert.h> #include <stdio.h>…

Maven的安装和使用

Maven是一个基于项目对象模型&#xff08;POM&#xff09;&#xff0c;可以管理项目构建、依赖管理、项目报告等的工具&#xff0c;使构建Java项目更容易。可以说Maven是一个项目管理和构建工具&#xff0c;它可以从管理项目的角度出发&#xff0c;将开发过程中的需求纳入进来&…

FFmpeg架构全面分析

一、简介 它的官网为&#xff1a;https://ffmpeg.org/&#xff0c;由Fabrice Bellard&#xff08;法国著名程序员Born in 1972&#xff09;于2000年发起创建的开源项目。该人是个牛人&#xff0c;在很多领域都有很大的贡献。 FFmpeg是多媒体领域的万能工具。只要涉及音视频领…

软文推广如何自然融入品牌?媒介盒子有妙招

软文推广作为一种柔性推广方式&#xff0c;能将品牌信息融入到用户日常浏览的内容中&#xff0c;让用户不知不觉接触品牌&#xff0c;从而产生好感&#xff0c;这种方式既可以避免广告带来的反感&#xff0c;又可以提高广告的有效性。那么在推广中应该如何自然融入品牌信息呢&a…

leetCode 78.子集 + 回溯算法 + 图解

给你一个整数数组 nums &#xff0c;数组中的元素 互不相同 。返回该数组所有可能的子集&#xff08;幂集&#xff09;。解集 不能 包含重复的子集。你可以按 任意顺序 返回解集 示例 1&#xff1a; 输入&#xff1a;nums [1,2,3] 输出&#xff1a;[[],[1],[2],[1,2],[3],[1…

11月30日作业

设计一个Per类&#xff0c;类中包含私有成员:姓名、年龄、指针成员身高、体重&#xff0c;再设计一个Stu类&#xff0c;类中包含私有成员:成绩、Per类对象p1&#xff0c;设计这两个类的构造函数、析构函数和拷贝构造函数 #include <iostream>using namespace std;class …

二分算法(整数二分、浮点数二分)

文章目录 二分一、整数二分&#xff08;一&#xff09;整数二分思路&#xff08;二&#xff09;整数二分算法模板1.左查找&#xff08;寻找左侧边界&#xff09;2.右查找&#xff08;寻找右侧边界&#xff09;3.总模板 &#xff08;三&#xff09;题目&#xff1a;数的范围 二、…

Luminar Neo1.16.0(ai智能图像处理)

Luminar Neo是一款ai智能图像编辑软件&#xff0c;它专注于使用人工智能技术来实现对照片的快速、高效和创造性的编辑。 具体来说&#xff0c;Luminar Neo可以自动移除景观或旅行照片中令人分心的元素&#xff0c;例如电话线、电线杆等&#xff0c;从而增强照片的整体质量。同…

传统家装“死气沉沉”?VR智慧家装提供VR可视化方案

传统家装市场虽然处于成熟期&#xff0c;但是对于装修小白的户主来说&#xff0c;难以解决的痛点依旧还有很多。很多家装公司所谓的设计师&#xff0c;不一定全都具备设计知识&#xff0c;也不懂得从客户的需求出发&#xff0c;多重因素导致家装行业“死气沉沉”。 为了打破装修…

JUC并发编程 01——多线程基础知识

一.线程应用 异步调用 以调用方角度来讲&#xff0c;如果 需要等待结果返回&#xff0c;才能继续运行就是同步 不需要等待结果返回&#xff0c;就能继续运行就是异步 应用 比如在项目中&#xff0c;视频文件需要转换格式等操作比较费时&#xff0c;这时开一个新线程处理视…

借助ETL快速查询金蝶云星空表单信息

随着数字化转型的加速&#xff0c;企业信息化程度越来越高&#xff0c;大量的数据产生并存储在云端&#xff0c;需要进行有效的数据管理和查询。金蝶云星空是金蝶云旗下的一款云ERP产品&#xff0c;为企业提供了完整的业务流程和数据管理功能&#xff0c;因此需要进行有效的数据…

.NET开源的处理分布式事务的解决方案

前言 在分布式系统中&#xff0c;由于各个系统服务之间的独立性和网络通信的不确定性&#xff0c;要确保跨系统的事务操作的最终一致性是一项重大的挑战。今天给大家推荐一个.NET开源的处理分布式事务的解决方案基于 .NET Standard 的 C# 库&#xff1a;CAP。 CAP项目介绍 CA…

homeassistant 随笔

1.使用mushroom-strategy自动生成ui&#xff0c;隐藏中文ares&#xff0c;名字为区域的拼音&#xff0c;例如显示厨房则真实名字为chu_fang 隐藏图片中的工作室 代码为&#xff1a;