使用其他字段值自定义bean字段的验证器

时间:2012-05-07 18:17:04

标签: java bean-validation hibernate-validator

不确定这是否可行。想知道我是否可以为bean的字段创建自定义约束,它将使用相同类对象的其他字段的值。我尝试使用以下代码实现此功能:

public final class AWRRecordObject extends DoaAbstract implements
        java.io.Serializable {
    private static final long serialVersionUID = 1L;

    @ValidateApplicationType
    private String applicationType;

    private String recordData;

    private String programSource;

    // ...
}

public class ApplicationTypeValidator implements
        ConstraintValidator<ValidateApplicationType, AWRRecordObject> {

    private Class<AWRRecordObject> awrRecObj; // ?

    @Override
    public void initialize(ValidateApplicationType constraintAnnotation) {
        this.awrRecObj = constraintAnnotation.value();
    }

    @Override
    public boolean isValid(String arg0, ConstraintValidatorContext arg1) {

        // verify if the application type is A1 and length is 512
        if ((awrRecObj.getApplicationType()
                .equalsIgnoreCase(AWRConstant.AWR_W2))
                && (awrRecObj.getRecordData().toString().length() != AWRConstant.W2_RECORD_LEN)
                && (awrRecObj.getProgramSource()
                        .equalsIgnoreCase(AWRConstant.SOURCE_BATCH))) {

            // create AWRRequestError Object and add it to AWRRecordObject
            AWRUtility.createAWRRequestErrorObject(awrRecObj,
                    AWRErrorTypeCode.W2_RECORD_LENGTH_ERROR,
                    awrRecObj.getRecordData());
            return false;
            // ...
        }

        return true;
    }
}

@Target({ METHOD, FIELD, ANNOTATION_TYPE })
@Retention(RUNTIME)
@Documented
@Constraint(validatedBy = { ApplicationTypeValidator.class })
public @interface ValidateApplicationType {

    String message() default "{com.myproject.validation.ApplicationType.message}";

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

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

    Class<AWRRecordObject> value();
}

代码读取固定长度文件并将解析后的值存储到bean中:

public static AWRRecordObject bufferedReader() throws IOException {

    int lineCount = 0;
    long time1 = System.currentTimeMillis();
    File file = new File("D://TestData/test.txt");
    BufferedReader br = new BufferedReader(new FileReader(file), 8192);
    ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
    validator = factory.getValidator();
    String line;

    while ((line = br.readLine()) != null) {

        String type = line.length() > 2 ? line.substring(0, 2) : line;

        AWRRecordObject record = new AWRRecordObject(line, type, lineCount);

        Set<ConstraintViolation<AWRRecordObject>> constraintViolations = validator
                .validate(record);

        if (constraintViolations.size() > 0) {

            Iterator it = constraintViolations.iterator();
            while (it.hasNext()) {
                ConstraintViolation<AWRRecordObject> cv = (ConstraintViolation<AWRRecordObject>) it
                        .next();
                System.out.println(cv.getInvalidValue());
                System.out.println(cv.getMessage());

            }

        }

        return record;
    }
}

不幸的是,我收到以下错误消息:

Exception in thread "main" javax.validation.UnexpectedTypeException: No validator could be found for type: java.lang.String
at org.hibernate.validator.engine.ConstraintTree.verifyResolveWasUnique(ConstraintTree.java:383)

1 个答案:

答案 0 :(得分:0)

看起来你需要做两件事:

1。您当前已将自定义验证应用于目标bean的字段。你需要把它移到课堂上。

@ValidateApplicationType
public final class AWRRecordObject

2。您的注释定义需要更改,以允许将注释应用于类。

@Target({ TYPE, ANNOTATION_TYPE })