29 Ağustos 2018 Çarşamba

SpringMVC @ExceptionHandler Anotasyonu

Giriş
Şu satırı dahil ederiz.
import org.springframework.web.bind.annotation.ExceptionHandler;
Exception yakalamak için yöntemler şöyle
- @ControllerAdvice + @ExceptionHandler : Global Exception handling yapar
- @Controller + @ExceptionHandler : Controller için Exception handling yapar
- HandlerExceptionResolver
- ResponseStatusException

SpringMVC ile exception handling içindir. İki şekilde kullanılabilir
1. Rest Controller seviyesinde
2. @ControllerAdvice ile birlikte

1. Controller Seviyesi
Örnek
Şöyle yaparız. //1 ile işaretli yerden fırlatılan ServiceException //2 ile işaretli kod tarafından yakalanır
@RestController
public class MyController {
    
  @GetMapping("/hello")
  public String hello() {
    service.hello();                                       // 1
  }
  
  @ExceptionHandler
  public ResponseEntity<String> handle(ServiceException e) { // 2
    return ResponseEntity(e.getMessage(),HttpStatus.INTERNAL_SERVER_ERROR);
  }
}
2. @ControllerAdvice İle Birlikte
Herhangi bir Controller'dan fırlatılan exceptionları yakalar. Birden fazla exception yakalanabilir. Metod parametresi olarak WebRequest, HandlerMethod alabilir.
Örnek
Şöyle yaparız
@ControllerAdvice
public class MyCustomExceptionsHandler {
  @ExceptionHandler(value = {UserServiceException.class})
  public ResponseEntity<Object> handleUserServiceException(UserServiceException ex, 
                                                           WebRequest request) {
    ...
  }
  @ExceptionHandler(value = {ExpiredJwtException.class})
  public ResponseEntity<Object> handleExpiredJwtException(ExpiredJwtException ex, 
                                                          WebRequest request) {
    ... 
  }
 
  //handlerOtherExceptions handles any unhandled exceptions.
  @ExceptionHandler(value = {Exception.class})
  public ResponseEntity<Object> handleOtherExceptions(Exception ex, 
                                                      WebRequest request) {
    ...
  }
}
Örnek
String taşıyan ResponseEntity dönmek için şöyle yaparız.
@ControllerAdvice
public class GlobalExceptionHandler {

  @ExceptionHandler(value = {UnauthorizedException.class})
  public ResponseEntity<Object> handleException(UnauthorizedException ex){
    return new ResponseEntity<Object>(ex.getMessage(), new HttpHeaders(),
      HttpStatus.FORBIDDEN);
  }
}
Örnek
Rest servisinden fırlatılan exception'ı yakalayıp String taşıyan ResponseEntity dönmek için şöyle yaparız. Burada metod imzasında HandlerMethod parametresi ile exception'ı fırlatan sınıf ta bulunabiliyor.
@ControllerAdvice
class AdviceA {

  @ExceptionHandler({MyException.class})
  public ResponseEntity<String> handleMyException(MyException pe,
    HandlerMethod handlerMethod) {
    Class controllerClass = handlerMethod.getMethod().getDeclaringClass();
    //controllerClass.toString will give you fully qualified name
    return new ResponseEntity<>("SomeString", HttpStatus.BAD_REQUEST);
  }
Ö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()));
  }

  //...
}
Örnek
Şöyle yaparız.
@ControllerAdvice
public class ControllerExceptionHandler {

  @ExceptionHandler(NoHandlerFoundException.class)
  public ModelAndView handlerNoHandlerFoundException() {

    ModelAndView modelAndView = new ModelAndView();
    modelAndView.setViewName("errorpage");
    modelAndView.addObject("errorTitle", "404 Not Found ");
    modelAndView.addObject("errorDescription", "The page is not available.");
    
    return modelAndView;
  }
}

Hiç yorum yok:

Yorum Gönder