Spring Boot 中配置了全局异常处理器,免try...catch
spring boot 中如果使用了全局异常处理 package com.weiyu.exception; import com.weiyu.model.Result; // 自定义的统一响应对象 import com.weiyu.util.ErrorFileResponseUtils; // 处理错误文件响应的工具类 import jakarta.servlet.http.HttpServletRequest; // 获取HTTP请求信息 import jakarta.validation.ConstraintViolation; import jakarta.validation.ConstraintViolationException; import lombok.extern.slf4j.Slf4j; // Lombok日志注解 import org.springframework.http.HttpStatus; // HTTP状态码枚举 import org.springframework.util.StringUtils; // Spring字符串工具类 import org.springframework.validation.FieldError; import org.springframework.validation.ObjectError; import org.springframework.web.bind.MethodArgumentNotValidException; import org.springframework.web.bind.annotation.ExceptionHandler; // 异常处理器注解 import org.springframework.web.bind.annotation.RestControllerAdvice; // 控制器增强注解 import org.springframework.web.method.annotation.HandlerMethodValidationException; import java.util.List; import java.util.Map; import java.util.Objects; import java.util.Set; import java.util.stream.Collectors; import static java.util.Map.entry; /** * 全局异常处理器 * 作用集中处理整个应用程序中控制器层抛出的异常 */ RestControllerAdvice // 组合注解包含 ControllerAdvice ResponseBody使返回值自动转为JSON SuppressWarnings(unused) // 使用这个注解来抑制警告 或 使用 Component Slf4j public class GlobalExceptionHandler { private static final MapString, String FIELD_NAME_MAP Map.ofEntries( entry(capitalNo, 资金序号), entry(capitalName, 资金名称), entry(capitalType, 资金类别), entry(capitalTotal, 指标预算总额), entry(capitalLeaveTotal, 指标剩余额), entry(capitalValidTotal, 指标可用总额), entry(capitalIndexType, 指标类别), entry(capitalAccount, 资金账户), entry(capitalSource, 资金来源), entry(capitalIndexSource, 指标来源), entry(capitalYear, 资金年份), entry(capitalState, 资金状态), entry(remark, 备注信息) ); /** * 处理防抖异常DebounceException同时支持普通请求和文件下载请求 * 适用场景当检测到重复/频繁请求时抛出的自定义异常 * * param e 捕获的防抖异常对象 * param request HTTP请求对象 * return 根据请求类型返回不同响应文件下载请求返回错误文件普通请求返回JSON错误信息 */ ExceptionHandler(DebounceException.class) // 指定处理的异常类型 public Object handleDebounceException(DebounceException e, HttpServletRequest request) { // 1. 检查是否为文件下载请求 if (ErrorFileResponseUtils.isFileDownloadRequest(request)) { // 生成包含错误信息的文件响应如txt return ErrorFileResponseUtils.createErrorFileResponse(e); } // 2. 普通请求返回统一JSON错误格式 return Result.error(e.getMessage(), e.getCode()); } /** * 处理请求已被取消异常RequestCancelledException * * param e 捕获的请求已被取消异常对象 * return 返回JSON错误信息 */ ExceptionHandler(RequestCancelledException.class) public Object handleRequestCancelledException(RequestCancelledException e) { log.error(请求已被取消异常错误: {}, e.getMessage(), e); // 记录错误消息和详细堆栈跟踪信息 return Result.error(e.getMessage(), e.getCode()); } /** * 处理线程中断异常InterruptedException * * param e 捕获的线程中断异常对象 * return 返回JSON错误信息 */ ExceptionHandler(InterruptedException.class) public Object handleInterruptedException(InterruptedException e) { log.error(线程已被中断异常错误: {}, e.getMessage(), e); // 记录错误消息和详细堆栈跟踪信息 Thread.currentThread().interrupt(); return Result.error(e.getMessage(), 499); } /** * 处理方法参数验证异常MethodArgumentNotValidException * * param e 捕获的方法参数验证异常对象 * return 返回JSON错误信息 */ ExceptionHandler(MethodArgumentNotValidException.class) public Object handleMethodArgumentNotValidException(MethodArgumentNotValidException e) { //return Result.error(Objects.requireNonNull(e.getBindingResult().getFieldError()).getDefaultMessage()); // 优先处理全局错误AssertTrue的错误 ListObjectError globalErrors e.getBindingResult().getGlobalErrors(); if (!globalErrors.isEmpty()) { String errorMessage globalErrors.get(0).getDefaultMessage(); return Result.error(errorMessage); } // 处理字段错误 FieldError fieldError e.getBindingResult().getFieldError(); if (fieldError ! null) { // 获取字段名称如capitalNo、capitalName、capitalType String fieldName fieldError.getField(); // 获取默认信息包括自定义信息 String defaultMessage fieldError.getDefaultMessage(); // 检查是否为占位符为后续扩展到配置文件 if (defaultMessage ! null defaultMessage.startsWith({) defaultMessage.endsWith(})) { return Result.error(【 defaultMessage 】); } // 检查是否为常见默认信息 SetString defaultMessages Set.of(不能为空, 不能为null); String fieldDescription FIELD_NAME_MAP.get(fieldName); if (StringUtils.hasText(fieldDescription) (defaultMessages.contains(defaultMessage) || (defaultMessage ! null defaultMessage.startsWith(个数必须在)))) { // 生成友好信息 String friendlyMessage generateFriendlyMessage(fieldDescription, fieldError); return Result.error(friendlyMessage); } // 默认信息包括自定义信息 return Result.error(defaultMessage); } return Result.error(参数验证失败 e.getBindingResult().getFieldError().getDefaultMessage()); } /** * 处理 Spring 6.1 统一方法参数验证异常HandlerMethodValidationException * 包括RequestParam、PathVariable、RequestBody 等直接标注约束的校验失败 * * param e 捕获的Spring 6.1 统一方法参数验证异常对象 * return 返回JSON错误信息 */ ExceptionHandler(HandlerMethodValidationException.class) public Object handleHandlerMethodValidationException(HandlerMethodValidationException e) { // 提取所有参数验证失败的具体错误信息 ListString errorDetails e.getAllValidationResults().stream() .flatMap(validationResult - { // 获取参数名如果没有则使用参数位置索引 String paramName validationResult.getMethodParameter().getParameterName(); if (paramName null) { paramName arg validationResult.getMethodParameter().getParameterIndex(); } // 将该参数上的所有错误消息转换为字符串支持字段级和参数级 String finalParamName paramName; ListString paramErrors validationResult.getResolvableErrors().stream() .map(error - { if (error instanceof FieldError fieldError) { // 字段错误参数名.字段路径 : 错误消息 return finalParamName . fieldError.getField() : fieldError.getDefaultMessage(); } else { // 参数对象整体错误如 ScriptAssert、Valid 嵌套对象的类级别注解 return finalParamName : error.getDefaultMessage(); } }) .toList(); return paramErrors.stream(); }) .collect(Collectors.toList()); // 如果解析失败极少情况至少返回原始异常信息 if (errorDetails.isEmpty()) { errorDetails.add(e.getMessage()); } // 返回统一错误响应 return Result.error(参数校验失败\n\n errorDetails); } /** * 处理约束违例异常ConstraintViolationException * 触发场景 * 1. Controller 类标注 Validated方法参数直接标注约束或参数对象内嵌套验证 * 2. Service 类标注 Validated方法参数/返回值校验失败 * * param e 捕获的约束违例异常对象 * return 返回JSON错误信息 */ ExceptionHandler(ConstraintViolationException.class) public Object handleConstraintViolationException(ConstraintViolationException e) { // 提取所有约束违例的详细错误信息 ListString errorDetails e.getConstraintViolations().stream() .map(this::buildConstraintViolationMessage) .collect(Collectors.toList()); // 如果解析失败极少情况降级返回原始异常信息 if (errorDetails.isEmpty()) { errorDetails.add(e.getMessage()); } // 返回统一错误响应 return Result.error(参数校验失败\n\n errorDetails); } /** * 处理业务异常BusinessException * 适用场景业务异常 * * param e 捕获的异常对象 * param request 请求对象 * return 返回JSON错误信息 */ ExceptionHandler(BusinessException.class) public Object handleBusinessException(BusinessException e, HttpServletRequest request) { log.error(异常信息: {}, e.getMessage(), e); // 1. 处理文件下载请求的异常 if (ErrorFileResponseUtils.isFileDownloadRequest(request)) { // 前端接收响应结果内容示例[...] xxx // return ErrorFileResponseUtils.createErrorFileResponse(e.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR); // 前端接收响应结果内容示例{code:1,message:xxx,data:null} return ErrorFileResponseUtils.createErrorJsonResponse(e.getMessage()); } // 2. 普通请求的异常处理返回统一错误响应 return Result.error(业务异常 e.getMessage()); } /** * 处理模板文件不存在异常TemplateNotFoundException * 适用场景模板文件不存在 * * param e 捕获的异常对象 * param request 请求对象 * return 返回JSON错误信息 */ ExceptionHandler(TemplateNotFoundException.class) public Object handleTemplateNotFoundException(TemplateNotFoundException e, HttpServletRequest request) { log.error(异常信息{}模板文件路径: {}, e.getMessage(), e.getTemplatePath(), e); // 1. 处理文件下载请求的异常 if (ErrorFileResponseUtils.isFileDownloadRequest(request)) { // 前端接收响应结果内容示例[/capital/info/export-data-by-template] 模板文件不存在 // return ErrorFileResponseUtils.createErrorFileResponse(模板文件不存在, HttpStatus.NOT_FOUND); // 前端接收响应结果内容示例{code:1,message:模板文件不存在,data:null} return ErrorFileResponseUtils.createErrorJsonResponse(模板文件不存在, HttpStatus.NOT_FOUND); } // 2. 普通请求的异常处理返回统一错误响应 return Result.error(模板文件不存在); } /** * 处理资源不存在异常ResourceNotFoundException * 适用场景文资源文件不存在 * * param e 捕获的异常对象 * param request 请求对象 * return 返回JSON错误信息 */ ExceptionHandler(ResourceNotFoundException.class) public Object handleResourceNotFoundException(ResourceNotFoundException e, HttpServletRequest request) { log.error(异常信息{}, e.getMessage(), e); // 1. 处理文件下载请求的异常 if (ErrorFileResponseUtils.isFileDownloadRequest(request)) { return ErrorFileResponseUtils.createErrorFileResponse(资源文件不存在, HttpStatus.NOT_FOUND); } // 2. 普通请求的异常处理返回统一错误响应 return Result.error(资源文件不存在); } /** * 处理所有其他未明确指定的异常Exception * 作用作为异常处理的兜底方案确保所有异常都被处理 * * param e 捕获的约束违例异常对象 * param request 请求对象 * return 返回JSON错误信息 */ ExceptionHandler(Exception.class) // 捕获所有未被处理的异常 public Object handleException(Exception e, HttpServletRequest request) { // ❌ 禁止使用 printStackTrace 在控制台输出异常的详细堆栈跟踪信息 // e.printStackTrace(); // ✅ 规范日志记录使用日志框架记录完整异常堆栈参数 e 包含异常的详细堆栈跟踪信息 log.error(异常错误: {}, e.getMessage(), e); // 记录错误消息和详细堆栈跟踪信息 // 1. 处理文件下载请求的异常 if (ErrorFileResponseUtils.isFileDownloadRequest(request)) { // 确保错误消息不为空使用默认消息兜底 String message StringUtils.hasLength(e.getMessage()) ? e.getMessage() : 下载文件失败; // 生成包含错误信息的文件响应使用500状态码 return ErrorFileResponseUtils.createErrorFileResponse(message, HttpStatus.INTERNAL_SERVER_ERROR); } // 2. 普通请求的异常处理 return Result.error( StringUtils.hasLength(e.getMessage()) ? e.getMessage() : 操作失败, // 消息处理 500 // 统一返回500服务器错误状态码 ); } /** * 将单个 ConstraintViolation 转换为可读的错误消息 * 格式字段路径 : 错误消息 */ private String buildConstraintViolationMessage(ConstraintViolation? violation) { // 获取完整的属性路径如generateWorkflow.createDTOs[0].deptId String propertyPath violation.getPropertyPath().toString(); // 获取错误消息 String message violation.getMessage(); // 如果路径为空如类级别约束只返回消息 if (propertyPath.isBlank()) { return message; } return propertyPath : message; } /** * 生成友好信息 * * param fieldName 字段名称 * param error 字段错误对象 * return 信息字符串 */ private String generateFriendlyMessage(String fieldName, FieldError error) { return switch (Objects.requireNonNull(error.getCode())) { case NotBlank, NotNull - fieldName 不能为空; case Size - fieldName error.getDefaultMessage(); case Pattern - fieldName 格式不正确; default - fieldName 验证失败; }; } } 以下这里是不是就可以不用try了 /** * 查询资金分配分页 * * param queryDTO 查询对象 * return {link Result}lt;{link PageResult}lt;{link CapitalAllocateVO}gt;gt; */ PostMapping(/page) public ResultPageResultCapitalAllocateVO queryPage(RequestBody Valid CapitalAllocateQueryDTO queryDTO) { String endpoint /capital/allocate/list; String method queryPage; log.info(【资金分配】查询资金分配列表{}{}queryDTO {}, endpoint, method, SecurityUtils.safeForLog(queryDTO)); // 1、基本校验已由 Valid 完成Spring会自动执行以下验证 // a. 检查Pattern注解格式验证 // b. 调用AssertTrue注解的方法业务逻辑验证 // 处理校验结果由全局异常 【处理方法参数验证异常MethodArgumentNotValidException】 处理校验结果 // 2、处理业务逻辑校验检查空条件 if (isAllQueryParamsEmpty(queryDTO)) { log.warn(【资金信息】 至少需要一个查询条件{}{}, endpoint, method); return Result.error(请至少输入一个查询条件); } // 3、处理业务逻辑校验 - 日期范围 String dateRangeError DateUtils.validateDateRange(queryDTO.createDateRange()); if (dateRangeError ! null) { return Result.error(dateRangeError); } PageResultCapitalAllocateVO capitalAllocatePage allocateService.queryPage(queryDTO); return Result.success(capitalAllocatePage); }是的因为已经配置了全局异常处理器你在控制器方法中无需显式使用 try-catch 来捕获异常。全局异常处理器会统一捕获并处理控制器层抛出的所有未处理异常并将其转换为统一的Result格式返回给客户端。原因分析参数校验异常自动处理Valid触发的校验失败如Pattern、AssertTrue等会抛出MethodArgumentNotValidException该异常已被全局异常处理器的handleMethodArgumentNotValidException方法捕获并返回格式化的错误信息。你不需要在方法内手动捕获或处理。业务异常由全局处理器接管如果allocateService.queryPage(queryDTO)抛出自定义的业务异常如BusinessException或其他运行时异常全局异常处理器中的对应ExceptionHandler方法会捕获并返回合适的Result对象。手动返回错误是业务逻辑校验代码中的if (isAllQueryParamsEmpty(...))和日期范围校验属于业务逻辑层面的主动判断它们直接返回Result.error(...)是为了快速响应无效输入避免执行后续无意义的操作。这些不是异常而是正常的流程控制因此必须手动处理。总结异常处理→ 全局处理器负责方法内无需 try-catch。业务逻辑校验→ 仍需手动判断并返回错误响应。这样既保持了代码简洁又确保了所有异常都能被统一格式化输出同时也保留了业务逻辑的灵活控制。如果强制加上try结果又会怎么样呢在Spring Boot应用中如果你强制在控制器方法内添加try-catch块来捕获异常结果会因你的处理方式不同而产生差异。下面分情况讨论1. 如果在catch中捕获异常后不重新抛出也不返回统一响应对象javaPostMapping(/page) public ResultPageResultCapitalAllocateVO queryPage(RequestBody Valid CapitalAllocateQueryDTO queryDTO) { try { // ... 业务逻辑 PageResultCapitalAllocateVO capitalAllocatePage allocateService.queryPage(queryDTO); return Result.success(capitalAllocatePage); } catch (Exception e) { // 仅记录日志未返回任何内容或返回null log.error(发生异常, e); // 遗漏了返回值 } // 方法结束没有返回值编译报错或运行时返回null取决于代码结构 }编译错误如果catch块后没有返回值方法缺少返回语句IDE 会报错。运行时问题如果通过某种方式绕过了编译如catch中返回null则客户端会收到null破坏统一响应格式前端无法正确解析。2. 在catch中手动返回自定义的错误响应javaPostMapping(/page) public ResultPageResultCapitalAllocateVO queryPage(RequestBody Valid CapitalAllocateQueryDTO queryDTO) { try { PageResultCapitalAllocateVO capitalAllocatePage allocateService.queryPage(queryDTO); return Result.success(capitalAllocatePage); } catch (BusinessException e) { return Result.error(业务异常 e.getMessage()); } catch (Exception e) { return Result.error(系统繁忙); } }优点能够保证返回统一响应格式。缺点重复代码每个需要异常处理的方法都要编写相似的catch逻辑导致代码冗余。异常处理不一致不同开发者可能返回不同的错误格式或者遗漏某些异常类型造成响应格式不统一。丢失全局处理器的增强功能全局异常处理器中可能包含一些额外逻辑如文件下载请求的特殊处理、日志记录、错误码映射等手动catch后这些逻辑不会执行。降低可维护性如果需要修改错误响应格式例如增加一个字段需要修改所有catch块而不是只修改全局异常处理器。3. 在catch中捕获异常后重新抛出javaPostMapping(/page) public ResultPageResultCapitalAllocateVO queryPage(RequestBody Valid CapitalAllocateQueryDTO queryDTO) { try { return Result.success(allocateService.queryPage(queryDTO)); } catch (Exception e) { log.error(捕获到异常重新抛出, e); throw e; // 重新抛出让全局异常处理器处理 } }结果异常最终仍会被全局异常处理器捕获效果等同于没有try-catch。虽然不会破坏统一响应但try-catch变得多余而且可能引入性能损耗虽然微乎其微。4. 在catch中执行了某些操作后重新抛出或者包装后抛出javaPostMapping(/page) public ResultPageResultCapitalAllocateVO queryPage(RequestBody Valid CapitalAllocateQueryDTO queryDTO) { try { return Result.success(allocateService.queryPage(queryDTO)); } catch (Exception e) { // 添加额外日志或统计 log.error(请求 /capital/allocate/page 失败, e); // 重新包装为自定义异常抛出 throw new BusinessException(查询失败, e); } }结果抛出的新异常会被全局异常处理器处理。但需要注意如果包装异常时丢失了原始异常信息可能会导致调试困难。同时这种模式增加了不必要的嵌套。5. 特殊情况手动处理部分异常其他交给全局处理器javaPostMapping(/page) public ResultPageResultCapitalAllocateVO queryPage(RequestBody Valid CapitalAllocateQueryDTO queryDTO) { try { return Result.success(allocateService.queryPage(queryDTO)); } catch (BusinessException e) { // 对于业务异常返回特殊错误码 return Result.error(e.getCode(), e.getMessage()); } catch (Exception e) { // 其他异常交给全局处理器 throw e; } }这种方式允许针对特定异常进行定制化返回同时保持其他异常由全局处理器统一处理。但需要注意如果全局处理器对BusinessException也有特殊处理如文件下载请求的适配手动处理可能会覆盖全局行为导致功能缺失。为什么不推荐在控制器中手动 try-catch违反单一职责原则控制器应专注于请求路由和参数校验异常处理应集中管理。代码重复每个方法都需要重复编写 catch 块增加维护成本。降低可测试性异常处理逻辑分散单元测试时难以覆盖所有场景。可能绕过全局处理器的增强功能例如文件下载请求的特殊响应、统一日志记录、错误码映射等。容易出错开发者可能忘记在某些 catch 块中返回正确的响应导致接口行为不一致。最佳实践不需要在控制器方法中主动 try-catch除非你有非常特殊的业务需求例如需要捕获特定异常后执行某些本地清理操作然后重新抛出。对于业务逻辑校验如检查参数是否为空、日期范围是否合法应该像你代码中那样通过if判断并直接返回Result.error(...)因为这些是预期内的错误流程不是异常。对于可能抛出的异常由全局异常处理器统一处理确保响应格式一致、日志完整、特殊场景如文件下载适配正确。你提供的GlobalExceptionHandler已经覆盖了参数校验异常MethodArgumentNotValidException、ConstraintViolationException、业务异常BusinessException和所有其他异常因此控制器方法中完全不需要 try-catch。保持代码简洁、关注点分离是最佳选择。

