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

SpringBoot错误处理机制解析

SpringBoot错误处理----源码解析

文章目录

    • 1、默认机制
    • 2、使用@ExceptionHandler标识一个方法,处理用@Controller标注的该类发生的指定错误
      • 1).局部错误处理部分源码
      • 2).测试
    • 3、 创建一个全局错误处理类集中处理错误,使用==@ControllerAdvice==注解标注
      • 1).全局错误处理部分源码
      • 3).测试
    • 4、SpringMVC错误处理未能处理(上述处理不存在)
        • 1、SpringBoot中自动配置的错误处理机制,基于`ErrorMvcAutoConfiguration`自动配置实现
        • 2、` BasicErrorController`组件
        • 规则如下:
    • 5、自定义错误响应
    • 6、测试
        • 1、在项目的resources/templates/目录下创建一个error文件夹,放入4xx.html、5xx.html
        • 2、在项目的resources/templates/error文件夹中,再放入404.html、500.html
        • 3、浏览器先后测试上述情况

1、默认机制

SpringBoot错误处理的自动配置都在ErrorMvcAutoConfiguration中,两大核心机制:

  • 1.SpringBoot会自适应处理错误,响应页面或JSON数据

  • 2.SpringMVC的错误处理机制依然保留,MVC处理不了,才会交给SpringBoot进行处理。
    在这里插入图片描述(图片来自尚硅谷)

2、使用@ExceptionHandler标识一个方法,处理用@Controller标注的该类发生的指定错误

(默认只能处理这个类的该指定错误)

// @ExceptionHandler源码
@Target({ElementType.METHOD})     // 指定了该注解仅能用于方法
@Retention(RetentionPolicy.RUNTIME)   //指定了注解会在运行时保留,这允许通过反射在运行时获取对注解的访问
@Documented      //注解应该被包含在生成的 JavaDoc 文档中
@Reflective({ExceptionHandlerReflectiveProcessor.class}) 
public @interface ExceptionHandler {Class<? extends Throwable>[] value() default {};       //它定义了一个名为 value 的属性,其类型是一个 Class 数组,这个数组的元素必须是 Throwable 类或其子类。通过使用这个注解时,可以为 value 属性提供一个 Throwable 类型的数组
}

1).局部错误处理部分源码

@Controller         //适配服务端渲染    前后不分离模式开始
public class WelcomeController {//来到首页@GetMapping("/")public String index(){int i=10/0;    //制造错误return "index";}@ResponseBody     //返回的字符串应该直接作为 HTTP 响应体的内容,而不是作为视图名称解析。通常用于返回 JSON 或纯文本等非HTML内容@ExceptionHandler(Exception.class)   //传递到value数组中public String handleException(Exception e){return "Ohho~~~,原因:"+e.getMessage();}}

2).测试

  • 1.启动项目,浏览器访问http://localhost:8080/

  • 2.测试结果(成功处理错误)
    在这里插入图片描述

3、 创建一个全局错误处理类集中处理错误,使用==@ControllerAdvice==注解标注

(这个类是集中处理所有@Controller 发生的错误)

//@ControllerAdvice源码
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component       //标记类为一个 Spring 组件
public @interface ControllerAdvice {@AliasFor(annotation = Component.class,attribute = "value")String name() default "";@AliasFor("basePackages")String[] value() default {};@AliasFor("value")String[] basePackages() default {};Class<?>[] basePackageClasses() default {};Class<?>[] assignableTypes() default {};Class<? extends Annotation>[] annotations() default {};
}

1).全局错误处理部分源码

@ControllerAdvice        //这个类是集中处理所有@Controller发生的错误
public class GlobalExceptionHandler {@ResponseBody@ExceptionHandler(Exception.class)public String handleException(Exception e){return "Ohho~~~统一处理所有错误,原因:"+e.getMessage();}
}

###2).再创建一个类,使用@Controller注解标注

@Controller
public class HelloController {@GetMapping("/haha")public String haha(){int i = 10/0;        //制造错误return "index";}
}

3).测试

  • 1.启动项目,浏览器访问http://localhost:8080/
  • 2.测试结果(成功处理错误)就近原则,执行的是@Controller类中标注了@ExceptionHandler方法的处理
    在这里插入图片描述
  • 3.浏览器访问http://localhost:8080/haha全局错误处理类进行处理
    在这里插入图片描述

