跳到主要内容
Spring Boot 自定义错误页面:404/500 页面定制与 ErrorController | 极客日志
Java java
Spring Boot 自定义错误页面:404/500 页面定制与 ErrorController 综述由AI生成 Spring Boot 自定义错误页面方案。内容包括通过静态文件或模板引擎(Thymeleaf)配置 404/500 页面,以及实现自定义 ErrorController 接口接管错误处理。文章对比了默认 BasicErrorController 与自定义方案的差异,演示了如何根据请求头区分返回 HTML 或 JSON 响应。同时涵盖了结合 ControllerAdvice 处理业务异常、日志记录及生产环境部署建议,旨在帮助开发者构建友好的用户体验和规范的 API 错误响应。
HadoopMan 发布于 2026/3/23 更新于 2026/5/12 29K 浏览Spring Boot 自定义错误页面:404/500 页面定制与 ErrorController
一、引言
当用户访问一个不存在的链接或服务器内部发生错误时,他们会看到一个冰冷、晦涩的默认错误页面(如 Whitelabel Error Page)。这不仅是一个糟糕的用户体验,还可能暴露不必要的服务器内部信息。在生产环境中,提供一个定制的、友好的错误页面是至关重要的。
Spring Boot 为此提供了一套强大且灵活的错误处理机制。这套机制的核心是 BasicErrorController,它是一个默认的 MVC 控制器,专门用于处理 /error 路径的请求。开发者可以通过多种方式来定制这套机制:
自定义错误页面 :对于使用 Thymeleaf、FreeMarker 等传统视图技术的 Web 应用,可以简单地在静态资源或模板目录下放置错误页面文件(如 404.html)。
自定义 ErrorController :当需要更精细的控制,例如为 API 和网页返回不同格式的响应时,可以实现自定义的 ErrorController 来完全取代默认行为。
使用 @ControllerAdvice :对于 RESTful API,结合 @ControllerAdvice 和 @ExceptionHandler 可以更优雅地处理业务逻辑异常,而 ErrorController 则作为处理未预料到的服务器错误的最后一道防线。
本文将全面剖析这些技术,引导读者构建一个既能服务于人类用户(通过精美页面),又能服务于机器客户端(通过标准 JSON)的全方位错误处理方案。
二、技术背景
2.1 Spring Boot 的默认错误处理流程
错误发生 : 当控制器方法执行抛出异常,或 DispatcherServlet 找不到对应的处理器(导致 404)时,会产生一个错误。
转发到 /error : Spring Boot 的 BasicErrorController 会拦截这个错误,并将请求转发 到 ServletContext 的根路径下的 /error 端点。
解析错误属性 : BasicErrorController 会从 HttpServletRequest 的属性中收集丰富的错误信息,这些属性由 Spring 的 DefaultErrorAttributes 提供。关键的属性包括:
timestamp: 时间戳
status: HTTP 状态码 (e.g., 404, 500)
error: 错误原因简述 (e.g., 'Not Found', 'Internal Server Error')
exception: 异常的类名(如果可用)
message: 异常的具体消息(如果可用)
path: 发起请求的 URI 路径
trace: 完整的堆栈跟踪(默认只在非生产环境显示)
选择响应方式 : BasicErrorController 有两个处理 /error 的方法:
errorHtml(HttpServletRequest, HttpServletResponse): 当请求的 Accept 头包含 text/html 时调用,返回一个渲染好的错误页面(Whitelabel Error Page)。
error(HttpServletRequest): 当请求的 头是 或其他非 HTML 类型时调用,返回一个 JSON 响应,包含上述所有错误属性。
Accept
application/json
解析视图或返回 JSON : 对于 HTML 请求,它会尝试解析一个名为 error 的视图。如果该视图不存在,则回退到 Whitelabel 页面。对于 JSON 请求,它直接返回 Map 转换的 JSON。
2.2 定制路径 默认的错误路径 /error 可以通过配置 server.error.path 属性进行修改。
三、应用使用场景 场景分类 具体描述 推荐技术方案 Web 应用友好提示 用户通过浏览器访问网站,遇到 404/500 错误时,看到品牌化的、友好的 HTML 页面。 自定义错误页面 (放置在 src/main/resources/templates/error/ 或静态资源目录)。REST API 标准化响应 前端或第三方应用调用 API 时发生错误,期望收到一个结构统一、包含错误码的 JSON 响应。 自定义 ErrorController 或 @ControllerAdvice + @ExceptionHandler 的组合。区分对待 API 与 Web 请求 同一个应用既是网站又是 API 服务器。需要根据客户端的 Accept 头返回 HTML 页面或 JSON 数据。 自定义 ErrorController ,在其中判断请求头的 Accept。记录详细的错误日志 对于所有服务器内部错误(500),需要将完整的堆栈信息记录到日志系统中,但不返回给客户端。 在自定义 ErrorController 或全局异常处理器中,使用 logger.error 记录 exception 属性。 完全掌控错误响应 默认的错误处理逻辑无法满足需求,例如需要集成 APM 工具上报错误,或需要屏蔽某些敏感信息。 实现 ErrorController 接口 ,完全接管 /error 端点的处理逻辑。
四、不同场景下详细代码实现
4.1 环境准备与项目结构 1. 依赖 (pom.xml)
我们将使用 spring-boot-starter-web 和 spring-boot-starter-thymeleaf(用于演示 HTML 错误页面)。
<?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 > 2.7.5</version >
<relativePath />
</parent >
<groupId > com.example</groupId >
<artifactId > custom-error-page-demo</artifactId >
<version > 0.0.1-SNAPSHOT</version >
<name > custom-error-page-demo</name >
<description > Demo project for Spring Boot Custom Error Pages and ErrorController</description >
<properties >
<java.version > 11</java.version >
</properties >
<dependencies >
<dependency >
<groupId > org.springframework.boot</groupId >
<artifactId > spring-boot-starter-web</artifactId >
</dependency >
<dependency >
<groupId > org.springframework.boot</groupId >
<artifactId > spring-boot-starter-thymeleaf</artifactId >
</dependency >
<dependency >
<groupId > org.springframework.boot</groupId >
<artifactId > spring-boot-starter-test</artifactId >
<scope > test</scope >
</dependency >
</dependencies >
<build >
<plugins >
<plugin >
<groupId > org.springframework.boot</groupId >
<artifactId > spring-boot-maven-plugin</artifactId >
</plugin >
</plugins >
</build >
</project >
package com.example.customerrorpagedemo.model;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import java.time.LocalDateTime;
@Data
public class ApiError {
private int status;
private String error;
private String message;
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime timestamp;
private String path;
public ApiError (int status, String error, String message, String path) {
this .timestamp = LocalDateTime.now();
this .status = status;
this .error = error;
this .message = message;
this .path = path;
}
}
package com.example.customerrorpagedemo.controller;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class DemoController {
@GetMapping("/")
public String home () {
return "Welcome to the Home Page!" ;
}
@GetMapping("/resource/{id}")
public String getResource (@PathVariable int id) {
if (id == 1 ) {
return "Found resource with ID: " + id;
} else {
throw new ResourceNotFoundException ("Resource with ID " + id + " not found." );
}
}
@GetMapping("/trigger-error")
public void triggerError () {
throw new RuntimeException ("This is a deliberate server-side error for demonstration." );
}
@GetMapping("/api/data")
public ResponseEntity<String> getData () {
return ResponseEntity.ok("{\"data\": \"some valuable information\"}" );
}
}
class ResourceNotFoundException extends RuntimeException {
public ResourceNotFoundException (String message) {
super (message);
}
}
package com.example.customerrorpagedemo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class CustomErrorPageDemoApplication {
public static void main (String[] args) {
SpringApplication.run(CustomErrorPageDemoApplication.class, args);
}
}
4.2 场景一:自定义错误页面 (静态与模板) 创建模板错误页面 (推荐) :
在 src/main/resources/templates/ 目录下创建 error 文件夹。Thymeleaf 会自动在这里查找错误页面。页面的名称可以是通用的 error.html,也可以是特定状态码的页面,如 error/404.html。特定状态码的页面优先级高于通用页面 。
src/main/resources/templates/error/404.html
<!DOCTYPE html >
<html xmlns:th ="http://www.thymeleaf.org" >
<head >
<title > 404 Not Found</title >
<style >
body { font-family : sans-serif; text-align : center; padding-top : 50px ; }
h1 { color : #d9534f ; }
</style >
</head >
<body >
<h1 > 404 - Page Not Found</h1 >
<p th:text ="'The requested URL ' + ${path} + ' was not found on this server.'" > The requested URL was not found on this server.</p >
<p th:text ="'Timestamp: ' + ${timestamp}" > Timestamp: ...</p >
<a href ="/" > Back to Home</a >
</body >
</html >
src/main/resources/templates/error/500.html
<!DOCTYPE html >
<html xmlns:th ="http://www.thymeleaf.org" >
<head >
<title > 500 Internal Server Error</title >
<style >
body { font-family : sans-serif; text-align : center; padding-top : 50px ; }
h1 { color : #d9534f ; }
</style >
</head >
<body >
<h1 > 500 - Internal Server Error</h1 >
<p > Something went wrong on our end. We have been notified.</p >
<p th:text ="'Error: ' + ${error}" > Error: Internal Server Error</p >
<p th:text ="'Message: ' + ${message}" > Message: ...</p >
<p th:text ="'Path: ' + ${path}" > Path: ...</p >
<a href ="/" > Back to Home</a >
</body >
</html >
创建静态错误页面 :
在 src/main/resources/static/ 目录下创建 error 文件夹,并在其中放置 404.html 和 500.html。这种方式优先级最低,当没有找到模板引擎对应的页面时,会 fallback 到这里。
src/main/resources/static/error/404.html
<!DOCTYPE html >
<html >
<head >
<title > Static 404 Not Found</title >
</head >
<body >
<h1 > Oops! (Static)</h1 >
<p > The page you are looking for does not exist.</p >
<a href ="/" > Go Home</a >
</body >
</html >
4.3 场景二:自定义 ErrorController (高级定制) 当简单的 HTML 页面无法满足需求时(例如,为 API 返回 JSON),我们需要实现自定义的 ErrorController。
package com.example.customerrorpagedemo.controller;
import com.example.customerrorpagedemo.model.ApiError;
import org.springframework.boot.web.servlet.error.ErrorAttributes;
import org.springframework.boot.web.servlet.error.ErrorController;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.context.request.ServletWebExchange;
import org.springframework.web.context.request.WebRequest;
import javax.servlet.http.HttpServletRequest;
import java.util.Map;
@Controller
public class CustomErrorController implements ErrorController {
private final ErrorAttributes errorAttributes;
public CustomErrorController (ErrorAttributes errorAttributes) {
this .errorAttributes = errorAttributes;
}
@RequestMapping("/error")
public ResponseEntity<?> handleError(WebRequest webRequest) {
Map<String, Object> attrs = errorAttributes.getErrorAttributes(webRequest, true );
Integer statusCode = (Integer) attrs.get("status" );
String path = (String) attrs.get("path" );
String error = (String) attrs.get("error" );
String message = (String) attrs.get("message" );
Throwable exception = errorAttributes.getError(webRequest);
if (statusCode != null && statusCode >= 500 ) {
System.err.println("!!! SERVER ERROR !!! Status: " + statusCode + ", Path: " + path);
if (exception != null ) {
exception.printStackTrace(System.err);
}
}
String acceptHeader = ((ServletWebExchange) webRequest).getRequest().getHeader("Accept" );
if (acceptHeader != null && acceptHeader.contains(MediaType.APPLICATION_JSON_VALUE)) {
ApiError apiError = new ApiError (statusCode, error, message, path);
return new ResponseEntity <>(apiError, HttpStatus.valueOf(statusCode));
} else {
if (statusCode == 404 ) {
return ResponseEntity.status(HttpStatus.NOT_FOUND).body("<h1>Custom 404 JSON Response</h1>" );
} else {
return ResponseEntity.status(HttpStatus.valueOf(statusCode)).body(attrs);
}
}
}
@Override
public String getErrorPath () {
return "/error" ;
}
}
注意 : 一旦我们提供了自定义的 ErrorController,Spring Boot 的默认 BasicErrorController 就会失效。因此,我们必须自己实现所有逻辑,包括在 handleError 方法中判断 Accept 头来模拟其行为。上面的代码示例展示了如何获取错误属性和记录日志,并返回一个自定义的 ResponseEntity。为了简单起见,它没有重新实现复杂的视图解析逻辑,而是演示了如何根据 Accept 头返回不同内容。
一个更实用的做法是,让自定义的 ErrorController只处理 API 错误 ,而让 Spring Boot 继续处理 HTML 错误。这可以通过让自定义控制器只响应 JSON 来实现,而 HTML 请求则会因为没有对应的 @RequestMapping(produces = "text/html") 方法而 fallback 到默认机制。但默认的 BasicErrorController 已经被我们的 Bean 覆盖,所以我们需要在自定义控制器中显式地调用父类的逻辑或重新实现 HTML 渲染,这会很复杂。因此,在生产中,一个常见的模式是:
使用 @ControllerAdvice 处理所有已知的业务异常,返回 JSON。
对于未知的 404/500 错误,使用自定义错误页面 来处理 HTML 请求。
如果需要为 API 也定制 404/500 的 JSON 响应,可以实现一个 ErrorController,但让它只对特定的 Content-Type 或路径生效,或者使用 @ConditionalOn 等注解在特定环境下激活。
为了演示的清晰性,下面提供一个更简洁的、只处理 API JSON 响应 的 ErrorController,并配合 @ControllerAdvice 和静态/模板页面来处理 HTML 和普通异常。这需要移除 @Controller 注解,并用 @Component 使其成为 Bean,同时添加一个条件,比如只在请求是 API 路径时才处理。但为了简化,我们展示一个独立的、完全自定义的版本,它会覆盖所有 /error 请求。
简化版 CustomErrorController (完全接管) :
@Component
public class PureJsonErrorController implements ErrorController {
private final ErrorAttributes errorAttributes;
public PureJsonErrorController (ErrorAttributes errorAttributes) {
this .errorAttributes = errorAttributes;
}
@RequestMapping("/error")
@ResponseBody
public ResponseEntity<ApiError> handleError (HttpServletRequest request) {
Map<String, Object> attrs = errorAttributes.getErrorAttributes(new ServletWebRequest (request), true );
Integer statusCode = (Integer) attrs.get("status" );
if (statusCode == null ) { statusCode = 500 ; }
String path = (String) attrs.get("path" );
String error = (String) attrs.get("error" );
String message = (String) attrs.get("message" );
Throwable exception = errorAttributes.getError(new ServletWebRequest (request));
if (statusCode >= 500 ) {
System.err.println("Server error at " + path + ": " + exception.getMessage());
exception.printStackTrace();
}
ApiError apiError = new ApiError (statusCode, error, message, path);
return new ResponseEntity <>(apiError, HttpStatus.valueOf(statusCode));
}
@Override
public String getErrorPath () {
return "/error" ;
}
}
要使用这个控制器,你需要暂时移除 src/main/resources/templates/error/ 下的 HTML 文件,因为它会覆盖所有错误,导致看不到 HTML 页面。这个例子清晰地展示了如何为 API 构建一个统一的 JSON 错误响应。
五、原理解释与核心特性
5.1 核心特性
分层定制 : Spring Boot 允许从最简单的静态文件定制到最复杂的 Java 代码逻辑定制,适应不同复杂度的需求。
内容协商 : 默认的 BasicErrorController 和精心设计的自定义 ErrorController 能够根据 Accept 请求头智能地返回 HTML 或 JSON。
丰富的错误属性 : ErrorAttributes 提供了标准化的错误上下文,开发者无需手动从 HttpServletRequest 中抓取。
无缝集成 : 自定义错误页面可以与 Thymeleaf 等模板引擎无缝集成,使用其表达式语言访问错误属性。
完全控制 : 通过实现 ErrorController 接口,开发者可以获得对错误处理流程的绝对控制权,包括日志记录、监控集成和自定义响应格式。
5.2 原理流程图与解释
错误发生后,请求被转发到 /error。
Spring 检查容器中是否存在用户自定义的 ErrorController Bean。
如果没有 ,则使用 BasicErrorController。该控制器根据 Accept 头,要么渲染一个名为 error 的视图,要么返回一个包含所有错误属性的 JSON。
如果存在 ,则调用自定义控制器的处理方法。在该方法中,我们通过 ErrorAttributes 获取错误详情,然后根据业务逻辑(如请求头、路径等)构建任意想要的响应(HTML 或 JSON),并返回。
六、实际详细应用代码示例实现
src/main/resources/templates/error/*.html: 静态和模板错误页面。
DemoController.java: 用于触发各种错误的控制器。
CustomErrorController.java: 展示了如何实现一个高级的、可完全控制的错误控制器。
七、运行结果与测试步骤
7.1 运行应用
7.2 测试步骤 前提 : 确保 CustomErrorController 没有被激活(或者删掉它),以便测试自定义错误页面 。
curl -i -H "Accept: application/json" http://localhost:8080/resource/999
预期 : 收到一个 JSON 响应,包含 status: 404 和我们自定义的消息。(注意:由于我们没有在 DemoController 中配置 @ControllerAdvice,这个 404 是由 ResponseEntityExceptionResolver 处理的,其默认行为是返回空的 JSON body。要让它返回更丰富的信息,需要配合 @ControllerAdvice 或自定义 ErrorController) 。
curl -i http://localhost:8080/trigger-error
预期 : 看到一个 500 错误页面,显示了错误信息和路径。在应用的控制台,你会看到抛出的 RuntimeException 的堆栈跟踪。
curl -i http://localhost:8080/nonexistent-page
预期 : 浏览器会显示一个漂亮的 404 页面,其中包含路径和时间戳等信息。curl 会收到一个 text/html 响应。
测试 CustomErrorController :
将 PureJsonErrorController.java 添加到项目中。
暂时移除或重命名 src/main/resources/templates/error/ 目录下的 HTML 文件,防止冲突。
重启应用。
curl -i http://localhost:8080/trigger-error
预期 : 即使没有 Accept: application/json 头,由于我们自定义的控制器用了 @ResponseBody,它仍然会返回 JSON。这证明了它覆盖了默认行为。
curl -i -H "Accept: application/json" http://localhost:8080/trigger-error
预期 : 收到一个结构化的 ApiError JSON 响应,这是我们自定义的格式。
八、部署场景
Jar 包部署 : 所有静态资源和模板文件都会打包在 Jar 内。应用启动时,Spring Boot 会从 classpath 加载它们。自定义 ErrorController 的逻辑随应用一起运行。
Docker 部署 : 与 Jar 包部署类似。需要注意的是,如果在容器中需要修改错误页面,必须重新构建镜像,因为它们是打包进去的。更好的做法是将错误页面放在容器外部的卷中,并通过自定义 ErrorController 或修改 Spring 的 ResourceHandler 来加载,但这比较复杂。
生产环境配置 :
application-prod.properties: 在此文件中设置 server.error.whitelabel.enabled=false 可以完全禁用默认的 Whitelabel 页面,以防自定义机制失效时出现。
日志 : 确保 ErrorController 中对 5xx 错误的 printStackTrace 或 logger.error 能正确输出到标准错误流,并被容器编排系统(如 Kubernetes)收集。
APM 集成 : 在 ErrorController 的 catch-all 逻辑中,可以加入向 Sentry, Datadog 等监控服务上报错误的代码。
CDN/反向代理 : 有时,404 错误可能在 CDN(如 Cloudflare)或反向代理(如 Nginx)层面就被处理了。在这种情况下,需要在那些层级也配置相应的自定义错误页面,以覆盖整个请求链路。
九、疑难解答
问题:我创建了 error.html,但访问 404 时没生效。
原因 : 可能存在特定状态码的页面(如 404.html)优先级更高,但它可能出错了或不存在。或者 Thymeleaf 的依赖或配置有问题。
解决 : 检查控制台日志是否有模板解析错误。确保 spring-boot-starter-thymeleaf 依赖已正确引入。可以先删除 404.html,只保留 error.html 来测试通用页面是否生效。
问题:自定义 ErrorController 后,连 Whitelabel 页面都不见了,返回 404。
原因 : 自定义的 ErrorController 可能没有正确处理所有情况,或者其返回的视图名无法被解析。
解决 : 检查自定义控制器的逻辑,确保它能处理所有预期的 HTTP 状态码。如果只是想为 API 定制,可以尝试让控制器方法只匹配 produces = "application/json",从而为 HTML 请求留出空间,让其 fallback 到默认机制(但默认机制已被覆盖,所以此法不通)。最佳实践是,如果需要 HTML 页面,就不要完全覆盖 ErrorController,而是使用自定义错误页面 的方式。
问题:@ControllerAdvice 和 ErrorController 是什么关系?
关系 : 它们是互补的,作用于不同阶段。@ControllerAdvice 主要用于处理控制器方法执行过程中抛出的已知异常 (如 ResourceNotFoundException)。ErrorController 是处理未被 @ControllerAdvice 捕获的、更底层的错误 (如控制器不存在的 404,或控制器方法抛出未预料到的 RuntimeException 导致的 500)。
问题:如何在 ErrorController 中获取异常的完整堆栈?
解决 : 在调用 errorAttributes.getErrorAttributes(..., true) 时,第二个参数设为 true,表示包含 'trace'。然后可以从返回的 Map 中获取 trace 键的值。但请注意,这个值默认只在非生产环境返回给客户端。在 ErrorController 内部,你应该使用 errorAttributes.getError(request) 获取 Throwable 对象,然后用 logger.error 记录其堆栈。
十、未来展望、技术趋势与挑战
Observability-Driven Error Handling : 未来的错误处理将与可观测性(Observability)紧密结合。当 ErrorController 捕获到错误时,它不仅返回一个响应,还会自动发出指标(Metric)、日志(Log)和追踪(Trace)——即 '可观测性三大支柱' 。这将使开发人员能够实时监控服务健康状况,快速定位故障根源。
Headless CMS for Error Pages : 对于大型网站,错误页面本身可能需要频繁更新或 A/B 测试。未来可能会出现将错误页面内容与主应用解耦的趋势,例如从一个 Headless CMS(内容管理平台)动态获取错误页面的 HTML 内容。
AI-Powered Error Analysis : AI 和机器学习可以用于分析大量的错误日志和 ErrorController 捕获的数据,自动识别异常模式、预测潜在故障,并提出修复建议。
挑战:安全性与信息泄露 : 在自定义 ErrorController 时,最大的挑战之一是确保不会向客户端泄露敏感信息(如数据库密码、内部 IP 地址)。必须对返回给客户端的 message 字段进行严格的审查和过滤,尤其是在生产环境中。
挑战:一致性 : 在微服务架构中,确保每个服务都遵循统一的错误响应格式是一项挑战。需要通过共享库或 API 网关来强制执行错误格式规范。
十一、总结 Spring Boot 的错误处理机制非常强大,为开发者提供了从简单到复杂的多种定制选项。
对于传统的 Web 应用 ,使用 自定义错误页面 (src/main/resources/templates/error/status_code.html)是最简单、最直接的方式,能够快速提升用户体验。
对于现代的 RESTful API ,最佳实践是结合使用 @ControllerAdvice + @ExceptionHandler 来处理业务逻辑异常,并可以辅以一个自定义的 ErrorController 来为未预料的 404/500 错误提供统一的、结构化的 JSON 响应。
核心组件 ErrorAttributes 和 ErrorController 为我们提供了深入定制错误处理流程的能力,使我们能够实现日志记录、监控集成和精细化控制。
理解 Spring Boot 的默认错误流程是进行有效定制的前提。通过本文的学习,读者应能根据自己应用的特点,选择并实现一个功能完善、用户体验良好且安全可靠的错误 handling 方案。
相关免费在线工具 Keycode 信息 查找任何按下的键的javascript键代码、代码、位置和修饰符。 在线工具,Keycode 信息在线工具,online
Escape 与 Native 编解码 JavaScript 字符串转义/反转义;Java 风格 \uXXXX(Native2Ascii)编码与解码。 在线工具,Escape 与 Native 编解码在线工具,online
JavaScript / HTML 格式化 使用 Prettier 在浏览器内格式化 JavaScript 或 HTML 片段。 在线工具,JavaScript / HTML 格式化在线工具,online
JavaScript 压缩与混淆 Terser 压缩、变量名混淆,或 javascript-obfuscator 高强度混淆(体积会增大)。 在线工具,JavaScript 压缩与混淆在线工具,online
Base64 字符串编码/解码 将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online
Base64 文件转换器 将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online