相关新闻

如何将视频从 iPhone 传输到Mac

如何将视频从 iPhone 传输到Mac

出于多种原因,您可能需要将视频从 iPhone 传输到Mac 。您可能希望释放 iPhone 的存储空间、备份重要视频,甚至提升 iPhone 的性能。对于视频编辑者来说,将 iPhone 视频传输到Mac通常是必要的,以便充分利用Mac强大的编辑工具。如果…

2026/7/4 22:51:50 阅读更多 →
写作压力小了,AI论文写作软件千笔·专业学术智能体 VS 万方智搜AI

写作压力小了,AI论文写作软件千笔·专业学术智能体 VS 万方智搜AI

随着人工智能技术的迅猛迭代与普及,AI辅助写作工具已逐步渗透到高校学术写作场景中,成为专科生、本科生、研究生完成毕业论文不可或缺的辅助手段。越来越多面临毕业论文压力的学生,开始依赖各类AI工具简化写作流程、提升创作效率。但与此同时…

2026/7/4 14:00:55 阅读更多 →
学术圈福利!AI专著写作工具大盘点,省时省力出佳作

学术圈福利!AI专著写作工具大盘点,省时省力出佳作

学术专著创作的创新挑战与AI工具应对 在学术专著的创作中,创新是灵魂所在,也是最为严格的标准。合格的专著不仅仅是将已存在的研究成果简单叠加,它需要展现出贯穿整本书的独到见解、理论框架或研究方法。在如今如此众多的学术出版物中&#…