4、SpringMVC错误处理未能处理(上述处理不存在)

第一阶段的处理未解决,错误转发到/error,执行后续处理(图中第一阶段失效,第二阶段处理),以下测试过程中,注释掉上文中的全局和局部处理代码

1、SpringBoot中自动配置的错误处理机制,基于ErrorMvcAutoConfiguration自动配置实现

ErrorMvcAutoConfiguration自动装配类中,SpringBoot在底层写好一个 ==BasicErrorController==的组件,专门处理/error这个请求,部分源码如下:

@AutoConfiguration(before = WebMvcAutoConfiguration.class) //指定了该自动配置类在 WebMvcAutoConfiguration 之前进行配置
@ConditionalOnWebApplication(type = Type.SERVLET)    //只有在当前应用是一个 Servlet Web 应用时,这个自动配置才会生效
@ConditionalOnClass({ Servlet.class, DispatcherServlet.class })   //只有当类路径中存在 Servlet 和 DispatcherServlet 时,这个自动配置才会生效
@EnableConfigurationProperties({ ServerProperties.class, WebMvcProperties.class }) //启用指定类的配置属性绑定
public class ErrorMvcAutoConfiguration {private final ServerProperties serverProperties; //注入了 ServerProperties 实例。这样的构造方法注入是为了获取应用程序的服务器配置public ErrorMvcAutoConfiguration(ServerProperties serverProperties) {this.serverProperties = serverProperties;  //注入 ServerProperties 实例}//容器中不存在 ErrorAttributes 类型的 Bean 时,才会创建并注册当前方法所返回的 Bean@Bean@ConditionalOnMissingBean(value = ErrorAttributes.class, search = SearchStrategy.CURRENT)public DefaultErrorAttributes errorAttributes() {return new DefaultErrorAttributes();}//在容器中不存在 ErrorController 类型的 Bean 时,才会创建并注册当前方法所返回的 Bean@Bean@ConditionalOnMissingBean(value = ErrorController.class, search = SearchStrategy.CURRENT)public BasicErrorController basicErrorController(ErrorAttributes errorAttributes,ObjectProvider<ErrorViewResolver> errorViewResolvers) {return new BasicErrorController(errorAttributes, this.serverProperties.getError(),errorViewResolvers.orderedStream().toList());}...
}
2、 BasicErrorController组件

SpringBoot中默认的server.error.path=/error,即该类就是处理/error请求的,根据不同类型的请求,如果产生 HTML 内容的请求,匹配public ModelAndView errorHtml(HttpServletRequest request, HttpServletResponse response) 这个方法;否则其他请求类型,匹配public ResponseEntity<Map<String, Object>> error(HttpServletRequest request)方法。分别进行处理。(只会匹配其中一个,Spring MVC会尝试匹配与请求路径最匹配的RequestMapping)

  • 1.部分源码:
