1. Why Error Handling is Needed
- To provide user-friendly error pages
- To log error information and handle them appropriately
- Avoid exposing internal server errors (like HTTP Status 500 or 404) to users with default WAS error pages
2. Servlet's Basic Error Handling Mechanism
1. Throwing Exceptions
throw new RuntimeException("Something went wrong!");
- If not caught, the exception propagates to the WAS and the default error page is shown
2. Sending Error Response
response.sendError(404, "Resource not found");
- Stores error status internally
- WAS checks this and returns appropriate error page
3. Registering Custom Error Pages in Spring Boot
Using WebServerFactoryCustomizer
@Component
public class WebServerCustomizer implements WebServerFactoryCustomizer<ConfigurableWebServerFactory> {
@Override
public void customize(ConfigurableWebServerFactory factory) {
factory.addErrorPages(
new ErrorPage(HttpStatus.NOT_FOUND, "/error-page/404"),
new ErrorPage(RuntimeException.class, "/error-page/500")
);
}
}
The second argument ("/error-page/404") is the path that the WAS forwards to when that error occurs.
Custom Controller to Handle Those Mappings
@Controller
public class ErrorPageController {
@RequestMapping("/error-page/404")
public String error404(HttpServletRequest request) {
return "error-page/404";
}
@RequestMapping("/error-page/500")
public String error500(HttpServletRequest request) {
return "error-page/500";
}
}
4. Error Page Call Flow (WAS-Level)
1. /hello -> Filter -> Servlet -> Interceptor -> Controller
2. Exception Occurs -> WAS identifies matching ErrorPage mapping
3. WAS calls /error-page/500 -> Filter -> Servlet -> Interceptor -> Controller (/error-page/500)
From the browser’s point of view, only one request is made. Internally the WAS does an additional forward to show the error page.
5. How Filters and Interceptors Distinguish Between Normal and Error Requests
Filter: DispatcherType based detection
You can specify which DispatcherType the filter should respond to:
filterRegistrationBean.setDispatcherTypes(DispatcherType.REQUEST, DispatcherType.ERROR);
** If the dispatcherTypes parameter is left empty or not defined, the default value is DispatcherType.REQUEST.
✅ DispatcherType Values and Their Meanings
Type | Description |
REQUEST | Used when the request is an initial client request.Example: A browser sends a GET /hello request. |
FORWARD | Used when the request is forwarded to another servlet or JSP using RequestDispatcher.forward(). |
INCLUDE | Used when the response includes another servlet or JSP using RequestDispatcher.include(). |
ERROR | Used when an exception occurs or response.sendError() is called, triggering an internal request to an error page. |
ASYNC | Used during asynchronous processing (available since Servlet 3.0). |
These values help filters (and sometimes interceptors) distinguish between different types of request flows in a servlet-based application.
Interceptor: Path-based exclusion
Interceptors do not support DispatcherType, so we exclude error paths explicitly:
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new LogInterceptor())
.order(1)
.addPathPatterns("/**")
.excludePathPatterns("/css/**", "/error", "/error-page/**", "/*.ico");
}
This prevents interceptors from being executed again during error page calls.
6. Spring Boot’s BasicErrorController
What it does:
- It maps the default error path /error registered by Spring Boot's ErrorMvcAutoConfiguration
- Automatically handles errors propagated to the WAS or triggered by response.sendError()
Developer Responsibility:
- Just create view templates for /error/404, /error/500, etc. in resources/templates/error/
View Resolution Priority
1. templates/error/500.html
2. templates/error/5xx.html
3. static/error/500.html
4. static/error/5xx.html
5. templates/error.html (default fallback)
More specific pages take priority over general ones.
Example:
templates/error/404.html -> shown for HTTP 404
static/error/4xx.html -> shown for any 4xx error
7. Error Attributes Available in the View
BasicErrorController passes these to the model:
* timestamp
* status
* error
* exception
* trace
* message
* errors
* path
You can access these in a Thymeleaf template like:
<li th:text="|status: ${status}|"></li>
<li th:text="|message: ${message}|"></li>
You can configure inclusion of attributes in application.properties:
server.error.include-exception=true
server.error.include-message=on_param
server.error.include-stacktrace=on_param
server.error.include-binding-errors=on_param
⚠️ In production, do not expose sensitive error data to users.
'JAVA Spring' 카테고리의 다른 글
Spring Type Conversion & Formatter (0) | 2025.04.11 |
---|---|
API Exception Handling (0) | 2025.04.11 |
Servlet Filter vs Spring Interceptor (0) | 2025.04.11 |
Cookie and Session (0) | 2025.04.11 |
Bean Validation (0) | 2025.04.08 |