Giriş
RFC 7807 Nedir?
Açıklaması şöyle
ProblemDetail is a standard format that is defined in RFC 7807 for describing errors and exceptions in HTTP APIs. The format includes a set of predefined fields, such as the error type, error code, error message, and additional details about the error.
Açıklaması şöyle
So you know how you would handle custom exceptions with @ControllerAdvice where you would have your custom messages wrapped inside a ResponseEntity. It is a tedious process and you still need to figure out what your message should look like. Imagine if the message was standardized but you could still extend it. Welcome to the Problem Detail RFC. SpringBoot 3.0 provides a ProblemDetail class to do the trick.
Maven
Şu satırı dahil ederiz
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
Eski Yöntem
Eski kodlarda şöyle yapılıyor
Örnek
Elimizde şöyle bir kod olsun. /**
* Data Transport Object to represent errors
*/
public class ErrorModel {
private final List<String> messages;
@JsonCreator
public ErrorModel(@JsonProperty("messages") List<String> messages) {
this.messages = messages;
}
public ErrorModel(String message) {
this.messages = Collections.singletonList(message);
}
public List<String> getMessages() {
return messages;
}
}
Rest servisinden fırlatılan exception'ı yakalayıp daha anlaşılır bir nesne taşıyan ResponseEntity dönmek için şöyle yaparız.@ControllerAdvice
public class ExceptionHandlers {
@ExceptionHandler
public ResponseEntity<ErrorModel> handle(ValidationException ex) {
return ResponseEntity.badRequest()
.body(new ErrorModel(ex.getMessages()));
}
//...
}
Yeni Yöntem
Artık ProblemDetail kullanılıyor. RFC ile tanımlı alanların açıklaması şöyle
"type" (string)- A URI reference [RFC3986] that identifies theproblem type. This specification encourages that, whendereferenced, it provide human-readable documentation for theproblem type (e.g., using HTML [W3C.REC-html5-20141028]). Whenthis member is not present, its value is assumed to be "about:blank"."title" (string)- A short, human-readable summary of the problemtype. It SHOULD NOT change from occurrence to occurrence of theproblem, except for purposes of localization (e.g., usingproactive content negotiation; see [RFC7231], Section 3.4)."status" (number)- The HTTP status code ([RFC7231], Section 6)generated by the origin server for this occurrence of the problem."detail" (string)- A human-readable explanation specific to this occurrence of the problem."instance" (string)- A URI reference that identifies the specificoccurrence of the problem. It may or may not yield furtherinformation if dereferenced.
Çıktı şöyle
{
"title": "Bad Request",
"status": 400,
"detail": "The request is invalid.",
"type": "https://example.com/errors/bad-request",
"instance": "/orders/1234"
}
constructor
Örnek
Şöyle yaparız
@RestControllerAdvice
public class CustomExceptionHandler extends ResponseEntityExceptionHandler {
@ExceptionHandler(value = { CustomException.class })
protected ResponseEntity<Object> handleCustomException(CustomException ex,
WebRequest request) {
ProblemDetail problemDetail = new ProblemDetails();
problemDetail.setStatus(HttpStatus.BAD_REQUEST);
problemDetail.setTitle("Custom Exception");
problemDetail.setDetail(ex.getMessage());
return handleExceptionInternal(ex, problemDetail, new HttpHeaders(),
HttpStatus.BAD_REQUEST, request);
}
}
forStatusAndDetail metodu
Örnek
Şöyle yaparız
@ControllerAdvice
public class ProblemDetailErrorHandlingControllerAdvice {
@ExceptionHandler
public ProblemDetail onException(IllegalArgumentException e) {
return ProblemDetail.forStatusAndDetail(HttpStatusCode.valueOf(400), e.getMessage());
}
}
Çıktısı şöyle
{
"type":"about:blank",
"title":"Bad Request",
"status":400,
"detail":"User with firstName=Natashaa not found.",
"instance":"/users"
}
Hiç yorum yok:
Yorum Gönder