Как мы можем обработать исключение в HandlerInterceptorAdapter? - PullRequest
1 голос
/ 19 июня 2020

В настоящее время я пытаюсь реализовать собственный обработчик ошибок для весенней загрузки, и я сделал это следующим образом:

 public class ExceptionHandler extends HandlerInterceptorAdapter {

 public static Logger log = LoggerFactory.getLogger(LoggingInterceptor.class);

 public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable ModelAndView modelAndView) throws Exception {
        try {
          log.info("Service {} Calling {} on {} finished with status {}",request.getRemoteUser(), request.getMethod(), request.getRequestURI(), HttpStatus.valueOf(response.getStatus()));
        } catch (Exception e) {
            // Do nothing
        } finally {
            log.error("[Spring Boot Interceptor] {} returned with {}", handler, HttpStatus.valueOf(response.getStatus()));
    }
 }

Почему-то это не работает, и исключение все еще отправляется клиенту, есть ли способ поймать исключение, созданное методом, и проигнорировать его, например.

1 Ответ

2 голосов
/ 22 июня 2020

Хороший способ управлять исключением - использовать @ControllerAdvice, с его помощью вы можете обрабатывать любые исключения и настраивать ответ по мере необходимости.

Как сказано в комментарии, вы должны добавить InterceptorRegistry для регистрации перехватчика.

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class WebConfig implements WebMvcConfigurer {

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new Interceptor()).addPathPatterns("/**");
    }
}

Блок catch внутри postHandle будет выполнен только в том случае, если внутри блока try-catch произошло исключение, как показано ниже,

@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable ModelAndView modelAndView) throws Exception {
    try {
        int error = 1/0;
    } catch (Exception e) {
        log.info("Exception will be handled inside catch block");
    } 
}

Теперь давайте рассмотрим @ ControllerAdvice для управления исключением в приложении. Эти два API будут генерировать исключения, и мы будем управлять исключениями, используя @ExceptionHandler

@GetMapping("/exception/404")
public void generateResourceNotFound() {
    throw new ResourceNotFoundException("resource not found");
}

@GetMapping("/exception/403")
public void generateAccessDenied() {
    throw new AccessDeniedException("access denied");
}

GlobalExceptionHandler. java

import com.learning.annotations.controller.ResourceNotFoundException;
import com.learning.annotations.dto.ErrorResponseDTO;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.context.request.WebRequest;
import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler;

@ControllerAdvice
public class GlobalExceptionHandler extends ResponseEntityExceptionHandler {

    public Logger log = LoggerFactory.getLogger(Interceptor.class);

    @ExceptionHandler(AccessDeniedException.class)
    public ResponseEntity<ErrorResponseDTO> handleAccessDeniedException(AccessDeniedException ex, WebRequest request) {
        ErrorResponseDTO response = new ErrorResponseDTO();
        response.setError(ex.getMessage());
        response.setMessage("You don't have authority to access the resource");
        return new ResponseEntity<>(response, HttpStatus.FORBIDDEN);
    }

    @ExceptionHandler(ResourceNotFoundException.class)
    public ResponseEntity<ErrorResponseDTO> handleResourceNotFoundException(ResourceNotFoundException ex, WebRequest request) {
        ErrorResponseDTO response = new ErrorResponseDTO();
        response.setError(ex.getMessage());
        response.setMessage("Resource might be moved temporary or not available");
        return new ResponseEntity<>(response, HttpStatus.NOT_FOUND);
    }
}

Чтобы настроить ответ мы можем создать DTO ответа на ошибку следующим образом:

import lombok.Data;

@Data
public class ErrorResponseDTO {
    private String message;
    private String error;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...