@Controller
@RequestMapping("${server.error.path:${error.path:/error}}")
public class BasicErrorController extends AbstractErrorController {private final ErrorProperties errorProperties;/*** Create a new {@link BasicErrorController} instance.* @param errorAttributes the error attributes* @param errorProperties configuration properties*/public BasicErrorController(ErrorAttributes errorAttributes, ErrorProperties errorProperties) {this(errorAttributes, errorProperties, Collections.emptyList());}/*** Create a new {@link BasicErrorController} instance.* @param errorAttributes the error attributes* @param errorProperties configuration properties* @param errorViewResolvers error view resolvers*/public BasicErrorController(ErrorAttributes errorAttributes, ErrorProperties errorProperties,List<ErrorViewResolver> errorViewResolvers) {super(errorAttributes, errorViewResolvers);Assert.notNull(errorProperties, "ErrorProperties must not be null");this.errorProperties = errorProperties;}@RequestMapping(produces = MediaType.TEXT_HTML_VALUE)   //请求类型为HTML 文本public ModelAndView errorHtml(HttpServletRequest request, HttpServletResponse response) {HttpStatus status = getStatus(request);Map<String, Object> model = Collections.unmodifiableMap(getErrorAttributes(request, getErrorAttributeOptions(request, MediaType.TEXT_HTML)));response.setStatus(status.value());ModelAndView modelAndView = resolveErrorView(request, response, status, model);return (modelAndView != null) ? modelAndView : new ModelAndView("error", model);}@RequestMappingpublic ResponseEntity<Map<String, Object>> error(HttpServletRequest request) {HttpStatus status = getStatus(request);if (status == HttpStatus.NO_CONTENT) {return new ResponseEntity<>(status);}Map<String, Object> body = getErrorAttributes(request, getErrorAttributeOptions(request, MediaType.ALL));return new ResponseEntity<>(body, status);}...
}
  • 2.匹配成功之后,错误页面解析的核心代码

    //1、解析错误的自定义视图地址
    ModelAndView modelAndView = resolveErrorView(request, response, status, model);
    //2、如果解析不到错误页面的地址,默认的错误页就是 error
    return (modelAndView != null) ? modelAndView : new ModelAndView("error", model);
    
  • 3.在ErrorMvcAutoConfiguration自动装配类中,SpringBoot在底层写好一个 ==DefaultErrorViewResolver==的组件,注入到了容器中

    	@Configuration(proxyBeanMethods = false)@EnableConfigurationProperties({ WebProperties.class, WebMvcProperties.class })static class DefaultErrorViewResolverConfiguration {private final ApplicationContext applicationContext;private final Resources resources;DefaultErrorViewResolverConfiguration(ApplicationContext applicationContext, WebProperties webProperties) {this.applicationContext = applicationContext;this.resources = webProperties.getResources();}@Bean@ConditionalOnBean(DispatcherServlet.class)@ConditionalOnMissingBean(ErrorViewResolver.class)DefaultErrorViewResolver conventionErrorViewResolver() {return new DefaultErrorViewResolver(this.applicationContext, this.resources);}}
    
  • 4.在DefaultErrorViewResolver中定义了错误页的默认规则,功能如下:

    • 如果在类路径下,查看是否存在 error/错误码 的页面,存在就返回该视图;
    • 否则,去4个CLASSPATH_RESOURCE_LOCATIONS路径下,查看是否写了 error/错误码.html 的页面,存在则返回该视图;
    • 都不存在,则modelAndView=null;则判断是否有 error/4xx 或者 error/5xx 的页面,存在则返回该视图
    • 否则,去4个CLASSPATH_RESOURCE_LOCATIONS路径下,查看是否写了 error/4xx.html 或者 error/5xx.html 的页面,存在则返回该视图;
    public class DefaultErrorViewResolver implements ErrorViewResolver, Ordered {...private static final Map<Series, String> SERIES_VIEWS;static {Map<Series, String> views = new EnumMap<>(Series.class);views.put(Series.CLIENT_ERROR, "4xx");views.put(Series.SERVER_ERROR, "5xx");SERIES_VIEWS = Collections.unmodifiableMap(views);}// 查看是否存在 error/错误码 的页面,存在就返回该视图// 不存在,则判断是否有  error/4xx  或者  error/5xx  的页面,存在则返回该视图@Overridepublic ModelAndView resolveErrorView(HttpServletRequest request, HttpStatus status, Map<String, Object> model) {ModelAndView modelAndView = resolve(String.valueOf(status.value()), model);if (modelAndView == null && SERIES_VIEWS.containsKey(status.series())) {modelAndView = resolve(SERIES_VIEWS.get(status.series()), model);}return modelAndView;}// 在类路径下,查看是否存在 error/错误码 的模板引擎,存在就返回该视图;// 否则去下面的4个CLASSPATH_RESOURCE_LOCATIONS路径下,查看是否写了  error/错误码.html 的页面,存在则返回该视图private ModelAndView resolve(String viewName, Map<String, Object> model) {String errorViewName = "error/" + viewName;TemplateAvailabilityProvider provider = this.templateAvailabilityProviders.getProvider(errorViewName,this.applicationContext);if (provider != null) {return new ModelAndView(errorViewName, model);}return resolveResource(errorViewName, model);}//去下面的4个CLASSPATH_RESOURCE_LOCATIONS路径下,查看是否写了  error/错误码.html  的页面,存在则返回该视图//this.resources.getStaticLocations()//private static final String[] CLASSPATH_RESOURCE_LOCATIONS = { "classpath:/META-INF/resources/",//			"classpath:/resources/", "classpath:/static/", "classpath:/public/" };private ModelAndView resolveResource(String viewName, Map<String, Object> model) {for (String location : this.resources.getStaticLocations()) {try {Resource resource = this.applicationContext.getResource(location);resource = resource.createRelative(viewName + ".html");if (resource.exists()) {return new ModelAndView(new HtmlResourceView(resource), model);}}catch (Exception ex) {}}return null;}...
    }
    
  • 5.在ErrorMvcAutoConfiguration自动装配类中,向容器中放入了一个默认名为error的视图,提供了默认的白页功能,如果上述都无法处理

    	@Configuration(proxyBeanMethods = false)@ConditionalOnProperty(prefix = "server.error.whitelabel", name = "enabled", matchIfMissing = true)@Conditional(ErrorTemplateMissingCondition.class)protected static class WhitelabelErrorViewConfiguration {private final StaticView defaultErrorView = new StaticView();//   注入了error视图@Bean(name = "error")@ConditionalOnMissingBean(name = "error")public View defaultErrorView() {return this.defaultErrorView;}// If the user adds @EnableWebMvc then the bean name view resolver from// WebMvcAutoConfiguration disappears, so add it back in to avoid disappointment.@Bean@ConditionalOnMissingBeanpublic BeanNameViewResolver beanNameViewResolver() {BeanNameViewResolver resolver = new BeanNameViewResolver();resolver.setOrder(Ordered.LOWEST_PRECEDENCE - 10);return resolver;}}
    

    默认的白页源码,就在类ErrorMvcAutoConfiguration中定义的

    private static class StaticView implements View {private static final MediaType TEXT_HTML_UTF8 = new MediaType("text", "html", StandardCharsets.UTF_8);private static final Log logger = LogFactory.getLog(StaticView.class);@Overridepublic void render(Map<String, ?> model, HttpServletRequest request, HttpServletResponse response)throws Exception {if (response.isCommitted()) {String message = getMessage(model);logger.error(message);return;}response.setContentType(TEXT_HTML_UTF8.toString());StringBuilder builder = new StringBuilder();Object timestamp = model.get("timestamp");Object message = model.get("message");Object trace = model.get("trace");if (response.getContentType() == null) {response.setContentType(getContentType());}builder.append("<html><body><h1>Whitelabel Error Page</h1>").append("<p>This application has no explicit mapping for /error, so you are seeing this as a fallback.</p>").append("<div id='created'>").append(timestamp).append("</div>").append("<div>There was an unexpected error (type=").append(htmlEscape(model.get("error"))).append(", status=").append(htmlEscape(model.get("status"))).append(").</div>");if (message != null) {builder.append("<div>").append(htmlEscape(message)).append("</div>");}if (trace != null) {builder.append("<div style='white-space:pre-wrap;'>").append(htmlEscape(trace)).append("</div>");}builder.append("</body></html>");response.getWriter().append(builder.toString());}private String htmlEscape(Object input) {return (input != null) ? HtmlUtils.htmlEscape(input.toString()) : null;}private String getMessage(Map<String, ?> model) {Object path = model.get("path");String message = "Cannot render error page for request [" + path + "]";if (model.get("message") != null) {message += " and exception [" + model.get("message") + "]";}message += " as the response has already been committed.";message += " As a result, the response may have the wrong status code.";return message;}@Overridepublic String getContentType() {return "text/html";}}
    
  • 6.在ErrorMvcAutoConfiguration自动装配类中,封装了JSON格式的错误信息(初始化了错误的类型、错误的状态码、路径、栈信息、时间戳等信息)

    @Bean
    @ConditionalOnMissingBean(value = ErrorAttributes.class, search = SearchStrategy.CURRENT)
    public DefaultErrorAttributes errorAttributes() {return new DefaultErrorAttributes();
    }
    
规则如下:
  • 1.解析一个错误页:

    • 如果发生了500、404、503、403 这些错误
        1. 如果有模板引擎,默认在 classpath:/templates/error/精确码.html
        1. 如果没有模板引擎,在静态资源文件夹下找 精确码.html
    • 如果匹配不到精确码.html这些精确的错误页,就去找5xx.html4xx.html模糊匹配
        1. 如果有模板引擎,默认在 classpath:/templates/error/5xx.html
        1. 如果没有模板引擎,在静态资源文件夹下找 5xx.html
  • 2.如果模板引擎路径templates下有 error.html页面,就直接渲染

5、自定义错误响应

​ 1) 自定义json响应:使用文章第2和第3部分介绍的,使用注解进行统一的异常处理

