【问题标题】:Can't hand exception不能处理异常
【发布时间】:2018-02-08 10:13:59
【问题描述】:

我使用 Spring 并在 @ControllerAdvice 注释的帮助下创建了用于处理所有异常的类。

 @EnableWebMvc
    @ControllerAdvice
    class RestResponseEntityExceptionHandler extends ResponseEntityExceptionHandler {

private final MessageSource messages;

    private RestResponseEntityExceptionHandler(@Qualifier("messageSource") MessageSource messages) {
        this.messages = messages;
    }

     @ExceptionHandler({ESInvalidValueException.class})
        public ResponseEntity<Object> handleValidation(final RuntimeException ex, final WebRequest request) {
            log.error("400 Status Code: " + ex.getMessage());
            Locale locale = LocaleContextHolder.getLocale();
            final GenericResponse body = GenericResponse.error(
                    messages.getMessage("portNotValid", null, locale), 400);
            return handleExceptionInternal(ex, body, new HttpHeaders(), HttpStatus.BAD_REQUEST, request);
        }
    }

另外,我创建了扩展 AbstractPortalException 的自定义异常:

public class ESInvalidValueException extends AbstractPortalException{

    public ESInvalidValueException(String message, int code) {

        super(message, code);
    }
}


public abstract class AbstractPortalException extends RuntimeException {

    private int code;

    AbstractPortalException() {
        super();
    }

    AbstractPortalException(final String message, final Throwable cause) {
        super(message, cause);
    }

    AbstractPortalException(final String message) {
        super(message);
    }

    AbstractPortalException(final String message, int code) {
        super(message);
        this.code = code;
    }

    AbstractPortalException(final Throwable cause) {
        super(cause);
    }

    public int getCode() {
        return code;
    }

    public void setCode(int code) {
        this.code = code;
    }
}

然后我尝试借助控制器中的注释 @Valid 来验证端口号。 这是我的验证类:

@Log4j2
@Component
public class ESRequestDTOValidator implements Validator{

    @Override
    public boolean supports(Class<?> clazz) {
        return ElasticSearchLogRequest.class.isAssignableFrom(clazz);
    }

    @Override
    public void validate(Object target, Errors errors) {
        log.debug("Validating: {}", target);
        ElasticSearchLogRequest form = (ElasticSearchLogRequest) target;
        validatePort(form);


    }

    private void validatePort(ElasticSearchLogRequest form) {
        String reg = "^((6553[0-5])|(655[0-2][0-9])|(65[0-4][0-9]{2})" +
                "|(6[0-4][0-9]{3})|([1-5][0-9]{4})|([0-5]{0,5})|([0-9]{1,4}))$";
        if (!form.getPort().toString().matches(reg)) {
           throw new ESInvalidValueException("portNotValid", HTTP_BAD_REQUEST);
        }
    }
}

这是问题所在:messages.getMessage() 找不到带有此类代码“portNotValid”的消息。在ESInvalidValueException 异常中,我想传递不同的消息以验证其他字段,在handleValidation() 方法中,我想根据消息处理所有这些异常。我怎样才能执行这样的任务?也许还有另一种方法。

【问题讨论】:

    标签: java spring exception exception-handling


    【解决方案1】:

    这是无法实现的。签出这个答案https://stackoverflow.com/a/20552196/3892213

    在您的情况下,您的 bean 位于 CGLIB 代理之后。它创建一个子类 您的 bean 并且由于该方法具有 final 修饰符,因此无法更改 原始 ResponseEntityExceptionHandler 类的行为 在后面插入对bean的调用-请查看我的其他答案 CGLIB。

    CGLIB 代理是一个不同的对象,它将方法调用委托给 原来的豆子。

    请注意,无法实现大部分 Spring 仅具有子类化的功能,即没有这种分离 对象。当单例范围的 bean 引用一个 会话范围的 bean - 显然有许多会话范围的 bean 和 只有一个单例范围的 bean。

    您可以尝试使用一些私有方法来实现这一点,而不是使用spring bean。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-05-14
      • 1970-01-01
      • 2010-11-12
      • 2021-11-12
      • 2019-11-23
      • 1970-01-01
      • 2018-07-13
      相关资源
      最近更新 更多