26 Nisan 2023 Çarşamba

SpringMVC ProblemDetail Sınıfı - RFC 7807 İçindir

Giriş
Şu satırı dahil ederiz.
import org.springframework.http.ProblemDetail;
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 the
    problem type.  This specification encourages that, when
    dereferenced, it provide human-readable documentation for the
    problem type (e.g., using HTML [W3C.REC-html5-20141028]).  When
    this member is not present, its value is assumed to be "about:blank".

"title" (string)
- A short, human-readable summary of the problem
    type.  It SHOULD NOT change from occurrence to occurrence of the
    problem, except for purposes of localization (e.g., using
    proactive 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 specific
    occurrence of the problem.  It may or may not yield further
    information 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