​ 2)自定义页面响应:根据第4部分介绍的规则,在对应的项目路径"classpath:/METAINF/resources/","classpath:/resources/","classpath:/static/", "classpath:/public/"或者模板引擎目录下,定义错误页面即可。

6、测试

1、在项目的resources/templates/目录下创建一个error文件夹,放入4xx.html、5xx.html
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body>4xx.html
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body>
5xx.html
</body>
</html>
2、在项目的resources/templates/error文件夹中,再放入404.html、500.html
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body>
404.html
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body>
500.html
</body>
</html>
3、浏览器先后测试上述情况
  • 1.访问一个不存在的路径;
  • 2.制造除0错误。

相关文章:

SpringBoot错误处理机制解析

SpringBoot错误处理----源码解析 文章目录 1、默认机制2、使用ExceptionHandler标识一个方法&#xff0c;处理用Controller标注的该类发生的指定错误1&#xff09;.局部错误处理部分源码2&#xff09;.测试 3、 创建一个全局错误处理类集中处理错误&#xff0c;使用Controller…...

牛客剑指offer刷题模拟篇

文章目录 顺时针打印矩阵题目思路代码实现 扑克牌顺子题目思路代码实现 把字符串转换成整数题目思路代码实现 表示数值的字符串题目思路代码实现 顺时针打印矩阵 题目 描述 输入一个矩阵&#xff0c;按照从外向里以顺时针的顺序依次打印出每一个数字&#xff0c;例如&#xf…...

