Master Spring Boot 3 Exception Handling with @ExceptionHandler and Media Types
Explore how Spring Boot 3 leverages the @ExceptionHandler annotation to centralize error handling, customize responses based on the Accept header, configure view beans for HTML errors, and utilize new Spring 6.2 attributes, with complete code examples and testing guidance.
Introduction
Spring Boot 3 provides powerful mechanisms for handling exceptions in a centralized way using the @ExceptionHandler annotation. This article demonstrates how to customize error responses based on the client’s Accept header and how to configure view beans for HTML error pages.
@ExceptionHandler Overview
The @ExceptionHandler annotation can be placed on methods inside a controller advice class to handle specific exception types, making error handling clear and modular.
<code>@RestControllerAdvice
public class GlobalControllerAdvice {
@ExceptionHandler(BusinessException.class)
public ResponseEntity<Object> handleException(Exception e) {
// ...
}
@ExceptionHandler(CommonException.class)
public ResponseEntity<Object> handleException(Exception e) {
// ...
}
// ...
}</code>Media Type Specific Handling (Spring 6.2+)
Starting with Spring 6.2, @ExceptionHandler can specify the media type to produce, allowing different responses for the same exception based on the Accept header.
<code>@ControllerAdvice
public class GlobalControllerAdvice {
@ExceptionHandler(produces = "application/json")
public ResponseEntity<Object> handleJson(Exception e) {
return ResponseEntity.badRequest().body(
Map.of("code", -1, "message", e.getMessage()));
}
@ExceptionHandler(produces = "text/html")
public String handleHtml(Exception e) {
return "customError";
}
}</code>If the client requests application/json , the handleJson method is invoked; for text/html , the handleHtml method is used.
View Configuration for HTML Errors
The HTML response requires a view bean that renders the error page.
<code>@Configuration
public class ViewConfig {
@Bean(name = "customError")
View customError() {
return new View() {
@Override
public void render(Map<String, ?> model, HttpServletRequest request,
HttpServletResponse response) throws Exception {
response.setContentType("text/html;charset=utf-8");
response.getWriter().append("<h1>请求错误</h1>");
}
@Override
public String getContentType() {
return "text/html";
}
};
}
}</code>Testing the Exception Handling
<code>@GetMapping("")
public Object index() {
System.err.println(1/0);
return "error";
}</code>When the endpoint is called (e.g., via Postman), the division‑by‑zero exception triggers the appropriate handler based on the Accept header.
Displaying Exception Details in HTML
To show the actual exception message on the HTML error page, add a Model parameter to the handler and pass the message to the view.
<code>@ExceptionHandler(produces = "text/html")
public String handleHtml(Exception e, Model model) {
model.addAttribute("message", e.getMessage());
return "customError";
}
public void render(Map<String, ?> model, HttpServletRequest request,
HttpServletResponse response) throws Exception {
response.setContentType("text/html;charset=utf-8");
response.getWriter().append(model.get("message").toString());
}</code>Now the rendered HTML contains the specific error message.
New Attributes in Spring 6.2
Spring 6.2 adds an exception attribute (alias of value ) to @ExceptionHandler , allowing explicit declaration of the exception classes to handle.
<code>public @interface ExceptionHandler {
@AliasFor("exception")
Class<? extends Throwable>[] value() default {};
@AliasFor("value")
Class<? extends Throwable>[] exception() default {};
String[] produces() default {};
}</code>This attribute serves the same purpose as the original value element.
Spring Full-Stack Practical Cases
Full-stack Java development with Vue 2/3 front-end suite; hands-on examples and source code analysis for Spring, Spring Boot 2/3, and Spring Cloud.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.