2026/7/5 6:32:36 阅读更多 →

最新新闻

YOLOv8保姆级教程:一小时搞定环境搭建、自定义数据集训练与部署

YOLOv8保姆级教程:一小时搞定环境搭建、自定义数据集训练与部署

很多同学在入门深度学习目标检测时,面对YOLOv8的部署和训练常常感到无从下手,网上教程要么版本过时,要么步骤跳跃,导致环境配置失败、训练报错不断。本文将为你提供一份从零开始的保姆级教程,手把手带你在一小时内完成…

2026/7/5 12:43:53 阅读更多 →
暗黑2存档编辑器:可视化修改神器,让游戏存档管理变得如此简单

暗黑2存档编辑器:可视化修改神器,让游戏存档管理变得如此简单

暗黑2存档编辑器:可视化修改神器,让游戏存档管理变得如此简单 【免费下载链接】d2s-editor 项目地址: https://gitcode.com/gh_mirrors/d2/d2s-editor 你是否曾经因为《暗黑破坏神2》中角色属性点分配不当而懊恼?是否想要测试不同的装…

2026/7/5 12:43:53 阅读更多 →
YOLO目标检测实战指南:从原理到部署的完整路径

YOLO目标检测实战指南:从原理到部署的完整路径

在实际计算机视觉项目中,目标检测是连接图像理解与下游任务的核心桥梁。从自动驾驶的车辆行人识别,到工业质检的缺陷定位,再到安防监控的异常行为分析,一个高效、准确的检测模型是系统成功的关键。YOLO(You Only Look …

2026/7/5 12:41:53 阅读更多 →
莫比乌斯反演学习笔记

莫比乌斯反演学习笔记

积性函数 一说数论函数, 我个人认为积性函数这个叫法更好 对于一个函数 �(�)f(x), 如果满足对于任意的 $(a, b) | ���(�,�)1,�∈�,�∈�gcd(a,b)…

2026/7/5 12:41:53 阅读更多 →
OpenCV形态学实战:从腐蚀膨胀到开闭运算,解锁图像处理核心技能

OpenCV形态学实战:从腐蚀膨胀到开闭运算,解锁图像处理核心技能

1. 形态学操作:图像处理的"外科手术刀"第一次接触OpenCV的形态学操作时,我正处理一批医学显微图像。那些粘连在一起的血细胞就像煮过头的饺子,完全分不清个数。导师当时说:"试试形态学操作吧,这是图像处…

2026/7/5 12:39:52 阅读更多 →
目标检测实战:从理论到实践攻克小目标与遮挡难题

目标检测实战:从理论到实践攻克小目标与遮挡难题

1. 小目标检测的挑战与核心问题小目标检测一直是计算机视觉领域的难点问题。在实际项目中,我们经常会遇到无人机航拍图像中的车辆、工厂流水线上的微小零件,或是监控摄像头中远距离的行人。这些目标在图像中往往只占据几十甚至几个像素,给检测…

2026/7/5 12:39:52 阅读更多 →

日新闻

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容 【免费下载链接】BiliTools A cross-platform bilibili toolbox. 跨平台哔哩哔哩工具箱,支持下载视频、番剧等等各类资源 项目地址: https://gitcode.com/GitHub_Trending/bilit/BiliTools …

2026/7/5 0:03:34 阅读更多 →
威胁模型全解析:从新手入门到实战应用,助你构建安全产品!

威胁模型全解析:从新手入门到实战应用,助你构建安全产品!

威胁模型的陌生现状在忙碌疲惫的一天里,参与了关于混合后量子密码学的讨论,应付端点攻击找茬的人,还参与留言板讨论后,发现“威胁模型”对多数人仍是陌生概念,且多被当作时髦用语。有趣的相关画作有一幅由 Embyr 创作的…

2026/7/5 0:03:34 阅读更多 →
渗透测试入门指南:从零基础到实战环境搭建

渗透测试入门指南:从零基础到实战环境搭建

1. 从“看热闹”到“入门”:我理解的渗透测试到底是什么?每次看到新闻里说某个大公司的数据被“黑”了,或者某个网站被攻击导致服务瘫痪,你是不是和我一样,心里会冒出两个念头:一是“这黑客真厉害”&#x…

2026/7/5 0:07:38 阅读更多 →

周新闻

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容 【免费下载链接】BiliTools A cross-platform bilibili toolbox. 跨平台哔哩哔哩工具箱,支持下载视频、番剧等等各类资源 项目地址: https://gitcode.com/GitHub_Trending/bilit/BiliTools …

2026/7/5 0:03:34 阅读更多 →
威胁模型全解析:从新手入门到实战应用,助你构建安全产品!

威胁模型全解析:从新手入门到实战应用,助你构建安全产品!

威胁模型的陌生现状在忙碌疲惫的一天里,参与了关于混合后量子密码学的讨论,应付端点攻击找茬的人,还参与留言板讨论后,发现“威胁模型”对多数人仍是陌生概念,且多被当作时髦用语。有趣的相关画作有一幅由 Embyr 创作的…

2026/7/5 0:03:34 阅读更多 →
渗透测试入门指南:从零基础到实战环境搭建

渗透测试入门指南:从零基础到实战环境搭建

1. 从“看热闹”到“入门”:我理解的渗透测试到底是什么?每次看到新闻里说某个大公司的数据被“黑”了,或者某个网站被攻击导致服务瘫痪,你是不是和我一样,心里会冒出两个念头:一是“这黑客真厉害”&#x…

2026/7/5 0:07:38 阅读更多 →

月新闻