Есть ли хороший пример реализации zalando-проблемы в spring boot?

#java #spring-boot #exception

#java #spring-boot #исключение

Вопрос:

Мы используем zalando-problem для обработки исключений в нашем приложении spring-boot. но, похоже, наши обработчики проблем никогда не вызываются. Вместо этого spring boot возвращает 500 внутренних ошибок сервера для всех исключений. Если вы можете привести несколько примеров, это будет полезно. Я не смог найти хороший пример реализации zalando-problem в spring boot

Если пользователь не вошел в систему, код выдает исключение SSOAuthenticationException.

 @Immutable
public class SSOAuthenticationException extends AbstractThrowableProblem {

    private final String errorMessage;

    public SSOAuthenticationException( final String errorMessage ) {
        super( ErrorConstants.SSO_CACHE_AUTHENTICATION_FAILED, errorMessage, Status.UNAUTHORIZED );
        this.errorMessage = errorMessage;
    }

    public String getErrorMessage(){
        return errorMessage;
    }
    @Override
    public String toString() {
        return "SSOAuthenticationException{}";
    }
}
  

И код обработки исключений:

 @ControllerAdvice
public class ExceptionTranslator implements ProblemHandling {
    @Override
    public ResponseEntity<Problem> process(@Nullable ResponseEntity<Problem> entity, NativeWebRequest request) {
        if (entity == null) {
            return entity;
        }
        Problem problem = entity.getBody();
        if (!(problem instanceof ConstraintViolationProblem || problem instanceof DefaultProblem)) {
            return entity;
        }
        ProblemBuilder builder = Problem.builder()
            .withType(Problem.DEFAULT_TYPE.equals(problem.getType()) ? ErrorConstants.DEFAULT_TYPE : problem.getType())
            .withStatus(problem.getStatus())
            .withTitle(problem.getTitle())
            .with("path", request.getNativeRequest(HttpServletRequest.class).getRequestURI());

        if (problem instanceof ConstraintViolationProblem) {
            builder
                .with("violations", ((ConstraintViolationProblem) problem).getViolations())
                .with("message", ErrorConstants.ERR_VALIDATION);
        } else {
            builder
                .withCause(((DefaultProblem) problem).getCause())
                .withDetail(problem.getDetail())
                .withInstance(problem.getInstance());
            problem.getParameters().forEach(builder::with);
            if (!problem.getParameters().containsKey("message") amp;amp; problem.getStatus() != null) {
                builder.with("message", "error.http."   problem.getStatus().getStatusCode());
            }
        }
        return new ResponseEntity<>(builder.build(), entity.getHeaders(), entity.getStatusCode());
    }

    @ExceptionHandler(SSOAuthenticationException.class)
    @ResponseBody
    public ResponseEntity<Problem> handleUnAuthenticatedUser(SSOAuthenticationException ex, NativeWebRequest request) {
        Problem problem = Problem.builder()
            .withStatus(Status.UNAUTHORIZED)
            .with("message", ErrorConstants.SSO_CACHE_AUTHENTICATION_FAILED)
            .build();
        return create(ex, problem, request);
    }
}

  

Когда я запускаю отладчик, я замечаю, что обработчик исключений никогда не вызывается. вместо этого код считает, что обработчик не зарегистрирован (в ServletInitialHandler.java , он переходит в раздел else, который предназначен для исключения, не обработанного) и изменяет код состояния на INTERNAL_SERVER_ERROR. Итак, для всех исключений приложение выдает ошибку 500. Что не так в коде обработки исключений? Нужно ли включать AdviceTrait? Я тоже пробовал это. но, похоже, это тоже не работает. Если бы вы могли объяснить правильный способ обработки этого исключения и пример, это помогло. Спасибо

Ответ №1:

Используя Problem Spring Web 0.25.2, я сначала создал новый AdviceTrait, аналогичный существующим:

 public interface CustomAdviceTrait extends AdviceTrait {

  @ExceptionHandler
  default ResponseEntity<Problem> handleCustomException(final CustomException exception, final NativeWebRequest request) {
    return create(Status.INTERNAL_SERVER_ERROR, exception, request);
  }
}
  

Здесь также может произойти преобразование в проблему, если это необходимо.

Затем, аналогично включению выделенных встроенных функций рекомендаций, я включаю их, реализуя соответствующий интерфейс в моем обработчике исключений:

 @ControllerAdvice
public class FootlooseServiceExceptionHandler implements ProblemHandling, CustomAdviceTrait { }