验证异常-正确的处理方法

cgvd09ve  于 2021-06-27  发布在  Java
关注(0)|答案(2)|浏览(396)

我试图验证我的邮箱中的邮政编码,但是我想的方法不可行,我不明白为什么。
我创建了一个验证器,它必须抛出一个 ValidationException 如果它无效。

@Service
public class ZipCodeValidator{

    public void validate(String zipCode){
        validateNotEmpty(zipCode);
        validateHasNoSpaces(zipCode);
    }

    private void validateNotEmpty(String zipCode){
       if (zipCode.length() != 0){
           throw new ValidationException("Postal Code can't be empty");
       }
    }

    private void validateHasNoSpaces(String zipCode) {
        if (zipCode.contains(" ")){
            throw new ValidationException("Postal Code can't contain spaces");
        }
    }

}

在我的服务中,当我收到邮政编码时,我想抛出我的自定义异常(我将错误消息传递给它),如下所示:

try{
        validator.validate(zipCode);
    }catch (ValidationException ex){
        throw new ZipCodeValidationException(ex.getMessage());
    }

但是它似乎不起作用,这个异常没有被捕获,所以程序运行得更远。
我做错什么了?
整个方法都错了吗?你有什么建议?
这是我的自定义例外

public class ZipCodeValidationException extends Exception{
    public ZipCodeValidationException(String message) {
        super(message);
    }
}
dddzy1tm

dddzy1tm1#

您好,请通过两个步骤找到我的答案,第一步是正确的,第二步是建议的实施方法。
更正:
请使用 ObjectUtils.isEmpty(arg) 用于检查字符串长度是0还是null。这是你的代码的修改版本

public interface ZipcodeService {
        void validate(@Zipcode String zipCode) throws ZipCodeValidationException;
    }

    @Service
    public static class ZipcodeServiceImpl implements ZipcodeService {
        private final ZipCodeRegexMatcher zipCodeRegexMatcher;

        public ZipcodeServiceImpl() {
            zipCodeRegexMatcher = new ZipCodeRegexMatcher();
        }

        @Override
        public void validate(String zipCode) throws ZipCodeValidationException {
            // uncomment for Regex Validation
            // boolean valid = zipCodeRegexMatcher.isValid(zipCode);
            // uncomment for Simple text validation
            final boolean valid = !ObjectUtils.isEmpty(zipCode);

            if (!valid) {
                throw new ZipCodeValidationException("Invalid zipcode");
            }
        }
    }

这是来电者在电话里的样子 Controller ```
@GetMapping(path = "dummy")
public String getDummy(@RequestParam("zipcode") String zipCode) {
try {
zipcodeService.validate(zipCode);
return zipCode;
} catch (ZipCodeValidationException e) {
return e.getMessage();
}
}

建议方式:
将以下条目添加到 `pom.xml` ```
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-validation</artifactId>
</dependency>

创建注解和验证器,如下所示

@Constraint(validatedBy = {ZipcodeValidator.class})
    @Target({ElementType.FIELD, ElementType.PARAMETER})
    @Retention(RetentionPolicy.RUNTIME)
    public @interface Zipcode {
        String message() default "Invalid Zipcode value";

        Class<?>[] groups() default {};

        Class<? extends Payload>[] payload() default {};
    }

    public static class ZipcodeValidator implements ConstraintValidator<Zipcode, String> {
        private final ZipCodeRegexMatcher zipCodeRegexMatcher;

        public ZipcodeValidator() {
            zipCodeRegexMatcher = new ZipCodeRegexMatcher();
        }

        @Override
        public boolean isValid(String zipCode, ConstraintValidatorContext constraintValidatorContext) {
            return zipCodeRegexMatcher.isValid(zipCode);
        }
    }

一旦完成了这个设置,就转到controller类和带有@validated和field的annotated类,您希望对自定义注解进行验证,即 Zipcode 我们刚刚创造了。在本例中,我们通过扩展constraintvalidator来创建一个自定义验证器zipcodevalidator。
来电者的样子如下:

@GetMapping
    public String get(@Zipcode @RequestParam("zipcode") String zipCode) {
        return zipCode;
    }

验证失败时,它抛出 javax.validation.ConstraintViolationException: get.zipCode: Invalid Zipcode value 您可以使用controlleradvice根据需要定制。
你也可以使用 @Zipcode 服务级别的注解,其工作方式相同。关于 ZipCodeRegexMatcher 您可以创建bean并注入依赖项,而不是在构造函数中创建它。它是一个简单的类,包含用于zipcode的regex并执行验证。

public static class ZipCodeRegexMatcher {
        public static final String ZIP_REGEX = "^[0-9]{5}(?:-[0-9]{4})?$";
        private final Pattern pattern;

        public ZipCodeRegexMatcher() {
            pattern = Pattern.compile(ZIP_REGEX);
        }

        public boolean isValid(String zipCode) {
            return pattern.matcher(zipCode).matches();
        }
    }

整个代码都在这里

blmhpbnm

blmhpbnm2#

我建议如下:
将所有例外情况作为 ExceptionHandler 类,有关详细信息,请参见:https://www.baeldung.com/exception-handling-for-rest-with-spring
你可以延长 ValidationExceptionRuntimeException ,这种方法将允许从try-catch构造中卸载代码
@对于转换器或验证器来说,服务注解不是很合适,因为规则@service class包含业务逻辑,对于助手类来说,使用@component会更好,这两个注解之间完全没有区别,只了解组件具有哪个应用程序层
请分享代码以获得更多建议和帮助。

相关问题