Java Can';t手例外

Java Can';t手例外,java,spring,exception,exception-handling,Java,Spring,Exception,Exception Handling,我使用Spring并在annotation@ControllerAdvice的帮助下创建了用于处理所有异常的类 @EnableWebMvc @ControllerAdvice class RestResponseEntityExceptionHandler extends ResponseEntityExceptionHandler { private final MessageSource messages; private RestResponseEntityE

我使用Spring并在annotation@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);
        }
    }
然后我尝试在控制器中的注释@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);
        }
    }
}
@Log4j2
@组成部分
公共类ESRequestDTOValidator实现验证器{
@凌驾
公共布尔支持(类clazz){
返回ElasticSearchLogRequest.class.isAssignableFrom(clazz);
}
@凌驾
公共无效验证(对象目标、错误){
调试(“验证:{}”,目标);
ElasticSearchLogRequest表单=(ElasticSearchLogRequest)目标;
验证端口(表格);
}
专用void validatePort(ElasticSearchLogRequest表单){
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}))$";
如果(!form.getPort().toString()匹配(reg)){
抛出新的ESInvalidValueException(“portNotValid”,HTTP\u BAD\u请求);
}
}
}

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

这是无法实现的。检查这个答案

在您的例子中,bean位于CGLIB代理之后。它创建了一个子类 由于该方法具有final修饰符,因此无法更改 原始ResponseEntityExceptionHandler类对的行为 向后面的bean插入一个调用-请检查我关于 CGLIB

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

请注意,不可能实现Spring的大部分功能 仅具有子类化的功能,即不分离 物体。当单例作用域bean引用 会话范围bean-显然有许多会话范围bean和 只有一个单例作用域bean

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

@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);
        }
    }
}