在春季启动中是否有一个很好的zalando问题实现示例?

时间:2019-04-11 00:53:25

标签: java spring-boot exception

我们在我们的spring-boot应用程序中使用zalando-problem处理异常。但是看起来我们的问题处理程序从未被调用过。相反,spring boot对于所有异常都返回500 Internal server error。如果您可以提供一些示例,将很有帮助。我找不到在春季启动中实现zalando问题的好例子

如果用户未登录,则代码将引发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") && 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 个答案:

答案 0 :(得分:0)

使用 Problem Spring Web 0.25.2 ,我首先创建了一个新的 AdviceTrait ,它与现有的类似:

batteryLevel.value

如果需要,这也是可以转换为问题的地方。

然后,与启用专用内置建议特征一样,我通过在ExceptionHandler上实现相应的接口来启用它们:

public interface CustomAdviceTrait extends AdviceTrait {

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