Locust单机多核压测,以及主从节点的数据通信处理!

一、背景 这还是2个月前做的一次接口性能测试&#xff0c;关于locust脚本的单机多核运行&#xff0c;以及主从节点之间的数据通信。 先简单交代下背景&#xff0c;在APP上线之前&#xff0c;需要对登录接口进行性能测试。经过评估&#xff0c;我还是优先选择了locust来进行脚…...

ERROR: [pool www] please specify user and group other than root

根据提供的日志信息&#xff0c;PHP-FPM 服务未能启动的原因是配置文件中的一个错误。错误消息明确指出了问题所在&#xff1a; [29-Nov-2023 14:28:26] ERROR: [pool www] please specify user and group other than root [29-Nov-2023 14:28:26] ERROR: FPM initialization …...

京东商品详情接口在电商行业中的重要性及实时数据获取实现

一、引言 随着电子商务的快速发展&#xff0c;商品信息的准确性和实时性对于电商行业的运营至关重要。京东作为中国最大的电商平台之一&#xff0c;其商品详情接口在电商行业中扮演着重要的角色。本文将深入探讨京东商品详情接口的重要性&#xff0c;并介绍如何通过API实现实时…...

WT2003H MP3语音芯片方案:强大、灵活且易于集成的音频解决方案

在当今的数字化时代&#xff0c;音频技术的普遍性已不容忽视。从简单的音乐播放&#xff0c;到复杂的语音交互&#xff0c;音频技术的身影无处不在。在这个背景下&#xff0c;WT2003H MP3语音芯片方案应运而生&#xff0c;它提供了一种强大、灵活且易于集成的音频解决方案。 1…...

机器学习深度学学习分类模型中常用的评价指标总结记录与代码实现说明

在机器学习深度学习算法模型大开发过程中&#xff0c;免不了要对算法模型进行对应的评测分析&#xff0c;这里主要是总结记录分类任务中经常使用到的一些评价指标&#xff0c;并针对性地给出对应的代码实现&#xff0c;方便读者直接移植到自己的项目中。 【混淆矩阵】 混淆矩阵…...

fastapi 后端项目目录结构 mysql fastapi 数据库操作

原文&#xff1a;fastapi 后端项目目录结构 mysql fastapi 数据库操作_mob6454cc786d85的技术博客_51CTO博客 一、安装sqlalchemy、pymysql模块 pip install sqlalchemy -i https://pypi.tuna.tsinghua.edu.cn/simple pip install pymysql -i https://pypi.tuna.tsinghua.edu.…...

研习代码 day47 | 动态规划——子序列问题3

一、判断子序列 1.1 题目 给定字符串 s 和 t &#xff0c;判断 s 是否为 t 的子序列。 字符串的一个子序列是原始字符串删除一些&#xff08;也可以不删除&#xff09;字符而不改变剩余字符相对位置形成的新字符串。&#xff08;例如&#xff0c;"ace"是"abcde&…...

