Part of
problem4j
package of libraries.
Spring Web integration module for problem4j-core
. library that integrates the RFC Problem Details
model with exception handling in Spring Boot.
The desired usage of this library is to make all your custom exceptions extend ProblemException
from problem4j-core
.
It's still possible to create custom @RestControllerAdvice
-s, but some nuances with @Order
are necessary (explained
in Usage chapter, which covers also how response bodies for build-in Spring exceptions are overwritten).
- ✅ Automatic mapping of exceptions to responses with
Problem
objects compliant with RFC 7807. - ✅ Mapping of exceptions extending
ProblemException
to responses withProblem
objects. - ✅ Fallback mapping of
Exception
toProblem
objects representing500 Internal Server Error
. - ✅ Simple configuration thanks to Spring Boot autoconfiguration.
import io.github.malczuuu.problem4j.core.Problem;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.context.request.WebRequest;
@Order(Ordered.LOWEST_PRECEDENCE - 20)
@Component
@RestControllerAdvice
public class ExampleExceptionAdvice {
@ExceptionHandler(ExampleException.class)
public ResponseEntity<Problem> method(ExampleException ex, WebRequest request) {
Problem problem =
Problem.builder()
.type("http://example.com/errors/example-error")
.title("Example Title")
.status(400)
.detail(ex.getMessage())
.instance("https://example.com/instances/example-instance")
.build();
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_PROBLEM_JSON);
HttpStatus status = HttpStatus.valueOf(problem.getStatus());
return new ResponseEntity<>(problem, headers, status);
}
}
Add library as dependency to Maven or Gradle. See the actual versions on Maven Central. Add it along with repository in your dependency manager. Java 17 or higher is required to use this library.
Tested with Spring Boot 3+
, but mostly on 3.5.x
. However, the idea for this library was to be backwards compatible
down to 3.0.0
.
Note that spring-webmvc
and jackson-databind
dependencies must be included alongside problem4j-spring-web
, as
the number of transitive dependencies was limited.
- Maven:
<dependencies> <dependency> <groupId>io.github.malczuuu.problem4j</groupId> <artifactId>problem4j-spring-web</artifactId> <version>${problem4j-spring-web.version}</version> </dependency> </dependencies>
- Gradle (Groovy or Kotlin DSL):
dependencies { implementation("io.github.malczuuu.problem4j:problem4j-spring-web:${problem4j-spring-web.version}") }
Overriding of build-in exceptions is performed by custom ExceptionMapping
and its implementations.
These mappings are instantiated in ExceptionMappingConfiguration
with
@ConditionalOnClass
, per appropriate exception. Therefore, if using this library with previous versions, mappings for
exception classes that are not present in classpath are silently ignored.
Do not use mentioned ExceptionMapping
in applications, for creating error handler for exceptions other than
ProblemException
stick to Spring's @RestControllerAdvice
, as described in next paragraph.
While creating your own @RestControllerAdvice
, make sure to position it with right @Order
. In order for your custom
implementation to work seamlessly, make sure to position it on at least Ordered.LOWEST_PRECEDENCE - 1
(the lower
the value, the higher the priority), as ExceptionAdvice
covers the most generic Exception
class.
@RestControllerAdvice |
covered exceptions | @Order(...) |
---|---|---|
ProblemEnhancedExceptionHandler |
Spring's internal exceptions | Ordered.LOWEST_PRECEDENCE - 10 |
ProblemExceptionAdvice |
ProblemException |
Ordered.LOWEST_PRECEDENCE - 10 |
ConstraintViolationExceptionAdvice |
ConstraintViolationException |
Ordered.LOWEST_PRECEDENCE - 10 |
ExceptionAdvice |
Exception |
Ordered.LOWEST_PRECEDENCE |
Library can be configured with following properties.
Property that specifies how exception handling imported with this module should print "defail"
field of Problem
model (lowercase
, capitalized
- default, uppercase
). Useful for keeping the same style of errors coming from
library and your application.
problem4j
- Documentation repository.problem4j-core
- Core library definingProblem
model andProblemException
.problem4j-jackson
- Jackson module for serializing and deserializingProblem
objects.problem4j-spring-web
- Spring Web module extendingResponseEntityExceptionHandler
for handling exceptions and returningProblem
responses.