Java - разрешить пользовательскому ограничению быть нулевым - PullRequest
0 голосов
/ 30 октября 2018

У меня есть следующее пользовательское ограничение для необязательного поля, означающее, что оно может быть нулевым или нет. Если это ноль, я не хочу проверять это, но если у этого есть значение, я хочу проверить это. Код моих ограничений:

Cif

import javax.validation.Constraint;
import javax.validation.Payload;
import java.lang.annotation.*;

@Target({ ElementType.FIELD, ElementType.ANNOTATION_TYPE })
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = { CifValidator.class })
@Documented
public @interface Cif {
    String message() default "Invalid cif";
    Class<?>[] groups() default {};
    Class<? extends Payload>[] payload() default {};
}

CifValidator

import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import java.util.regex.Pattern;

public final class CifValidator implements ConstraintValidator<Cif, String> {

    @Override
    public void initialize(Cif constraintAnnotation) { }

    @Override
    public boolean isValid(String cif, ConstraintValidatorContext context) {
        final Pattern p = Pattern.compile("^([ABCDEFGHJKLMNPQRSUVW])(\\d{7})([0-9A-J])$");

        if (!cif.matches(p.pattern()))
            return false;
        else
            return isValidCif(cif);
    }

    private boolean isValidCif(String cif) {
        System.out.println("haha");
        if (cif == null || cif.length() != 9)
            return false;

        String cifLetter = cif.substring(0, 1);

        if (!cifLetter.matches("[A-Z]"))
            return false;

        String cifDigits = cif.substring(1, cif.length() - 1);
        int sum = 0, digit;

        for (int i = 0; i < cifDigits.length(); ++i) {
            digit = Integer.parseInt(Character.toString(cifDigits.charAt(i)));

            if (!cifDigits.matches("\\d+"))
                return false;

            if (i % 2 == 0) {
                digit *= 2;
                if (digit > 9)
                    digit = (digit / 10) + (digit % 10);

                sum += digit;
            } else
                sum += digit;
        }

        sum %= 10;
        if (sum != 0)
            digit = 10 - sum;
        else
            digit = sum;

        char[] letters = {'J', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I'};
        String cifControlCharacter = cif.substring(cif.length() - 1);

        if (cifLetter.matches("[ABEH]"))
            return Integer.toString(digit).equalsIgnoreCase(cifControlCharacter);
        else if (cifLetter.matches("[NPQRSW]"))
            return Character.toString(letters[digit]).equalsIgnoreCase(cifControlCharacter);
        else
            return Integer.toString(digit).equalsIgnoreCase(cifControlCharacter) || Character.toString(letters[digit]).equalsIgnoreCase(cifControlCharacter);
    }
}

Есть ли чистый способ добиться этого? Я не думаю, что просто проверять, если null с if и возвращать true - это круто. Я думаю, что это грязный обходной путь, если есть что-то чище.

Если я не отправляю значение, к которому применяю это ограничение, я получаю следующую ошибку:

Caused by: java.lang.NullPointerException: null
    at es.xx.hos.xx.rest.validators.CifValidator.isValid(CifValidator.java:16) ~[classes/:na]
    at es.xx.hos.xx.rest.validators.CifValidator.isValid(CifValidator.java:7) ~[classes/:na]

Спасибо за помощь!

1 Ответ

0 голосов
/ 30 октября 2018

Из того, что я вижу в вашем коде, метод isValid выполняется до isValidCif, поэтому метод isValid должен проверять предоставленную строковую переменную, если она не равна нулю.

Вы можете использовать StringUtils.isNotEmpty(variable);

прежде чем вы получите это утверждение

if (!cif.matches(p.pattern()))

потому что, если cif здесь ноль, вы получите NullPointerException

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...