L1-017:到底有多二

题目描述 一个整数“犯二的程度”定义为该数字中包含2的个数与其位数的比值。如果这个数是负数&#xff0c;则程度增加0.5倍&#xff1b;如果还是个偶数&#xff0c;则再增加1倍。例如数字-13142223336是个11位数&#xff0c;其中有3个2&#xff0c;并且是负数&#xff0c;也是…...

Python多线程使用(二)

使用多个线程的时候容易遇到一个场景&#xff1a;多个线程处理一份数据 使用多线程的时候同时处理一份数据&#xff0c;在threading中提供了一个方法&#xff1a;线程锁 Demo&#xff1a;下订单 现在有多笔订单下单&#xff0c;库存减少 from threading import Thread from t…...

记录一次docker搭建tomcat容器的网页不能访问的问题

tomcat Tomcat是Apache软件基金会的Jakarta项目中的一个重要子项目&#xff0c;是一个Web服务器&#xff0c;也是Java应用服务器&#xff0c;是开源免费的软件。它是一个兼容Java Servlet和JavaServer Pages&#xff08;JSP&#xff09;的Web服务器&#xff0c;可以作为独立的W…...

GPT3年终总结

User You 程序员年度绩效总结 ChatGPT ChatGPT 程序员年度绩效总结通常包括以下几个方面&#xff1a; 目标达成情况&#xff1a; 回顾年初设定的目标&#xff0c;评估在项目完成、技能提升等方面的达成情况。 工作贡献&#xff1a; 强调在项目中的个人贡献&#xff0c;包括…...

Kafka生产者发送消息的流程

Kafka 生产者发送消息的流程涉及多个步骤&#xff0c;从消息的创建到成功存储在 Kafka 集群中。以下是 Kafka 生产者发送消息的主要步骤&#xff1a; 1. 创建消息 生产者首先创建一个消息&#xff0c;消息通常包含一个键&#xff08;可选&#xff09;和一个值&#xff0c;以及…...

基于SSM的数学竞赛网站设计与实现

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SSM 前端&#xff1a;Vue 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#xff1a;是 目录…...

01-使用Git操作本地库,如初始化本地库,提交工作区文件到暂存区和本地库,查看版本信息,版本切换命令等

Git的使用 概述 Git是一个分布式版本控制工具, 通常用来管理项目中的源代码文件(Java类、xml文件、html页面等)进行管理,在软件开发过程中被广泛使用 Git可以记录文件修改的历史记录并形成备份从而实现代码回溯, 版本切换, 多人协作, 远程备份的功能Git具有廉价的本地库,方便…...

排序算法介绍(二)冒泡排序

0. 简介 冒泡排序&#xff08;Bubble Sort&#xff09;是一种简单的排序算法。它重复地遍历要排序的数列&#xff0c;一次比较两个元素&#xff0c;如果他们的顺序错误就把他们交换过来。遍历数列的工作是重复地进行直到没有再需要交换&#xff0c;也就是说该数列已经排…...

搜索引擎高级用法总结: 谷歌、百度、必应

搜索引擎高级用法总结: 谷歌、百度、必应 google search 基本搜索 逻辑与:and逻辑或: or逻辑非: -完整匹配:“关键词”通配符:* ?高级搜索 intext:后台登录 将只返回正文中包含 后台登录 的网页 intitle intitle:后台登录 将只返回标题中包含 后台登录 的网页,intitle…...

com.intellij.openapi.application.ApplicationListener使用

一般监听期通过如下代码生效 <applicationListeners> <!-- <listener class"com.itheima.taunt.MyApplicationListener"--> <!-- topic"com.intellij.openapi.application.ApplicationListener"…...

常见js hook脚本

一.js hook 过无限debugger var _constructor constructor; Function.prototype.constructor function(s) {if (s "debugger") {console.log(s);return null;}return _constructor(s); }//去除无限debugger Function.prototype.__constructor_back Function.pro…...

python-flask-djangol框架的校园餐厅菜品自选系统

目录 技术选型核心功能模块数据库设计开发流程部署方案关键代码示例测试重点 项目技术支持源码获取详细视频演示 &#xff1a;文章底部获取博主联系方式&#xff01;同行可合作 技术选型 使用Python的Flask或Django框架作为后端基础。Flask适合轻量级快速开发&#xff0c;Djan…...

别再死记公式了!用Python+Matplotlib亲手仿真LC并联谐振,直观理解选频原理

用PythonMatplotlib动态仿真LC并联谐振&#xff1a;从代码到物理直觉的沉浸式探索 当教科书上的LC并联谐振公式变成屏幕上跳动的曲线&#xff0c;当抽象的Q值概念转化为滑块调节时的实时波形变化&#xff0c;电子工程的学习便从枯燥的符号演算升维为一场充满探索乐趣的科学实验…...

别再只盯着KNN了:聊聊Wi-Fi指纹定位中那些被低估的匹配算法与实战选择

超越KNN&#xff1a;Wi-Fi指纹定位中的高阶匹配算法与工程化选型指南 商场里找不到心仪店铺的焦虑、仓库中耗时的手动货品盘点、医院里紧急设备定位的延迟——这些场景背后都指向同一个技术痛点&#xff1a;室内定位精度不足。当大多数开发者习惯性采用KNN算法时&#xff0c;我…...

ImageMagick安装后报错‘vcomp140.dll缺失’?手把手教你彻底解决Visual C++依赖问题

ImageMagick安装后报错‘vcomp140.dll缺失’&#xff1f;手把手教你彻底解决Visual C依赖问题 当你兴冲冲下载完ImageMagick准备大展身手时&#xff0c;命令行却突然弹出一串红色错误提示——"无法启动程序&#xff0c;因为计算机中丢失vcomp140.dll"。这种场景对于…...

源网荷储全场景适配:新型电力系统时序数据库落地指南

新型电力系统应该用什么数据库&#xff1f;源网荷储四侧的时序数据库选型与落地实战 “双碳”目标的推进正在深刻重构电力系统的运行逻辑。新能源装机占比持续攀升&#xff0c;储能、虚拟电厂、需求响应等新业态快速涌现&#xff0c;源、网、荷、储各侧的角色与互动方式正在被…...

告别Win11无边框窗口的‘残疾’体验:Qt自定义标题栏完美集成Snap Layout保姆级教程

现代Qt应用开发&#xff1a;Win11无边框窗口与Snap Layout深度整合实战 当微软推出Windows 11时&#xff0c;其标志性的Snap Layout功能彻底改变了多窗口管理体验。然而对于使用Qt框架开发无边框窗口应用的开发者来说&#xff0c;这却带来了一个棘手的问题——自定义标题栏与系…...

MoveIt 2 Launch文件进阶:如何用MoveItConfigsBuilder灵活切换规划器(OMPL vs. Pilz)

MoveIt 2规划器切换实战&#xff1a;用MoveItConfigsBuilder实现OMPL与Pilz工业规划器的动态选择 在工业机器人应用开发中&#xff0c;运动规划器的选择往往决定了任务执行的效率和质量。想象一下这样的场景&#xff1a;你的机械臂需要在杂乱环境中快速避障移动时&#xff0c;…...

效率飙升:用快马平台一键生成项目模板,告别重复的vscode环境配置

作为一个经常需要在新设备上配置开发环境的前端开发者&#xff0c;我深刻体会到重复搭建项目的痛苦。每次换电脑或者开新项目&#xff0c;都要从头安装VSCode插件、配置构建工具、集成UI库……这些琐碎工作至少会浪费半小时。最近发现InsCode(快马)平台能完美解决这个问题&…...

【图像加密解密】基于Halton 序列图像加密解密位置扰乱和像素扰乱(含相关性分析)附Matlab代码

作者简介&#xff1a;热爱科研的Matlab仿真开发者&#xff0c;擅长数据处理、建模仿真、程序设计、完整代码获取、论文复现及科研仿真关注我领取海量matlab电子书和数学建模资料 &#x1f34a;个人信条&#xff1a;格物致知,完整Matlab代码获取及仿真咨询内容私信。&#x1f52…...

OpenClaw自动化周报生成:Qwen3-32B私有镜像精准提取Git提交记录

OpenClaw自动化周报生成&#xff1a;Qwen3-32B私有镜像精准提取Git提交记录 1. 为什么需要自动化周报生成 每周五下午&#xff0c;我都会面临同样的困扰&#xff1a;需要从零散的Git提交记录中手动整理本周工作内容&#xff0c;再拼凑成一份结构化的周报。这个过程不仅耗时&a…...